Forráskód Böngészése

feat(作业管理)
- 新增流程模式管理功能
- 异常管理列表增加详情按钮
- 硬件管理列表刷新逻辑优化,新增钥匙和锁的重复校验
- 我的待办时间筛选弹窗优化
- 作业执行全屏显示背景色修改

fix(作业管理)
- 修复新建、编辑作业的取消按钮边距问题
- 修复作业详情的人员分组查询问题

refactor(仓位管理)
- 优化仓位管理界面,调整加载提示,修复图标颜色问题

refactor(国际化)
- 调整部分中英文翻译

周文健 3 hónapja
szülő
commit
b58fb8198a
34 módosított fájl, 610 hozzáadás és 153 törlés
  1. 7 2
      app/src/main/java/com/grkj/iscs/features/main/fragment/exception_manage/ExceptionDetailFragment.kt
  2. 8 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/exception_manage/ExceptionReportFragment.kt
  3. 67 67
      app/src/main/java/com/grkj/iscs/features/main/fragment/hardware_manage/SlotsManageFragment.kt
  4. 2 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobExecuteFragment.kt
  5. 10 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobManageHomeFragment.kt
  6. 35 24
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/MyTodoListFragment.kt
  7. 132 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/WorkflowManageFragment.kt
  8. 44 0
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/WorkflowViewModel.kt
  9. 81 47
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/hardware_manage/SlotsManageViewModel.kt
  10. 1 0
      app/src/main/res/layout-land/fragment_create_job.xml
  11. 1 0
      app/src/main/res/layout-land/fragment_create_sop_job.xml
  12. 1 0
      app/src/main/res/layout-land/fragment_edit_job.xml
  13. 1 0
      app/src/main/res/layout-land/fragment_edit_sop_job.xml
  14. 1 0
      app/src/main/res/layout/fragment_create_job.xml
  15. 1 0
      app/src/main/res/layout/fragment_create_sop_job.xml
  16. 1 0
      app/src/main/res/layout/fragment_edit_job.xml
  17. 1 0
      app/src/main/res/layout/fragment_edit_sop_job.xml
  18. 7 0
      app/src/main/res/layout/fragment_exception_manage.xml
  19. 2 2
      app/src/main/res/layout/fragment_slots_manage.xml
  20. 143 0
      app/src/main/res/layout/fragment_workflow_manage.xml
  21. 10 0
      app/src/main/res/layout/item_exception_manage.xml
  22. BIN
      app/src/main/res/mipmap-xhdpi/icon_workflow_setting.png
  23. 11 0
      app/src/main/res/navigation/nav_job_manage.xml
  24. 5 0
      app/src/main/res/values-en/strings.xml
  25. 8 3
      app/src/main/res/values-zh/strings.xml
  26. 8 3
      app/src/main/res/values/strings.xml
  27. 1 0
      data/src/main/java/com/grkj/data/dao/IsSopDao.kt
  28. 1 0
      data/src/main/java/com/grkj/data/dao/JobTicketDao.kt
  29. 1 0
      data/src/main/java/com/grkj/data/dao/UserDao.kt
  30. 1 1
      data/src/main/java/com/grkj/data/dao/WorkflowStepDao.kt
  31. 3 1
      data/src/main/java/com/grkj/data/enums/RoleFunctionalPermissionsEnum.kt
  32. 1 1
      data/src/main/java/com/grkj/data/model/dos/WorkflowMode.kt
  33. 13 0
      data/src/main/java/com/grkj/data/model/vo/WorkflowModeVo.kt
  34. 1 1
      ui-base/src/main/java/com/grkj/ui_base/utils/ble/BleConnectionManager.kt

+ 7 - 2
app/src/main/java/com/grkj/iscs/features/main/fragment/exception_manage/ExceptionDetailFragment.kt

@@ -231,8 +231,13 @@ class ExceptionDetailFragment : BaseFragment<FragmentExceptionDetailBinding>() {
                             "作业"
                         )
                     }?.dictValue) {
-                    exceptionJobViewModel.ticketId = viewModel.exceptionSourceData[0].sourceDataId
-                    getData()
+                    viewModel.getExceptionSourceData().observe(this) {
+                        if (viewModel.exceptionSourceData.isNotEmpty()) {
+                            exceptionJobViewModel.ticketId =
+                                viewModel.exceptionSourceData[0].sourceDataId
+                            getData()
+                        }
+                    }
                 }
                 binding.handleException.isVisible =
                     viewModel.exceptionStatus.find { it.dictLabel == "待处理" }?.dictValue == viewModel.exceptionData?.exceptionStatus.toString()

+ 8 - 1
app/src/main/java/com/grkj/iscs/features/main/fragment/exception_manage/ExceptionReportFragment.kt

@@ -7,7 +7,6 @@ import com.grkj.iscs.databinding.FragmentExceptionReportBinding
 import com.grkj.iscs.features.main.dialog.TextDropDownDialog
 import com.grkj.iscs.features.main.viewmodel.exception_manage.ExceptionViewModel
 import com.grkj.ui_base.base.BaseFormFragment
-import com.grkj.ui_base.base.BaseFragment
 import com.grkj.ui_base.dialog.TipDialog
 import com.grkj.ui_base.utils.CommonUtils
 import com.sik.sikcore.extension.setDebouncedClickListener
@@ -77,6 +76,10 @@ class ExceptionReportFragment : BaseFormFragment<FragmentExceptionReportBinding>
         }
         binding.exceptionSource.setDebouncedClickListener {
             if (viewModel.selectedExceptionType == viewModel.exceptionType.find { it.dictLabel == "硬件异常" }?.dictValue) {
+                if (viewModel.exceptionSourceData.isEmpty()){
+                    showToast(getString(R.string.currently_no_hardware_can_be_report))
+                    return@setDebouncedClickListener
+                }
                 TextDropDownDialog.showMultiTree(viewModel.exceptionSourceData.map {
                     TextDropDownDialog.SimpleTextDropDownEntity(
                         dataText = it.sourceDataText,
@@ -105,6 +108,10 @@ class ExceptionReportFragment : BaseFormFragment<FragmentExceptionReportBinding>
                     logger.info("选中的数据源:${viewModel.selectedSourceData.toJson()}")
                 }
             } else {
+                if (viewModel.exceptionSourceData.isEmpty()){
+                    showToast(getString(R.string.currently_no_job_can_be_report))
+                    return@setDebouncedClickListener
+                }
                 TextDropDownDialog.showSingle(viewModel.exceptionSourceData.map {
                     TextDropDownDialog.SimpleTextDropDownEntity(
                         dataObject = it, dataText = it.sourceDataText

+ 67 - 67
app/src/main/java/com/grkj/iscs/features/main/fragment/hardware_manage/SlotsManageFragment.kt

@@ -43,7 +43,6 @@ import kotlinx.coroutines.withContext
 @AndroidEntryPoint
 class SlotsManageFragment : BaseFragment<FragmentSlotsManageBinding>() {
     private val viewModel: SlotsManageViewModel by viewModels()
-    private val dockDataList = mutableListOf<DockData>()
 
     override fun getLayoutId(): Int {
         return R.layout.fragment_slots_manage
@@ -76,7 +75,7 @@ class SlotsManageFragment : BaseFragment<FragmentSlotsManageBinding>() {
                     }
                 }
             }
-        }.models = dockDataList
+        }.models = viewModel.lastDockSnapshot
         if (MainDomainData.roleKeys?.contains(RoleEnum.ADMIN.roleKey) == true ||
             MainDomainData.roleKeys?.contains(RoleEnum.SYSCONFIG.roleKey) == true
         ) {
@@ -125,52 +124,71 @@ class SlotsManageFragment : BaseFragment<FragmentSlotsManageBinding>() {
                         ThreadUtils.runOnMain {
                             viewModel.checkKeyRfidIsNewDevice(keyRfid)
                                 .observe(this@SlotsManageFragment) {
-                                    LoadingEvent.sendLoadingEvent(getString(R.string.check_key_is_new_device))
-                                    LoadingEvent.sendLoadingEvent(getString(R.string.start_scan_key_mac))
-                                    viewModel.detectKeyMac(deviceBean)
-                                        .observe(this@SlotsManageFragment) { keyMac ->
-                                            LoadingEvent.sendLoadingEvent()
-                                            TipDialog.showInfo(
-                                                msg = getString(R.string.check_new_key_need_register),
-                                                onConfirmClick = {
-                                                    viewModel.registerKeyInfo(keyRfid, keyMac)
-                                                        .observe(this@SlotsManageFragment) {
-                                                            if (it) {
-                                                                TipDialog.showSuccess(getString(R.string.register_success))
-                                                            } else {
-                                                                TipDialog.showError(getString(R.string.register_failed))
-                                                            }
-                                                        }
-                                                })
-                                        }
+                                    if (it) {
+                                        LoadingEvent.sendLoadingEvent(getString(R.string.start_scan_key_mac))
+                                        viewModel.detectKeyMac(deviceBean)
+                                            .observe(this@SlotsManageFragment) { keyMac ->
+                                                LoadingEvent.sendLoadingEvent()
+                                                ThreadUtils.runOnMain {
+                                                    TipDialog.showInfo(
+                                                        msg = getString(R.string.check_new_key_need_register),
+                                                        onConfirmClick = {
+                                                            viewModel.registerKeyInfo(
+                                                                keyRfid,
+                                                                keyMac
+                                                            )
+                                                                .observe(this@SlotsManageFragment) {
+                                                                    if (it) {
+                                                                        TipDialog.showSuccess(
+                                                                            getString(R.string.register_success)
+                                                                        )
+                                                                    } else {
+                                                                        TipDialog.showError(
+                                                                            getString(R.string.register_failed)
+                                                                        )
+                                                                    }
+                                                                }
+                                                        })
+                                                }
+                                            }
+                                    } else {
+                                        LoadingEvent.sendLoadingEvent()
+                                        showToast(getString(R.string.key_info_already_exists))
+                                    }
+
                                 }
                         }
-
                     }
                 }
             }
 
             is DockBean.LockBean -> {
                 LoadingEvent.sendLoadingEvent(getString(R.string.start_detect_lock_slot))
-                ModBusController.readLockRfidStr(deviceBean.addr, deviceBean.idx) { lockRfid ->
-                    ThreadUtils.runOnMain {
-                        LoadingEvent.sendLoadingEvent(getString(R.string.check_lock_is_new_device))
-                        viewModel.checkLockRfidIsNewDevice(lockRfid)
-                            .observe(this@SlotsManageFragment) {
-                                LoadingEvent.sendLoadingEvent()
-                                TipDialog.showInfo(
-                                    msg = getString(R.string.check_new_lock_need_register),
-                                    onConfirmClick = {
-                                        viewModel.registerLockInfo(lockRfid)
-                                            .observe(this@SlotsManageFragment) {
-                                                if (it) {
-                                                    TipDialog.showSuccess(getString(R.string.register_success))
-                                                } else {
-                                                    TipDialog.showError(getString(R.string.register_failed))
-                                                }
-                                            }
-                                    })
-                            }
+                ThreadUtils.runOnIO {
+                    ModBusController.readLockRfidStr(deviceBean.addr, deviceBean.idx) { lockRfid ->
+                        ThreadUtils.runOnMain {
+                            LoadingEvent.sendLoadingEvent(getString(R.string.check_lock_is_new_device))
+                            viewModel.checkLockRfidIsNewDevice(lockRfid)
+                                .observe(this@SlotsManageFragment) {
+                                    LoadingEvent.sendLoadingEvent()
+                                    if (it) {
+                                        TipDialog.showInfo(
+                                            msg = getString(R.string.check_new_lock_need_register),
+                                            onConfirmClick = {
+                                                viewModel.registerLockInfo(lockRfid)
+                                                    .observe(this@SlotsManageFragment) {
+                                                        if (it) {
+                                                            TipDialog.showSuccess(getString(R.string.register_success))
+                                                        } else {
+                                                            TipDialog.showError(getString(R.string.register_failed))
+                                                        }
+                                                    }
+                                            })
+                                    } else {
+                                        showToast(getString(R.string.lock_already_exists))
+                                    }
+                                }
+                        }
                     }
                 }
             }
@@ -507,8 +525,11 @@ class SlotsManageFragment : BaseFragment<FragmentSlotsManageBinding>() {
         super.initData()
         getExceptionData()
         viewModel.registerStatusListener {
-            getData()
+            if (it.deviceList.isNotEmpty()) {
+                getData()
+            }
         }
+        getData()
     }
 
     /**
@@ -529,34 +550,13 @@ class SlotsManageFragment : BaseFragment<FragmentSlotsManageBinding>() {
      * 获取并加载数据
      */
     private fun getData() {
-        val dockData =
-            ModBusController.dockList.filter { it.type == DeviceConst.DOCK_TYPE_LOCK || it.type == DeviceConst.DOCK_TYPE_KEY || it.type == DeviceConst.DOCK_TYPE_PORTABLE }
-        val keyDock = dockData.filter { it.type == DeviceConst.DOCK_TYPE_KEY }.map {
-            DockData.KeyDock().apply {
-                keyData.addAll(it.deviceList.filterIsInstance<DockBean.KeyBean>())
+        viewModel.getData().observe(this) {
+            if (it) {
+                binding.loadingTip.isVisible = false
+                binding.dockRv.adapter?.notifyDataSetChanged()
             }
         }
-        val keyDatas = keyDock.map { it.keyData }.flatten()
-        val newKeyDock = DockData.KeyDock()
-        newKeyDock.keyData.addAll(keyDatas)
-        val newKeyDockList = newKeyDock.keyData.chunked(4).map { subList ->
-            DockData.KeyDock().apply { keyData.addAll(subList) }
-        }
-        val lockDock = dockData.filter { it.type == DeviceConst.DOCK_TYPE_LOCK }.map {
-            DockData.LockDock().apply {
-                lockData.addAll(it.deviceList.filterIsInstance<DockBean.LockBean>())
-            }
-        }
-        val portableDock =
-            dockData.filter { it.type == DeviceConst.DOCK_TYPE_PORTABLE }.map {
-                DockData.PortableDock().apply {
-                    deviceData.addAll(it.deviceList.toList())
-                }
-            }
-        dockDataList.clear()
-        binding.loadingTip.isVisible = false
-        dockDataList.addAll(newKeyDockList + portableDock + lockDock)
-        binding.dockRv.adapter?.notifyDataSetChanged()
+
     }
 
     override fun onDestroyView() {

+ 2 - 0
app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobExecuteFragment.kt

@@ -63,6 +63,7 @@ class JobExecuteFragment : BaseFragment<FragmentJobExecuteBinding>() {
                 binding.spaceView.isVisible = false
                 toggleExpandView(binding.fullScreenRootLayout, binding.dataLayout, true)
                 binding.fullScreen.isVisible = true
+                binding.dataLayout.setBackgroundResource(com.grkj.ui_base.R.drawable.common_layout_bg)
             } else {
                 navController.popBackStack()
             }
@@ -141,6 +142,7 @@ class JobExecuteFragment : BaseFragment<FragmentJobExecuteBinding>() {
         }
         binding.fullScreen.setDebouncedClickListener {
             toggleExpandView(binding.fullScreenRootLayout, binding.dataLayout, false)
+            binding.dataLayout.setBackgroundColor(requireContext().getColor(R.color.white))
             binding.fullScreen.isVisible = false
             binding.spaceView.isVisible = true
         }

+ 10 - 0
app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobManageHomeFragment.kt

@@ -80,6 +80,12 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
             RoleFunctionalPermissionsEnum.LOCKED_POINT.description,
             RoleFunctionalPermissionsEnum.LOCKED_POINT.functionalPermission
         ),
+        MenuItemEntity(
+            9,
+            R.mipmap.icon_workflow_setting,
+            RoleFunctionalPermissionsEnum.WORKFLOW_MANAGE.description,
+            RoleFunctionalPermissionsEnum.WORKFLOW_MANAGE.functionalPermission
+        ),
     )
 
     override fun getLayoutId(): Int {
@@ -187,6 +193,10 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
             8 -> {
                 navController.navigate(R.id.action_jobManageHomeFragment_to_lockedPointsFragment)
             }
+
+            9 -> {
+                navController.navigate(R.id.action_jobManageHomeFragment_to_workflowManageFragment)
+            }
         }
     }
 }

+ 35 - 24
app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/MyTodoListFragment.kt

@@ -103,28 +103,37 @@ class MyTodoListFragment : BaseFragment<FragmentMyTodoListBinding>() {
             ) {
                 val position = handleTimeData.indexOf(it.getShowText())
                 when (position) {
-                    0 -> binding.listRv.models =
-                        viewModel.doneData.sortedByDescending { it.stepUpdateTime }
-
-                    1 -> binding.listRv.models = viewModel.doneData.filter {
-                        val updateTimeDate = TimeUtils.parseDate(
-                            it.stepUpdateTime,
-                            TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT
-                        )
-                        updateTimeDate?.let {
-                            TimeUtils.calcDayNum(it, Date()) <= 1
-                        } ?: false
-                    }.sortedByDescending { it.stepUpdateTime }
-
-                    2 -> binding.listRv.models = viewModel.doneData.filter {
-                        val updateTimeDate = TimeUtils.parseDate(
-                            it.stepUpdateTime,
-                            TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT
-                        )
-                        updateTimeDate?.let {
-                            TimeUtils.calcDayNum(it, Date()) <= 30
-                        } ?: false
-                    }.sortedByDescending { it.stepUpdateTime }
+                    0 -> {
+                        binding.handleTime.text = it.getShowText()
+                        binding.listRv.models =
+                            viewModel.doneData.sortedByDescending { it.stepUpdateTime }
+                    }
+
+                    1 -> {
+                        binding.handleTime.text = it.getShowText()
+                        binding.listRv.models = viewModel.doneData.filter {
+                            val updateTimeDate = TimeUtils.parseDate(
+                                it.stepUpdateTime,
+                                TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT
+                            )
+                            updateTimeDate?.let {
+                                TimeUtils.calcDayNum(it, Date()) <= 1
+                            } ?: false
+                        }.sortedByDescending { it.stepUpdateTime }
+                    }
+
+                    2 -> {
+                        binding.handleTime.text = it.getShowText()
+                        binding.listRv.models = viewModel.doneData.filter {
+                            val updateTimeDate = TimeUtils.parseDate(
+                                it.stepUpdateTime,
+                                TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT
+                            )
+                            updateTimeDate?.let {
+                                TimeUtils.calcDayNum(it, Date()) <= 30
+                            } ?: false
+                        }.sortedByDescending { it.stepUpdateTime }
+                    }
 
                     3 -> {
                         viewModel.startTime = ""
@@ -154,13 +163,13 @@ class MyTodoListFragment : BaseFragment<FragmentMyTodoListBinding>() {
                     TimeUtils.DEFAULT_DATE_HOUR_MIN_FORMAT
                 )
             ) {
-                PopTip.build().tip(R.string.start_time_must_large_then_end_time)
+                showToast(getString(R.string.start_time_must_large_then_end_time))
+                pickDateTime(startTime, timeView)
                 return@setOnChoose
             }
             val timeStr = TimeUtils.formatDate(
                 Date(millisecond), TimeUtils.DEFAULT_DATE_HOUR_MIN_FORMAT
             )
-            timeView.text = timeStr
             if (startTime) {
                 viewModel.startTime = timeStr
             } else {
@@ -184,6 +193,8 @@ class MyTodoListFragment : BaseFragment<FragmentMyTodoListBinding>() {
                     TimeUtils.isTimeBefore(startTimeDate, updateTimeDate) &&
                             TimeUtils.isTimeBefore(updateTimeDate, endTimeDate)
                 }.sortedByDescending { it.stepUpdateTime }
+            } else if (viewModel.startTime.isNotEmpty() && viewModel.endTime.isEmpty() && startTime) {
+                pickDateTime(false, timeView)
             }
         }.build().show()
     }

+ 132 - 0
app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/WorkflowManageFragment.kt

@@ -0,0 +1,132 @@
+package com.grkj.iscs.features.main.fragment.job_manage
+
+import android.graphics.Color
+import androidx.fragment.app.viewModels
+import com.drake.brv.BindingAdapter
+import com.drake.brv.annotaion.DividerOrientation
+import com.drake.brv.utils.divider
+import com.drake.brv.utils.linear
+import com.drake.brv.utils.models
+import com.drake.brv.utils.setup
+import com.grkj.data.enums.JobTicketStatusEnum
+import com.grkj.data.model.vo.JobTicketManageVo
+import com.grkj.iscs.R
+import com.grkj.iscs.common.DataTransferConstants
+import com.grkj.iscs.databinding.FragmentJobManageBinding
+import com.grkj.iscs.databinding.FragmentWorkflowManageBinding
+import com.grkj.iscs.databinding.ItemJobManageBinding
+import com.grkj.iscs.features.main.viewmodel.WorkflowViewModel
+import com.grkj.iscs.features.main.viewmodel.job_manage.JobManageViewModel
+import com.grkj.ui_base.base.BaseFragment
+import com.grkj.ui_base.dialog.TipDialog
+import com.grkj.ui_base.utils.CommonUtils
+import com.grkj.ui_base.utils.extension.tip
+import com.kongzue.dialogx.dialogs.PopTip
+import com.sik.sikcore.data.GlobalDataTempStore
+import com.sik.sikcore.extension.setDebouncedClickListener
+import dagger.hilt.android.AndroidEntryPoint
+import kotlin.getValue
+
+/**
+ * 流程模式管理
+ */
+@AndroidEntryPoint
+class WorkflowManageFragment : BaseFragment<FragmentWorkflowManageBinding>() {
+    private val viewModel: WorkflowViewModel by viewModels()
+    override fun getLayoutId(): Int {
+        return R.layout.fragment_workflow_manage
+    }
+
+    override fun initView() {
+        binding.back.setDebouncedClickListener {
+            navController.popBackStack()
+        }
+        binding.delete.setDebouncedClickListener {
+            deleteSelected()
+        }
+        binding.importWorkflow.setDebouncedClickListener {
+
+        }
+        binding.listRv.linear().divider {
+            this.setColor(Color.BLACK)
+            this.startVisible = false
+            this.endVisible = true
+            this.orientation = DividerOrientation.VERTICAL
+        }.setup {
+            addType<JobTicketManageVo>(R.layout.item_job_manage)
+            onBind {
+                onListDataBinding(this)
+            }
+        }
+        setSelectAllListener()
+    }
+
+    private fun deleteSelected() {
+        if (viewModel.workflowModeData.none { it.isSelected }) {
+            showToast(getString(R.string.please_select_workflow_mode))
+            return
+        }
+        TipDialog.show(
+            msg = CommonUtils.getStr(R.string.check_delete_job).toString(),
+            countDownTime = 10,
+            onConfirmClick = {
+                viewModel.deleteSelectedWorkflowMode().observe(this) {
+                    if (it) {
+                        TipDialog.show(
+                            dialogType = TipDialog.DialogType.SUCCESS,
+                            msg = CommonUtils.getStr(R.string.job_manage_delete_succeed)
+                                .toString(),
+                            showConfirm = false,
+                            countDownTime = 10,
+                            onConfirmClick = {
+                                getData()
+                            },
+                            onCancelClick = {
+                                getData()
+                            }
+                        )
+                    } else {
+                        TipDialog.show(
+                            dialogType = TipDialog.DialogType.ERROR,
+                            msg = CommonUtils.getStr(R.string.job_manage_delete_failed)
+                                .toString(),
+                            showConfirm = false,
+                            countDownTime = 10
+                        )
+                    }
+                }
+            })
+    }
+
+    private fun setSelectAllListener() {
+        binding.selectAll.setOnCheckedChangeListener { v, checked ->
+            viewModel.workflowModeData.forEach { it.isSelected = checked }
+            binding.listRv.adapter?.notifyDataSetChanged()
+        }
+    }
+
+    private fun BindingAdapter.BindingViewHolder.onListDataBinding(holder: BindingAdapter.BindingViewHolder) {
+        val itemBinding = holder.getBinding<ItemJobManageBinding>()
+        val item = holder.getModel<JobTicketManageVo>()
+        itemBinding.jobName.text = item.ticketName
+        itemBinding.status.text = JobTicketStatusEnum.getTicketStatusStr(item.ticketStatus)
+        itemBinding.select.setOnCheckedChangeListener(null)
+        itemBinding.select.isChecked = item.isSelected
+    }
+
+    override fun onResume() {
+        super.onResume()
+        getData()
+    }
+
+    private fun getData() {
+        viewModel.getData().observe(this) {
+            if (viewModel.workflowModeData.isEmpty()) {
+                binding.state.showEmpty()
+            } else {
+                binding.state.showContent()
+            }
+            binding.listRv.models = viewModel.workflowModeData
+        }
+    }
+}

+ 44 - 0
app/src/main/java/com/grkj/iscs/features/main/viewmodel/WorkflowViewModel.kt

@@ -0,0 +1,44 @@
+package com.grkj.iscs.features.main.viewmodel
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.liveData
+import com.grkj.data.model.dos.WorkflowMode
+import com.grkj.data.model.vo.WorkflowModeVo
+import com.grkj.data.repository.IWorkflowRepository
+import com.grkj.data.repository.impl.standard.WorkflowRepository
+import com.grkj.ui_base.base.BaseViewModel
+import com.sik.sikcore.data.BeanUtils
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.Dispatchers
+import javax.inject.Inject
+
+/**
+ * 流程模式
+ */
+@HiltViewModel
+class WorkflowViewModel @Inject constructor(val workflowRepository: IWorkflowRepository) : BaseViewModel() {
+    /**
+     * 流程模式数据
+     */
+    var workflowModeData: List<WorkflowModeVo> = mutableListOf()
+
+    /**
+     * 获取流程模式数据
+     */
+    fun getData(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            workflowModeData = workflowRepository.getWorkflowModes()
+                .mapNotNull { BeanUtils.copyProperties(it, WorkflowModeVo::class.java) }
+            emit(true)
+        }
+    }
+
+    /**
+     * 删除流程模式
+     */
+    fun deleteSelectedWorkflowMode(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            workflowRepository
+        }
+    }
+}

+ 81 - 47
app/src/main/java/com/grkj/iscs/features/main/viewmodel/hardware_manage/SlotsManageViewModel.kt

@@ -1,13 +1,14 @@
 package com.grkj.iscs.features.main.viewmodel.hardware_manage
 
+import androidx.core.view.isVisible
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.liveData
 import com.grkj.data.model.dos.IsKey
 import com.grkj.data.model.dos.IsLock
 import com.grkj.data.model.dos.IsLockCabinetSlots
 import com.grkj.data.repository.IHardwareRepository
+import com.grkj.iscs.features.init.model.DockData
 import com.grkj.ui_base.base.BaseViewModel
-import com.grkj.ui_base.business.BleBusinessManager
 import com.grkj.ui_base.business.ModbusBusinessManager
 import com.grkj.ui_base.utils.ble.BleConnectionManager
 import com.grkj.ui_base.utils.modbus.DeviceConst
@@ -22,7 +23,6 @@ import kotlinx.coroutines.suspendCancellableCoroutine
 import kotlinx.coroutines.withContext
 import javax.inject.Inject
 import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
 
 /**
  * 仓位管理数据模型
@@ -36,6 +36,11 @@ class SlotsManageViewModel @Inject constructor(
      */
     var exceptionSlotsData: List<IsLockCabinetSlots> = listOf()
 
+    /**
+     * 缓存的dock数据
+     */
+    var lastDockSnapshot: MutableList<DockData> = mutableListOf()
+
     /**
      * 异常挂锁
      */
@@ -54,9 +59,9 @@ class SlotsManageViewModel @Inject constructor(
     /**
      * 注册监听
      */
-    fun registerStatusListener(statusListener: () -> Unit) {
+    fun registerStatusListener(statusListener: (DockBean) -> Unit) {
         ModbusBusinessManager.registerStatusListener(this) {
-            statusListener()
+            statusListener(it)
         }
     }
 
@@ -124,7 +129,11 @@ class SlotsManageViewModel @Inject constructor(
     /**
      * 标记硬件异常
      */
-    fun tagDeviceException(deviceType: Int, deviceRfid: String?, remark: String): LiveData<Boolean> {
+    fun tagDeviceException(
+        deviceType: Int,
+        deviceRfid: String?,
+        remark: String
+    ): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
             when (deviceType) {
                 DeviceConst.DEVICE_TYPE_KEY -> {
@@ -143,7 +152,8 @@ class SlotsManageViewModel @Inject constructor(
      */
     fun checkLockRfidIsNewDevice(lockRfid: String): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            emit(hardwareRepository.getLockInfo(lockRfid) == null)
+            val newDevices = hardwareRepository.getLockInfo(lockRfid) == null
+            emit(newDevices)
         }
     }
 
@@ -172,7 +182,8 @@ class SlotsManageViewModel @Inject constructor(
      */
     fun checkKeyRfidIsNewDevice(keyRfid: String): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            emit(hardwareRepository.getKeyInfo(keyRfid) == null)
+            val newDevices = hardwareRepository.getKeyInfo(keyRfid) == null
+            emit(newDevices)
         }
     }
 
@@ -181,7 +192,8 @@ class SlotsManageViewModel @Inject constructor(
      */
     fun detectKeyMac(keyBean: DockBean.KeyBean): LiveData<String> {
         return liveData(Dispatchers.IO) {
-            emit(detectNewKeyMac(keyBean))
+            val mac = detectNewKeyMac(keyBean)
+            emit(mac)
         }
     }
 
@@ -189,50 +201,72 @@ class SlotsManageViewModel @Inject constructor(
      * 检测新钥匙mac地址
      */
     private suspend fun detectNewKeyMac(keyBean: DockBean.KeyBean): String {
-        return suspendCancellableCoroutine<String> { cont ->
+        val mac = suspendCancellableCoroutine { cont ->
             val existsKeyMac =
                 hardwareRepository.getAllKeyInfo().mapNotNull { it.macAddress }.toList()
-            logger.info("设备检测-关闭充电:${keyBean.addr},${keyBean.idx}")
-            ModBusController.controlKeyCharge(false, keyBean.idx, keyBean.addr) {
-                ThreadUtils.runOnIO {
-                    delay(800)
-                    logger.info("设备检测-打开充电:${keyBean.addr},${keyBean.idx}")
-                    ModBusController.controlKeyLockAndCharge(true, keyBean.idx, keyBean.addr) {
-                        ThreadUtils.runOnIO {
-                            delay(3000)
-                            logger.info("设备检测-开始扫描在线蓝牙Mac")
-                            withContext(Dispatchers.Main) {
-                                BleConnectionManager.scanOnlineKeyLockMac(existsKeyMac) { mac ->
-                                    logger.info(
-                                        "设备检测-在线的蓝牙设备:${keyBean.rfid},${mac}"
-                                    )
-                                    if (isDestroy) {
-                                        logger.info(
-                                            "设备检测-界面已销毁"
-                                        )
-                                        return@scanOnlineKeyLockMac
-                                    }
-                                    if (mac == null) {
-                                        logger.info(
-                                            "设备检测-设备mac空:${keyBean.rfid}"
-                                        )
-                                        return@scanOnlineKeyLockMac
-                                    }
-                                    logger.info(
-                                        "设备检测-没有使用过的mac:${keyBean.rfid},${
-                                            mac
-                                        }"
-                                    )
-                                    keyBean.mac = mac
-                                    if (cont.isActive) {
-                                        cont.resume(mac)
-                                    }
-                                }
-                            }
-                        }
+            logger.info("设备检测-打开充电:${keyBean.addr},${keyBean.idx}")
+            ModBusController.controlKeyLockAndCharge(true, keyBean.idx, keyBean.addr) {
+                logger.info("设备检测-开始扫描在线蓝牙Mac")
+                BleConnectionManager.scanOnlineKeyLockMac(existsKeyMac) { mac ->
+                    logger.info(
+                        "设备检测-在线的蓝牙设备:${keyBean.rfid},${mac}"
+                    )
+                    if (isDestroy) {
+                        logger.info(
+                            "设备检测-界面已销毁"
+                        )
+                        return@scanOnlineKeyLockMac
+                    }
+                    if (mac == null) {
+                        logger.info(
+                            "设备检测-设备mac空:${keyBean.rfid}"
+                        )
+                        return@scanOnlineKeyLockMac
+                    }
+                    logger.info(
+                        "设备检测-没有使用过的mac:${keyBean.rfid},${
+                            mac
+                        }"
+                    )
+                    keyBean.mac = mac
+                    if (cont.isActive) {
+                        cont.resume(mac)
                     }
                 }
             }
         }
+        return mac
+    }
+
+    fun getData(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            val dockData =
+                ModBusController.dockList.filter { it.type == DeviceConst.DOCK_TYPE_LOCK || it.type == DeviceConst.DOCK_TYPE_KEY || it.type == DeviceConst.DOCK_TYPE_PORTABLE }
+            val keyDock = dockData.filter { it.type == DeviceConst.DOCK_TYPE_KEY }.map {
+                DockData.KeyDock().apply {
+                    keyData.addAll(it.deviceList.filterIsInstance<DockBean.KeyBean>())
+                }
+            }
+            val keyDatas = keyDock.map { it.keyData }.flatten()
+            val newKeyDock = DockData.KeyDock()
+            newKeyDock.keyData.addAll(keyDatas)
+            val newKeyDockList = newKeyDock.keyData.chunked(4).map { subList ->
+                DockData.KeyDock().apply { keyData.addAll(subList) }
+            }
+            val lockDock = dockData.filter { it.type == DeviceConst.DOCK_TYPE_LOCK }.map {
+                DockData.LockDock().apply {
+                    lockData.addAll(it.deviceList.filterIsInstance<DockBean.LockBean>())
+                }
+            }
+            val portableDock =
+                dockData.filter { it.type == DeviceConst.DOCK_TYPE_PORTABLE }.map {
+                    DockData.PortableDock().apply {
+                        deviceData.addAll(it.deviceList.toList())
+                    }
+                }
+            lastDockSnapshot.clear()
+            lastDockSnapshot.addAll(newKeyDockList + portableDock + lockDock)
+            emit(true)
+        }
     }
 }

+ 1 - 0
app/src/main/res/layout-land/fragment_create_job.xml

@@ -546,6 +546,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout-land/fragment_create_sop_job.xml

@@ -512,6 +512,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout-land/fragment_edit_job.xml

@@ -469,6 +469,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout-land/fragment_edit_sop_job.xml

@@ -452,6 +452,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout/fragment_create_job.xml

@@ -544,6 +544,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing_2x"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout/fragment_create_sop_job.xml

@@ -515,6 +515,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout/fragment_edit_job.xml

@@ -468,6 +468,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 1 - 0
app/src/main/res/layout/fragment_edit_sop_job.xml

@@ -455,6 +455,7 @@
                 android:minHeight="@dimen/common_btn_height"
                 android:paddingHorizontal="@dimen/common_spacing_2x"
                 android:text="@string/cancel"
+                android:layout_marginRight="@dimen/common_spacing"
                 android:textColor="@color/white"
                 android:textSize="@dimen/common_btn_text_size" />
         </LinearLayout>

+ 7 - 0
app/src/main/res/layout/fragment_exception_manage.xml

@@ -125,6 +125,13 @@
                 android:gravity="center"
                 android:text="@string/exception_occurrence_time_header"
                 android:textSize="@dimen/common_text_size" />
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/detail"
+                android:textSize="@dimen/common_text_size" />
         </LinearLayout>
 
         <com.drake.statelayout.StateLayout

+ 2 - 2
app/src/main/res/layout/fragment_slots_manage.xml

@@ -19,8 +19,7 @@
             <ImageView
                 android:layout_width="@dimen/title_icon_size"
                 android:layout_height="@dimen/title_icon_size"
-                android:src="@mipmap/dock_no_key"
-                android:tint="@color/black" />
+                android:src="@mipmap/dock_no_key"/>
 
             <TextView
                 android:layout_width="match_parent"
@@ -68,6 +67,7 @@
                 android:id="@+id/loading_tip"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:background="@color/white"
                 android:text="@string/loading_device"
                 android:textSize="@dimen/common_text_size_big"
                 android:textStyle="bold"

+ 143 - 0
app/src/main/res/layout/fragment_workflow_manage.xml

@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="@dimen/common_spacing_2x"
+        android:background="@drawable/home_card_bg"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:id="@+id/title_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:orientation="horizontal"
+            android:paddingHorizontal="@dimen/common_spacing">
+
+            <ImageView
+                android:layout_width="@dimen/title_icon_size"
+                android:layout_height="@dimen/title_icon_size"
+                android:src="@mipmap/icon_workflow_setting" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/common_spacing"
+                android:layout_weight="1"
+                android:text="@string/workflow_manage_title"
+                android:textColor="@color/black"
+                android:textSize="@dimen/normal_text_size_25"
+                android:textStyle="bold" />
+
+            <TextView
+                android:id="@+id/back"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginVertical="5dp"
+                android:layout_marginLeft="@dimen/common_spacing"
+                android:background="@drawable/common_btn"
+                android:drawableLeft="@mipmap/icon_back"
+                android:drawablePadding="@dimen/common_spacing"
+                android:gravity="center"
+                android:minHeight="@dimen/common_btn_height"
+                android:paddingHorizontal="@dimen/common_spacing_2x"
+                android:text="@string/back"
+                android:textColor="@color/black"
+                android:textSize="@dimen/common_btn_text_size" />
+        </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/divider_line_space"
+            android:background="@color/black" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingHorizontal="@dimen/common_spacing"
+            android:paddingVertical="@dimen/common_spacing">
+
+            <TextView
+                android:id="@+id/delete"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/common_spacing"
+                android:background="@drawable/common_btn"
+                android:paddingHorizontal="@dimen/common_spacing_2x"
+                android:text="@string/delete"
+                android:textColor="@color/black"
+                android:textSize="@dimen/common_btn_text_size" />
+
+            <TextView
+                android:id="@+id/import_workflow"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="@dimen/common_spacing"
+                android:background="@drawable/common_btn"
+                android:paddingHorizontal="@dimen/common_spacing_2x"
+                android:text="@string/import_str"
+                android:textColor="@color/black"
+                android:textSize="@dimen/common_btn_text_size" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="@dimen/common_spacing_2x"
+            android:layout_marginTop="@dimen/common_spacing"
+            android:background="@drawable/common_card_bg"
+            android:divider="@drawable/divider_table"
+            android:showDividers="middle">
+
+            <CheckBox
+                android:id="@+id/select_all"
+                android:layout_width="30dp"
+                android:layout_height="30dp"
+                android:layout_gravity="center"
+                android:layout_margin="@dimen/common_spacing" />
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/workflow_name"
+                android:textSize="@dimen/common_text_size" />
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/status"
+                android:textSize="@dimen/common_text_size" />
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/detail"
+                android:textSize="@dimen/common_text_size" />
+        </LinearLayout>
+
+
+        <com.drake.statelayout.StateLayout
+            android:id="@+id/state"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginHorizontal="@dimen/common_spacing_2x"
+            android:layout_marginBottom="@dimen/common_spacing"
+            android:background="@drawable/common_card_bg">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/list_rv"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="@drawable/common_card_bg" />
+        </com.drake.statelayout.StateLayout>
+    </LinearLayout>
+</layout>

+ 10 - 0
app/src/main/res/layout/item_exception_manage.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout xmlns:android="http://schemas.android.com/apk/res/android">
+
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
@@ -36,5 +37,14 @@
             android:layout_weight="1"
             android:gravity="center"
             android:textSize="@dimen/common_text_size" />
+
+        <TextView
+            android:id="@+id/view"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:gravity="center"
+            android:text="@string/view"
+            android:textSize="@dimen/common_text_size" />
     </LinearLayout>
 </layout>

BIN
app/src/main/res/mipmap-xhdpi/icon_workflow_setting.png


+ 11 - 0
app/src/main/res/navigation/nav_job_manage.xml

@@ -36,6 +36,9 @@
         <action
             android:id="@+id/action_jobManageHomeFragment_to_myTodoListFragment"
             app:destination="@id/myTodoListFragment" />
+        <action
+            android:id="@+id/action_jobManageHomeFragment_to_workflowManageFragment"
+            app:destination="@id/workflowManageFragment" />
     </fragment>
     <fragment
         android:id="@+id/createJobFragment"
@@ -231,4 +234,12 @@
         android:id="@+id/editSopWorkflowSettingFragment"
         android:name="com.grkj.iscs.features.main.fragment.common.EditSopWorkflowSettingFragment"
         android:label="EditSopWorkflowSettingFragment" />
+    <fragment
+        android:id="@+id/workflowManageFragment"
+        android:name="com.grkj.iscs.features.main.fragment.job_manage.WorkflowManageFragment"
+        android:label="WorkflowManageFragment" >
+        <action
+            android:id="@+id/action_workflowManageFragment_to_workflowSettingFragment"
+            app:destination="@id/workflowSettingFragment" />
+    </fragment>
 </navigation>

+ 5 - 0
app/src/main/res/values-en/strings.xml

@@ -508,5 +508,10 @@
     <string name="handle_time_last_30_days">Last 30 days</string>
     <string name="handle_time_custom_time_range">Custom time range</string>
     <string name="please_select_handle_time">Please select handle time</string>
+    <string name="currently_no_hardware_can_be_report">Currently no hardware can be report</string>
+    <string name="currently_no_job_can_be_report">Current no job ticket can be report</string>
+    <string name="workflow_manage_title">Workflow manager</string>
+    <string name="workflow_name">Workflow name</string>
+    <string name="import_str">Import</string>
 
 </resources>

+ 8 - 3
app/src/main/res/values-zh/strings.xml

@@ -504,9 +504,14 @@
     <string name="close">关闭</string>
     <string name="handle_failed">处理失败</string>
     <string name="handle_time">处理时间:</string>
-    <string name="handle_time_last_7_days">近7天</string>
-    <string name="handle_time_last_30_days">近30天</string>
-    <string name="handle_time_custom_time_range">自定义时间范围</string>
+    <string name="handle_time_last_7_days">近7天</string>
+    <string name="handle_time_last_30_days">近30天</string>
+    <string name="handle_time_custom_time_range">自定义区间</string>
     <string name="please_select_handle_time">请选择处理时间</string>
+    <string name="currently_no_hardware_can_be_report">当前没有硬件可以上报</string>
+    <string name="currently_no_job_can_be_report">当前没有作业可以上报</string>
+    <string name="workflow_manage_title">流程模式管理</string>
+    <string name="workflow_name">流程模式名称</string>
+    <string name="import_str">导入</string>
 
 </resources>

+ 8 - 3
app/src/main/res/values/strings.xml

@@ -507,9 +507,14 @@
     <string name="close">关闭</string>
     <string name="handle_failed">处理失败</string>
     <string name="handle_time">处理时间:</string>
-    <string name="handle_time_last_7_days">近7天</string>
-    <string name="handle_time_last_30_days">近30天</string>
-    <string name="handle_time_custom_time_range">自定义时间范围</string>
+    <string name="handle_time_last_7_days">近7天</string>
+    <string name="handle_time_last_30_days">近30天</string>
+    <string name="handle_time_custom_time_range">自定义区间</string>
     <string name="please_select_handle_time">请选择处理时间</string>
+    <string name="currently_no_hardware_can_be_report">当前没有硬件可以上报</string>
+    <string name="currently_no_job_can_be_report">当前没有作业可以上报</string>
+    <string name="workflow_manage_title">流程模式管理</string>
+    <string name="workflow_name">流程模式名称</string>
+    <string name="import_str">导入</string>
 
 </resources>

+ 1 - 0
data/src/main/java/com/grkj/data/dao/IsSopDao.kt

@@ -120,6 +120,7 @@ interface IsSopDao {
             WHERE su.del_flag = 0 and isu.sop_id = :sopId
             GROUP BY
               su.user_id,
+              isu.group_id,
               isu.user_role,
               su.nick_name,
               su.status

+ 1 - 0
data/src/main/java/com/grkj/data/dao/JobTicketDao.kt

@@ -183,6 +183,7 @@ interface JobTicketDao {
             WHERE su.del_flag = 0 and ijtu.ticket_id = :ticketId
             GROUP BY
               su.user_id,
+              ijtu.group_id,
               ijtu.user_role,
               su.nick_name,
               su.status

+ 1 - 0
data/src/main/java/com/grkj/data/dao/UserDao.kt

@@ -148,6 +148,7 @@ interface UserDao {
             WHERE su.del_flag = 0 and ijtu.ticket_id = :ticketId and su.user_id in (:userIds)
             GROUP BY
               su.user_id,
+              ijtu.group_id,
               ijtu.user_role,
               su.nick_name,
               su.status

+ 1 - 1
data/src/main/java/com/grkj/data/dao/WorkflowStepDao.kt

@@ -76,7 +76,7 @@ interface WorkflowStepDao {
     fun isUnlockBeforeLock(modeId: Long): Boolean
 
 
-    @Query("select * from is_workflow_mode")
+    @Query("select * from is_workflow_mode where deleted = 0")
     fun getWorkflowModes(): List<WorkflowMode>
 
     @Query("select * from is_workflow_mode where mode_id = :modeId")

+ 3 - 1
data/src/main/java/com/grkj/data/enums/RoleFunctionalPermissionsEnum.kt

@@ -22,6 +22,7 @@ enum class RoleFunctionalPermissionsEnum(
     EXCEPTION_JOB("exception_job", "异常作业", 1, listOf()),
     CREATE_JOB("job_ticket_manage:create_job", "新建作业", 1, listOf()),
     JOB_MANAGE("job_ticket_manage:job_manage", "作业管理", 1, listOf()),
+    WORKFLOW_MANAGE("job_ticket_manage:workflow_manage", "流程模式管理", 1, listOf()),
     CREATE_SOP_JOB("job_ticket_manage:create_sop_job", "新建SOP作业", 1, listOf()),
     LOCKED_POINT("job_ticket_manage:locked_point", "锁定中的点位", 1, listOf()),
     SLOT_MANAGE("hardware_manage:slot_manage", "仓位管理", 1, listOf()),
@@ -75,7 +76,8 @@ enum class RoleFunctionalPermissionsEnum(
             CREATE_JOB,
             JOB_MANAGE,
             CREATE_SOP_JOB,
-            LOCKED_POINT
+            LOCKED_POINT,
+            WORKFLOW_MANAGE
         )
     ),
     DATA_HOME_MANAGE(

+ 1 - 1
data/src/main/java/com/grkj/data/model/dos/WorkflowMode.kt

@@ -12,7 +12,7 @@ import com.sik.sikcore.date.TimeUtils
  * 工作流模式表实体
  */
 @Entity(tableName = "is_workflow_mode")
-class WorkflowMode {
+open class WorkflowMode {
     /** 自增主键,模式 ID */
     @PrimaryKey(autoGenerate = true)
     @ColumnInfo(name = "mode_id")

+ 13 - 0
data/src/main/java/com/grkj/data/model/vo/WorkflowModeVo.kt

@@ -0,0 +1,13 @@
+package com.grkj.data.model.vo
+
+import androidx.room.Ignore
+import com.grkj.data.model.dos.WorkflowMode
+
+/**
+ * 流程模式实体
+ */
+class WorkflowModeVo : WorkflowMode() {
+
+    @Ignore
+    var isSelected: Boolean = false
+}

+ 1 - 1
ui-base/src/main/java/com/grkj/ui_base/utils/ble/BleConnectionManager.kt

@@ -704,7 +704,7 @@ object BleConnectionManager {
         BLEScanner.stopScan()
         BLEScanner.startScan(object : IBluetoothScanCallback {
             override fun onDeviceFound(device: BluetoothDevice) {
-                logger.info("发现设备:${device.address}")
+                logger.info(" |:${device.address}")
                 callback(device.address)
             }