Explorar el Código

feat(登录)
- 优化登录结果提示,增加多种登录结果的中文提示

feat(硬件管理)
- 更新卡片和RFID标签对话框增加RFID卡读取功能

refactor(作业管理)
- 优化作业执行中判断是否解锁优先的逻辑
- 删除作业时同步删除关联的异常数据
- 优化我的待办事项标题展示

refactor(硬件管理)
- 点位管理和RFID标签管理增加使用中校验,使用中的点位和RFID标签不可编辑和删除

refactor(异常管理)
- 优化异常处理流程,修复异常处理状态同步问题

fix(异常管理)
- 修复异常作业管理列表布局问题
- 修复异常详情中获取作业数据逻辑错误

周文健 hace 3 meses
padre
commit
99dbba598a
Se han modificado 40 ficheros con 442 adiciones y 64 borrados
  1. 54 8
      app/src/main/java/com/grkj/iscs/features/login/activity/LoginActivity.kt
  2. 5 4
      app/src/main/java/com/grkj/iscs/features/login/dialog/LoginDialog.kt
  3. 6 5
      app/src/main/java/com/grkj/iscs/features/login/viewmodel/LoginViewModel.kt
  4. 6 8
      app/src/main/java/com/grkj/iscs/features/main/dialog/CheckFaceDialog.kt
  5. 16 0
      app/src/main/java/com/grkj/iscs/features/main/dialog/hardware_manage/UpdateCardDialog.kt
  6. 16 0
      app/src/main/java/com/grkj/iscs/features/main/dialog/hardware_manage/UpdateRfidTokenDialog.kt
  7. 10 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/data_manage/PointMangeFragment.kt
  8. 1 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/exception_manage/ExceptionDetailFragment.kt
  9. 2 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/exception_manage/ExceptionJobFragment.kt
  10. 10 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/hardware_manage/RfidTokenManageFragment.kt
  11. 1 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobExecuteFragment.kt
  12. 1 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/MyTodoListFragment.kt
  13. 18 1
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/data_manage/PointManageViewModel.kt
  14. 2 2
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/exception_manage/ExceptionJobViewModel.kt
  15. 19 1
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/hardware_manage/RfidTokenManageViewModel.kt
  16. 3 3
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobExecuteViewModel.kt
  17. 17 2
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobManageViewModel.kt
  18. 9 0
      app/src/main/res/layout/fragment_exception_job_manage.xml
  19. 9 0
      app/src/main/res/layout/item_exception_job_manage.xml
  20. 13 0
      app/src/main/res/values-en/strings.xml
  21. 13 0
      app/src/main/res/values-zh/strings.xml
  22. 13 0
      app/src/main/res/values/strings.xml
  23. 18 0
      data/src/main/java/com/grkj/data/dao/ExceptionDao.kt
  24. 6 0
      data/src/main/java/com/grkj/data/dao/IsolationPointDao.kt
  25. 56 0
      data/src/main/java/com/grkj/data/dao/JobTicketDao.kt
  26. 5 0
      data/src/main/java/com/grkj/data/repository/IExceptionRepository.kt
  27. 5 0
      data/src/main/java/com/grkj/data/repository/IHardwareRepository.kt
  28. 20 0
      data/src/main/java/com/grkj/data/repository/IJobTicketRepository.kt
  29. 1 1
      data/src/main/java/com/grkj/data/repository/IUserRepository.kt
  30. 4 0
      data/src/main/java/com/grkj/data/repository/impl/network/NetworkExceptionRepository.kt
  31. 4 0
      data/src/main/java/com/grkj/data/repository/impl/network/NetworkHardwareRepository.kt
  32. 18 2
      data/src/main/java/com/grkj/data/repository/impl/network/NetworkJobTicketRepository.kt
  33. 7 7
      data/src/main/java/com/grkj/data/repository/impl/network/NetworkUserRepository.kt
  34. 4 0
      data/src/main/java/com/grkj/data/repository/impl/network/NetworkWorkflowRepository.kt
  35. 10 2
      data/src/main/java/com/grkj/data/repository/impl/standard/ExceptionRepository.kt
  36. 4 0
      data/src/main/java/com/grkj/data/repository/impl/standard/HardwareRepository.kt
  37. 19 0
      data/src/main/java/com/grkj/data/repository/impl/standard/JobTicketRepository.kt
  38. 4 4
      data/src/main/java/com/grkj/data/repository/impl/standard/UserRepository.kt
  39. 3 3
      data/src/main/java/com/grkj/data/repository/impl/standard/WorkflowRepository.kt
  40. 10 6
      ui-base/src/main/java/com/grkj/ui_base/base/BaseViewModel.kt

+ 54 - 8
app/src/main/java/com/grkj/iscs/features/login/activity/LoginActivity.kt

@@ -14,7 +14,9 @@ import com.drake.brv.utils.grid
 import com.drake.brv.utils.linear
 import com.drake.brv.utils.models
 import com.drake.brv.utils.setup
+import com.google.android.gms.common.internal.service.Common
 import com.grkj.data.data.MainDomainData
+import com.grkj.data.enums.LoginResultEnum
 import com.grkj.data.model.local.LoginMenuEntity
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.ActivityLoginBinding
@@ -89,10 +91,48 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>() {
         holder.itemView.setOnClickListener {
             LoginDialog.show(this@LoginActivity, viewModel, item.loginType) {
                 LoadingEvent.sendLoadingEvent()
-                if (it) {
-                    startActivity(Intent(this@LoginActivity, MainActivity::class.java))
-                } else {
-                    PopTip.build().tip(CommonUtils.getStr(R.string.login_failed))
+                when (it) {
+                    LoginResultEnum.FINGERPRINTER_VERIFY_SUCCESS -> {
+                        showToast(CommonUtils.getStr(R.string.fingerprint_login_success).toString())
+                        startActivity(Intent(this@LoginActivity, MainActivity::class.java))
+                    }
+
+                    LoginResultEnum.FINGERPRINTER_VERIFY_FAILED -> showToast(
+                        CommonUtils.getStr(R.string.fingerprint_login_failed).toString()
+                    )
+
+                    LoginResultEnum.FACE_VERIFY_SUCCESS -> {
+                        showToast(CommonUtils.getStr(R.string.face_login_success).toString())
+                        startActivity(Intent(this@LoginActivity, MainActivity::class.java))
+                    }
+
+                    LoginResultEnum.FACE_VERIFY_FAILED -> showToast(
+                        CommonUtils.getStr(R.string.face_login_failed).toString()
+                    )
+
+                    LoginResultEnum.USERNAME_PASSWORD_LOGIN_SUCCESS -> {
+                        showToast(
+                            CommonUtils.getStr(R.string.username_passowrd_login_success).toString()
+                        )
+                        startActivity(Intent(this@LoginActivity, MainActivity::class.java))
+                    }
+
+                    LoginResultEnum.USERNAME_OR_PASSWORD_ERROR -> showToast(
+                        CommonUtils.getStr(R.string.username_or_password_error).toString()
+                    )
+
+                    LoginResultEnum.USERNAME_PASSWORD_NOT_EXISTS -> showToast(
+                        CommonUtils.getStr(R.string.username_password_not_exists).toString()
+                    )
+
+                    LoginResultEnum.JOB_CARD_LOGIN_SUCCESS -> {
+                        showToast(CommonUtils.getStr(R.string.job_card_login_success).toString())
+                        startActivity(Intent(this@LoginActivity, MainActivity::class.java))
+                    }
+
+                    LoginResultEnum.JOB_CARD_LOGIN_FAILED -> showToast(
+                        CommonUtils.getStr(R.string.job_card_login_failed).toString()
+                    )
                 }
             }
         }
@@ -163,10 +203,11 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>() {
                     ImageConvertUtils.bitmapToBase64(bitmap).toString()
                 ).observe(this@LoginActivity) { isSuccess ->
                     LoadingEvent.sendLoadingEvent()
-                    if (isSuccess) {
+                    if (isSuccess == LoginResultEnum.FINGERPRINTER_VERIFY_SUCCESS) {
+                        showToast(CommonUtils.getStr(R.string.fingerprint_login_success).toString())
                         startActivity(Intent(this@LoginActivity, MainActivity::class.java))
                     } else {
-                        PopTip.build().tip(CommonUtils.getStr(R.string.login_failed))
+                        showToast(CommonUtils.getStr(R.string.fingerprint_login_failed).toString())
                     }
                 }
             }
@@ -193,10 +234,15 @@ class LoginActivity : BaseActivity<ActivityLoginBinding>() {
                     )
                     viewModel.loginWithCard(cardNo).observe(this) { isSuccess ->
                         LoadingEvent.sendLoadingEvent()
-                        if (isSuccess) {
+                        if (isSuccess == LoginResultEnum.JOB_CARD_LOGIN_SUCCESS) {
+                            showToast(
+                                CommonUtils.getStr(R.string.job_card_login_success).toString()
+                            )
                             startActivity(Intent(this@LoginActivity, MainActivity::class.java))
                         } else {
-                            PopTip.tip(CommonUtils.getStr(R.string.login_failed))
+                            showToast(
+                                CommonUtils.getStr(R.string.job_card_login_failed).toString()
+                            )
                         }
                     }
                     // 重置cardNo

+ 5 - 4
app/src/main/java/com/grkj/iscs/features/login/dialog/LoginDialog.kt

@@ -3,6 +3,7 @@ package com.grkj.iscs.features.login.dialog
 import android.graphics.Bitmap
 import android.view.View
 import androidx.lifecycle.LifecycleOwner
+import com.grkj.data.enums.LoginResultEnum
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.DialogLoginBinding
 import com.grkj.iscs.features.login.viewmodel.LoginViewModel
@@ -27,7 +28,7 @@ import com.sik.sikimage.ImageConvertUtils
 class LoginDialog(
     private var lifecycleOwner: LifecycleOwner,
     private var viewModel: LoginViewModel,
-    private var callBack: ((Boolean) -> Unit)? = null
+    private var callBack: ((LoginResultEnum) -> Unit)? = null
 ) : OnBindView<CustomDialog>(R.layout.dialog_login) {
 
     private var cardNo = ""
@@ -158,7 +159,7 @@ class LoginDialog(
             lifecycleOwner: LifecycleOwner,
             viewModel: LoginViewModel,
             loginType: Int,
-            callBack: ((Boolean) -> Unit)?
+            callBack: ((LoginResultEnum) -> Unit)?
         ) {
             CustomDialog.show(LoginDialog(lifecycleOwner, viewModel, callBack).apply {
                 showByType(loginType)
@@ -175,10 +176,10 @@ class LoginDialog(
                 mBinding.preview!!
             ) { bitmap, userId ->
                 viewModel.loginWithUserId(userId).observe(lifecycleOwner) {
-                    if (it == false) {
+                    if (it == LoginResultEnum.FACE_VERIFY_FAILED) {
                         viewModel.loginWithFace(ImageConvertUtils.bitmapToBase64(bitmap).toString())
                             .observe(lifecycleOwner) {
-                                if (it == false) {
+                                if (it == LoginResultEnum.FACE_VERIFY_FAILED) {
                                     ThreadUtils.runOnMainDelayed(1000) {
                                         inDetecting = false
                                         inFaceChecking = false

+ 6 - 5
app/src/main/java/com/grkj/iscs/features/login/viewmodel/LoginViewModel.kt

@@ -2,6 +2,7 @@ package com.grkj.iscs.features.login.viewmodel
 
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.liveData
+import com.grkj.data.enums.LoginResultEnum
 import com.grkj.data.repository.IUserRepository
 import com.grkj.shared.utils.ArcSoftUtil
 import com.grkj.ui_base.base.BaseViewModel
@@ -38,7 +39,7 @@ class LoginViewModel @Inject constructor(
     fun loginWithAccount(
         username: String,
         password: String,
-    ): LiveData<Boolean> {
+    ): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
             val loginSuccess = userRepository.loginWithAccount(username, password)
             emit(loginSuccess)
@@ -48,7 +49,7 @@ class LoginViewModel @Inject constructor(
     /**
      * 刷卡登录
      */
-    fun loginWithCard(cardNo: String): LiveData<Boolean> {
+    fun loginWithCard(cardNo: String): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
             val loginSuccess = userRepository.loginWithCard(cardNo)
             emit(loginSuccess)
@@ -58,7 +59,7 @@ class LoginViewModel @Inject constructor(
     /**
      * 指纹登录
      */
-    fun loginWithFingerprint(fingerprint: String): LiveData<Boolean> {
+    fun loginWithFingerprint(fingerprint: String): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
             val loginSuccess = userRepository.loginWithFingerprint(fingerprint)
             emit(loginSuccess)
@@ -68,7 +69,7 @@ class LoginViewModel @Inject constructor(
     /**
      * 人脸登录
      */
-    fun loginWithFace(face: String): LiveData<Boolean> {
+    fun loginWithFace(face: String): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
             val loginSuccess = userRepository.loginWithFace(face)
             emit(loginSuccess)
@@ -78,7 +79,7 @@ class LoginViewModel @Inject constructor(
     /**
      * 人脸登录
      */
-    fun loginWithUserId(userId: Long?): LiveData<Boolean> {
+    fun loginWithUserId(userId: Long?): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
             val loginSuccess = userRepository.loginWithUserId(userId)
             emit(loginSuccess)

+ 6 - 8
app/src/main/java/com/grkj/iscs/features/main/dialog/CheckFaceDialog.kt

@@ -3,6 +3,7 @@ package com.grkj.iscs.features.main.dialog
 import android.graphics.Bitmap
 import android.view.View
 import androidx.lifecycle.LifecycleOwner
+import com.grkj.data.enums.LoginResultEnum
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.DialogCheckFaceBinding
 import com.grkj.shared.utils.ArcSoftUtil
@@ -27,7 +28,7 @@ import com.sik.sikimage.ImageConvertUtils
 class CheckFaceDialog(
     private var lifecycleOwner: LifecycleOwner,
     private var viewModel: BaseViewModel,
-    private var callBack: ((Boolean) -> Unit)? = null
+    private var callBack: ((LoginResultEnum) -> Unit)? = null
 ) : OnBindView<CustomDialog>(R.layout.dialog_check_face) {
     private var mLoginType = 0 // 0:人脸 1:指纹 2:工卡 3:账号
     private var inFaceChecking: Boolean = false
@@ -106,7 +107,7 @@ class CheckFaceDialog(
                         viewModel.checkFinger(
                             ImageConvertUtils.bitmapToBase64(bitmap).toString()
                         ).observe(lifecycleOwner) {
-                            if (it) {
+                            if (it == LoginResultEnum.FINGERPRINTER_VERIFY_SUCCESS) {
                                 callBack?.invoke(it)
                             } else {
                                 PopTip.tip(R.string.verify_failed)
@@ -134,7 +135,7 @@ class CheckFaceDialog(
             lifecycleOwner: LifecycleOwner,
             viewModel: BaseViewModel,
             loginType: Int,
-            callBack: ((Boolean) -> Unit)?
+            callBack: ((LoginResultEnum) -> Unit)?
         ) {
             CustomDialog.show(CheckFaceDialog(lifecycleOwner, viewModel, callBack).apply {
                 showByType(loginType)
@@ -162,18 +163,15 @@ class CheckFaceDialog(
                     viewModel.checkFace(
                         ImageConvertUtils.bitmapToBase64(itBitmap).toString()
                     ).observe(lifecycleOwner) {
-                        if (it == false) {
+                        if (it == LoginResultEnum.FACE_VERIFY_FAILED) {
                             ThreadUtils.runOnMainDelayed(1000) {
                                 ArcSoftUtil.inDetecting = false
                                 inFaceChecking = false
                             }
+                            PopTip.tip(R.string.face_login_failed)
                         } else {
                             ArcSoftUtil.stop()
-                        }
-                        if (it) {
                             callBack?.invoke(it)
-                        } else {
-                            PopTip.tip(R.string.verify_failed)
                         }
                     }
                     LoadingEvent.sendLoadingEvent(

+ 16 - 0
app/src/main/java/com/grkj/iscs/features/main/dialog/hardware_manage/UpdateCardDialog.kt

@@ -2,17 +2,22 @@ package com.grkj.iscs.features.main.dialog.hardware_manage
 
 import android.view.View
 import androidx.core.view.isVisible
+import com.grkj.data.data.EventConstants
 import com.grkj.data.enums.CommonDictDataEnum
 import com.grkj.data.model.dos.IsJobCard
 import com.grkj.data.model.vo.UpdateCardDataVo
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.DialogUpdateCardBinding
 import com.grkj.iscs.features.main.dialog.TextDropDownDialog
+import com.grkj.shared.model.EventBean
 import com.grkj.ui_base.utils.CommonUtils
+import com.grkj.ui_base.utils.event.RFIDCardReadEvent
 import com.grkj.ui_base.utils.extension.tip
 import com.kongzue.dialogx.dialogs.CustomDialog
 import com.kongzue.dialogx.dialogs.PopTip
 import com.kongzue.dialogx.interfaces.OnBindView
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
 
 /**
  * 更新卡片对话框,基于 DialogX
@@ -74,6 +79,17 @@ class UpdateCardDialog(
         }
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    open fun onEvent(event: EventBean<*>) {
+        when (event.code) {
+            EventConstants.EVENT_RFID_CARD_READ -> {
+                (event.data as RFIDCardReadEvent).let {
+                    binding.cardNfcEt.setText(it.rfidNo)
+                }
+            }
+        }
+    }
+
     companion object {
         /**
          * 显示更新卡片对话框并设置回调

+ 16 - 0
app/src/main/java/com/grkj/iscs/features/main/dialog/hardware_manage/UpdateRfidTokenDialog.kt

@@ -1,16 +1,21 @@
 package com.grkj.iscs.features.main.dialog.hardware_manage
 
 import android.view.View
+import com.grkj.data.data.EventConstants
 import com.grkj.data.enums.CommonDictDataEnum
 import com.grkj.data.model.dos.IsRfidToken
 import com.grkj.data.model.vo.UpdateRfidTokenDataVo
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.DialogUpdateRfidTokenBinding
+import com.grkj.shared.model.EventBean
 import com.grkj.ui_base.utils.CommonUtils
+import com.grkj.ui_base.utils.event.RFIDCardReadEvent
 import com.grkj.ui_base.utils.extension.tip
 import com.kongzue.dialogx.dialogs.CustomDialog
 import com.kongzue.dialogx.dialogs.PopTip
 import com.kongzue.dialogx.interfaces.OnBindView
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
 
 /**
  * 更新 RFID 标签对话框,基于 DialogX
@@ -70,6 +75,17 @@ class UpdateRfidTokenDialog(
         }
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    open fun onEvent(event: EventBean<*>) {
+        when (event.code) {
+            EventConstants.EVENT_RFID_CARD_READ -> {
+                (event.data as RFIDCardReadEvent).let {
+                    binding.rfidEt.setText(it.rfidNo)
+                }
+            }
+        }
+    }
+
     companion object {
         /**
          * 显示更新 RFID 标签对话框并设置回调

+ 10 - 1
app/src/main/java/com/grkj/iscs/features/main/fragment/data_manage/PointMangeFragment.kt

@@ -1,7 +1,6 @@
 package com.grkj.iscs.features.main.fragment.data_manage
 
 import android.graphics.Color
-import android.view.Gravity
 import androidx.fragment.app.viewModels
 import com.drake.brv.BindingAdapter
 import com.drake.brv.annotaion.DividerOrientation
@@ -151,6 +150,10 @@ class PointMangeFragment : BaseFragment<FragmentPointManageBinding>() {
             setSelectAllListener()
         }
         itemBinding.root.setDebouncedClickListener {
+            if (item.pointId in viewModel.inUsePointIds) {
+                showToast(CommonUtils.getStr(R.string.point_in_use).toString())
+                return@setDebouncedClickListener
+            }
             viewModel.initDialogData().observe(this@PointMangeFragment) {
                 UpdatePointDialog.show(item, viewModel.workstationData.map {
                     TextDropDownDialog.SimpleTextDropDownEntity(
@@ -201,6 +204,7 @@ class PointMangeFragment : BaseFragment<FragmentPointManageBinding>() {
     override fun initData() {
         super.initData()
         viewModel.pointFilterData = null
+        viewModel.getInUsePointData().observe(this) {}
         getPointData(nextPage = false)
     }
 
@@ -228,6 +232,11 @@ class PointMangeFragment : BaseFragment<FragmentPointManageBinding>() {
             PopTip.build().tip(R.string.please_select_point)
             return
         }
+        if (viewModel.pointManageDataList.filter { it.isSelected }.map { it.pointId }
+                .any { it in viewModel.inUsePointIds }) {
+            showToast(CommonUtils.getStr(R.string.selected_point_already_in_use).toString())
+            return
+        }
         TipDialog.show(
             msg = CommonUtils.getStr(R.string.check_delete_point).toString(),
             countDownTime = 10,

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

@@ -268,7 +268,7 @@ class ExceptionDetailFragment : BaseFragment<FragmentExceptionDetailBinding>() {
         }
         exceptionJobViewModel.getJobTicketData().observe(this) {
             if (it) {
-                exceptionJobViewModel.isUnlockFirst(exceptionJobViewModel.ticketData?.modeId!!)
+                exceptionJobViewModel.isUnlockFirst(exceptionJobViewModel.ticketData?.ticketId!!)
                     .observe(this) {}
                 exceptionJobViewModel.getWorkflowSteps(exceptionJobViewModel.ticketData?.modeId!!)
                     .observe(this) {

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

@@ -104,6 +104,8 @@ class ExceptionJobFragment : BaseFragment<FragmentExceptionJobBinding>() {
                                         onConfirmClick = {
                                             handleExceptionCheck()
                                         })
+                                } else {
+                                    handleExceptionCheck()
                                 }
                             })
                     } else {

+ 10 - 1
app/src/main/java/com/grkj/iscs/features/main/fragment/hardware_manage/RfidTokenManageFragment.kt

@@ -57,7 +57,7 @@ class RfidTokenManageFragment : BaseFragment<FragmentRfidTokenManageBinding>() {
                 }
             }
         }
-        binding.reset.setDebouncedClickListener{
+        binding.reset.setDebouncedClickListener {
             viewModel.rfidTokenFilterData = null
             loadTokens(true)
         }
@@ -107,6 +107,10 @@ class RfidTokenManageFragment : BaseFragment<FragmentRfidTokenManageBinding>() {
             }
         }
         bind.root.setOnClickListener {
+            if (item.rfidId in viewModel.inUseRfidIds){
+                showToast(CommonUtils.getStr(R.string.rfid_in_use).toString())
+                return@setOnClickListener
+            }
             UpdateRfidTokenDialog.show(item) { vo, dialog ->
                 viewModel.updateRfidToken(vo).observe(this) { ok ->
                     dialog.dismiss()
@@ -131,6 +135,7 @@ class RfidTokenManageFragment : BaseFragment<FragmentRfidTokenManageBinding>() {
     override fun initData() {
         super.initData()
         viewModel.rfidTokenFilterData = null
+        viewModel.getInUsePointData().observe(this) {}
         loadTokens(reset = true)
     }
 
@@ -153,6 +158,10 @@ class RfidTokenManageFragment : BaseFragment<FragmentRfidTokenManageBinding>() {
         if (viewModel.rfidTokenManageDataList.none { it.isSelected }) {
             PopTip.tip(R.string.please_select_rfid_token); return
         }
+        if (viewModel.rfidTokenManageDataList.map { it.rfidId }.any { it in viewModel.inUseRfidIds }){
+            showToast(CommonUtils.getStr(R.string.selected_rfid_in_use).toString())
+            return
+        }
         TipDialog.show(
             msg = CommonUtils.getStr(R.string.check_delete_rfid_token).toString(),
             countDownTime = 10,

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

@@ -633,7 +633,7 @@ class JobExecuteFragment : BaseFragment<FragmentJobExecuteBinding>() {
     private fun getData(refresh: Boolean = false) {
         viewModel.getJobTicketData(refresh).observe(this) {
             if (it) {
-                viewModel.isUnlockFirst(viewModel.ticketData?.modeId!!).observe(this) {}
+                viewModel.isUnlockFirst(viewModel.ticketData?.ticketId!!).observe(this) {}
                 viewModel.getWorkflowSteps(viewModel.ticketData?.modeId!!).observe(this) {
                     viewModel.currentStepData =
                         viewModel.ticketStep.firstOrNull { it.stepStatus == "0" }

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

@@ -263,7 +263,7 @@ class MyTodoListFragment : BaseFragment<FragmentMyTodoListBinding>() {
         val itemBinding = holder.getBinding<ItemMyTodoBinding>()
         val item = holder.getModel<TodoItemVo>()
         itemBinding.todoTitle.text =
-            "${getTodoTitlePrefix(item)}${item.todoType.todoTitle}${item.groupName?.let { if (it.isEmpty()) "(${item.todoContent})" else "(${it})" }}"
+            "${getTodoTitlePrefix(item)}${item.todoType.todoTitle}${item.groupName?.let { if (it.isEmpty()) "(${item.todoTitle})" else "(${it})" }}"
         if (item.todoStatus == TodoStatusEnum.TODO) {
             itemBinding.todoTitle.setTextColor(requireContext().getColor(R.color.tag_error))
         } else {

+ 18 - 1
app/src/main/java/com/grkj/iscs/features/main/viewmodel/data_manage/PointManageViewModel.kt

@@ -5,10 +5,12 @@ import androidx.lifecycle.liveData
 import com.grkj.data.model.dos.IsRfidToken
 import com.grkj.data.model.dos.IsWorkstation
 import com.grkj.data.model.vo.AddPointManageVo
+import com.grkj.data.model.vo.LockedPointVo
 import com.grkj.data.model.vo.PointManageFilterVo
 import com.grkj.data.model.vo.PointManageVo
 import com.grkj.data.model.vo.UpdatePointManageVo
 import com.grkj.data.repository.IIsolationPointRepository
+import com.grkj.data.repository.IJobTicketRepository
 import com.grkj.data.repository.IRfidTokenRepository
 import com.grkj.data.repository.IWorkstationRepository
 import com.grkj.iscs.R
@@ -25,7 +27,8 @@ import javax.inject.Inject
 class PointManageViewModel @Inject constructor(
     val isolationPointRepository: IIsolationPointRepository,
     val rfidTokenRepository: IRfidTokenRepository,
-    val workstationRepository: IWorkstationRepository
+    val workstationRepository: IWorkstationRepository,
+    val jobTicketRepository: IJobTicketRepository
 ) : BaseViewModel() {
     private var current: Int = 0
     private var size: Int = 50
@@ -34,6 +37,8 @@ class PointManageViewModel @Inject constructor(
     var pointManageDataList: MutableList<PointManageVo> = mutableListOf()
     var pointFilterData: PointManageFilterVo? = null
 
+    var inUsePointIds: MutableList<Long> = mutableListOf()
+
     /**
      * 删除选中隔离点
      */
@@ -109,4 +114,16 @@ class PointManageViewModel @Inject constructor(
             }
         }
     }
+
+    /**
+     * 获取使用中的点位
+     */
+    fun getInUsePointData(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            inUsePointIds =
+                (jobTicketRepository.getAllInUsePointsData() + jobTicketRepository.getAllLockedPointsData()
+                    .mapNotNull { it.pointId }).distinct().toMutableList()
+            emit(true)
+        }
+    }
 }

+ 2 - 2
app/src/main/java/com/grkj/iscs/features/main/viewmodel/exception_manage/ExceptionJobViewModel.kt

@@ -147,9 +147,9 @@ class ExceptionJobViewModel @Inject constructor(
     /**
      * 是否解锁优先
      */
-    fun isUnlockFirst(modeId: Long): LiveData<Boolean> {
+    fun isUnlockFirst(ticketId: Long): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            isUnlockFirst = workflowRepository.isUnlockBeforeLock(modeId)
+            isUnlockFirst = jobTicketRepository.isUnLockBeforeLock(ticketId)
             emit(true)
         }
     }

+ 19 - 1
app/src/main/java/com/grkj/iscs/features/main/viewmodel/hardware_manage/RfidTokenManageViewModel.kt

@@ -8,6 +8,7 @@ import com.grkj.data.model.vo.AddRfidTokenDataVo
 import com.grkj.data.model.vo.RfidTokenManageFilterVo
 import com.grkj.data.model.vo.UpdateRfidTokenDataVo
 import com.grkj.data.repository.IHardwareRepository
+import com.grkj.data.repository.IJobTicketRepository
 import com.grkj.iscs.R
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.utils.CommonUtils
@@ -21,13 +22,17 @@ import javax.inject.Inject
  */
 @HiltViewModel
 class RfidTokenManageViewModel @Inject constructor(
-    private val hardwareRepository: IHardwareRepository
+    private val hardwareRepository: IHardwareRepository,
+    val jobTicketRepository: IJobTicketRepository
 ) : BaseViewModel() {
     private var current: Int = 0
     private val size: Int = 50
     var rfidTokenManageDataList: MutableList<IsRfidToken> = mutableListOf()
     var rfidTokenFilterData: RfidTokenManageFilterVo? = null
 
+    private var inUsePointIds: List<Long> = mutableListOf()
+    var inUseRfidIds: List<Long> = mutableListOf()
+
     /**
      * 删除选中RFID标签
      */
@@ -114,4 +119,17 @@ class RfidTokenManageViewModel @Inject constructor(
             }
         }
     }
+
+    /**
+     * 获取使用中的点位
+     */
+    fun getInUsePointData(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            inUsePointIds =
+                (jobTicketRepository.getAllInUsePointsData() + jobTicketRepository.getAllLockedPointsData()
+                    .mapNotNull { it.pointId }).distinct()
+            inUseRfidIds = hardwareRepository.getRfidIdByPointIds(inUsePointIds)
+            emit(true)
+        }
+    }
 }

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

@@ -269,7 +269,7 @@ class JobExecuteViewModel @Inject constructor(
             }
             ModbusBusinessManager.checkEquipCount(ticketId, ticketPoints.count {
                 it.groupId == groupId && (it.pointStatus == "0" || (it.pointStatus == "2" && workflowRepository.isUnlockBeforeLock(
-                    ticketData?.modeId!!
+                    ticketData?.ticketId!!
                 )))
             }, true) { keyMap, lockMap ->
                 if (lockMap.isEmpty()) {
@@ -511,9 +511,9 @@ class JobExecuteViewModel @Inject constructor(
     /**
      * 是否解锁优先
      */
-    fun isUnlockFirst(modeId: Long): LiveData<Boolean> {
+    fun isUnlockFirst(ticketId: Long): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            isUnlockFirst = workflowRepository.isUnlockBeforeLock(modeId)
+            isUnlockFirst = jobTicketRepository.isUnLockBeforeLock(ticketId)
             emit(true)
         }
     }

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

@@ -5,6 +5,7 @@ import androidx.lifecycle.liveData
 import com.grkj.data.data.DictConstants
 import com.grkj.data.model.res.CommonDictRes
 import com.grkj.data.model.vo.JobTicketManageVo
+import com.grkj.data.repository.IExceptionRepository
 import com.grkj.data.repository.IJobTicketRepository
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.business.DataBusiness
@@ -18,6 +19,7 @@ import kotlinx.coroutines.Dispatchers
 @HiltViewModel
 class JobManageViewModel @Inject constructor(
     val jobTicketRepository: IJobTicketRepository,
+    val exceptionRepository: IExceptionRepository
 ) : BaseViewModel() {
     var jobTicketStatus: List<CommonDictRes> = mutableListOf()
     var jobManageDataList: MutableList<JobTicketManageVo> = mutableListOf()
@@ -29,12 +31,25 @@ class JobManageViewModel @Inject constructor(
      */
     fun deleteSelectedJob(): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            jobTicketRepository.deleteTicketByTicketIds(jobManageDataList.filter { it.isSelected == true }
-                .map { it.ticketId })
+            val selectedTicketId = jobManageDataList.filter { it.isSelected }
+                .map { it.ticketId }
+            jobTicketRepository.deleteTicketByTicketIds(selectedTicketId)
+            exceptionRepository.deleteExceptionBySourceIds(selectedTicketId)
             emit(true)
         }
     }
 
+    /**
+     * 检查是有存在只有上锁的作业
+     */
+    fun checkOnlyLockJob(): LiveData<Boolean>{
+        return liveData(Dispatchers.IO){
+            val selectedTicketId = jobManageDataList.filter { it.isSelected }
+                .map { it.ticketId }
+            jobTicketRepository.checkOnlyLockJob(selectedTicketId)
+        }
+    }
+
     /**
      * 获取数据
      */

+ 9 - 0
app/src/main/res/layout/fragment_exception_job_manage.xml

@@ -80,6 +80,15 @@
                 android:text="@string/exception_reason"
                 android:textSize="@dimen/common_text_size" />
 
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:paddingVertical="@dimen/common_spacing"
+                android:text="@string/status"
+                android:textSize="@dimen/common_text_size" />
+
             <TextView
                 android:layout_width="0dp"
                 android:layout_height="match_parent"

+ 9 - 0
app/src/main/res/layout/item_exception_job_manage.xml

@@ -33,5 +33,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>

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

@@ -534,5 +534,18 @@
     <string name="import_success">Import success</string>
     <string name="preset_workflow_can_not_delete">Preset workflow mode can not delete</string>
     <string name="workflow_already_exists">Workflow already existss</string>
+    <string name="fingerprint_login_success">Fingerprint verification passed</string>
+    <string name="fingerprint_login_failed">Fingerprint identification failed, please try again</string>
+    <string name="face_login_success">Face verification passed</string>
+    <string name="face_login_failed">Face matching failed, please try again</string>
+    <string name="username_passowrd_login_success">Account password verification passed</string>
+    <string name="username_or_password_error">Account or password error</string>
+    <string name="username_password_not_exists">Account password does not exist</string>
+    <string name="job_card_login_success">Successful identification of work card</string>
+    <string name="job_card_login_failed">Invalid job card</string>
+    <string name="selected_point_already_in_use">Exists point in use</string>
+    <string name="point_in_use">Point in use can not edit</string>
+    <string name="selected_rfid_in_use">Exists RFID tag in use</string>
+    <string name="rfid_in_use">RFID tag is in use and cannot be modified</string>
 
 </resources>

+ 13 - 0
app/src/main/res/values-zh/strings.xml

@@ -534,5 +534,18 @@
     <string name="import_success">导入成功</string>
     <string name="preset_workflow_can_not_delete">预设流程模式无法删除</string>
     <string name="workflow_already_exists">流程模式已存在</string>
+    <string name="fingerprint_login_success">指纹验证通过</string>
+    <string name="fingerprint_login_failed">指纹识别失败,请重试</string>
+    <string name="face_login_success">人脸验证通过</string>
+    <string name="face_login_failed">人脸匹配失败,请重试</string>
+    <string name="username_passowrd_login_success">账号密码验证通过</string>
+    <string name="username_or_password_error">账号或密码错误</string>
+    <string name="username_password_not_exists">账号密码不存在</string>
+    <string name="job_card_login_success">工卡识别成功</string>
+    <string name="job_card_login_failed">工卡无效</string>
+    <string name="selected_point_already_in_use">存在使用中的点位</string>
+    <string name="point_in_use">点位正在使用无法修改</string>
+    <string name="selected_rfid_in_use">存在正在使用的RFID标签</string>
+    <string name="rfid_in_use">RFID标签使用中,无法修改</string>
 
 </resources>

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

@@ -537,5 +537,18 @@
     <string name="import_success">导入成功</string>
     <string name="preset_workflow_can_not_delete">预设流程模式无法删除</string>
     <string name="workflow_already_exists">流程模式已存在</string>
+    <string name="fingerprint_login_success">指纹验证通过</string>
+    <string name="fingerprint_login_failed">指纹识别失败,请重试</string>
+    <string name="face_login_success">人脸验证通过</string>
+    <string name="face_login_failed">人脸匹配失败,请重试</string>
+    <string name="username_passowrd_login_success">账号密码验证通过</string>
+    <string name="username_or_password_error">账号或密码错误</string>
+    <string name="username_password_not_exists">账号密码不存在</string>
+    <string name="job_card_login_success">工卡识别成功</string>
+    <string name="job_card_login_failed">工卡无效</string>
+    <string name="selected_point_already_in_use">存在使用中的点位</string>
+    <string name="point_in_use">点位正在使用无法修改</string>
+    <string name="selected_rfid_in_use">存在正在使用的RFID标签</string>
+    <string name="rfid_in_use">RFID标签使用中,无法修改</string>
 
 </resources>

+ 18 - 0
data/src/main/java/com/grkj/data/dao/ExceptionDao.kt

@@ -52,4 +52,22 @@ interface ExceptionDao {
      */
     @Query("select exception_id from is_exception_source_standard where source_data_id = :ticketId")
     fun getExceptionIdByTicketId(ticketId: Long): Long
+
+    /**
+     * 根据异常数据源获取异常数据源数据
+     */
+    @Query("select * from is_exception_source_standard where source_data_id in (:sourceDataIds)")
+    fun getExceptionSourceDataBySourceDataIds(sourceDataIds: List<Long>): List<IsExceptionSourceStandard>
+
+    /**
+     * 根据异常id删除异常数据
+     */
+    @Query("delete from is_exception_standard where exception_id in (:exceptionIds)")
+    fun deleteExceptionByExceptionIds(exceptionIds: List<Long>)
+
+    /**
+     * 根据数据源id删除数据源
+     */
+    @Query("delete from is_exception_source_standard where source_id in (:sourceIds)")
+    fun deleteExceptionSourceDataById(sourceIds: List<Long>)
 }

+ 6 - 0
data/src/main/java/com/grkj/data/dao/IsolationPointDao.kt

@@ -123,4 +123,10 @@ interface IsolationPointDao {
     @Query("select * from is_isolation_point where rfid_id = :rfidId limit 1")
     fun getPointByRfidId(rfidId: Long): IsIsolationPoint?
 
+    /**
+     * 根据点位id获取rfidId
+     */
+    @Query("select rfid_id from is_isolation_point where point_id in (:inUsePointIds)")
+    fun getRfidIdByPointIds(inUsePointIds: List<Long>): List<Long>
+
 }

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

@@ -395,6 +395,26 @@ interface JobTicketDao {
     )
     fun getLockedPointsData(size: Int, offset: Int): List<LockedPointVo>
 
+    /**
+     * 获取所有锁定中的点位
+     */
+    @Query(
+        """
+        select ijtp.record_id,
+            ijtp.ticket_id,
+            ijtp.point_id,
+            ijt.ticket_name,
+            ijt.ticket_status,
+            iip.point_name
+        from is_job_ticket_points ijtp 
+        left join is_job_ticket ijt on ijtp.ticket_id=ijt.ticket_id
+        left join is_isolation_point iip on iip.point_id = ijtp.point_id
+        where ijtp.point_status = "1" and ijt.ticket_status in ('1','2','3','4','5','7')
+        order by ijtp.update_time desc
+    """
+    )
+    fun getAllLockedPointsData(): List<LockedPointVo>
+
     /**
      * 更新共锁人状态
      */
@@ -739,4 +759,40 @@ interface JobTicketDao {
     """
     )
     fun getTicketPointsByTicketIds(ticketIds: List<Long>): List<JobPointVo>
+    /**
+     * 判定在同一模式下 "解锁" 步骤是否排在 "上锁" 步骤之前
+     * 通过比较两者的最小 step_index
+     */
+    @Query(
+        """
+        SELECT CASE
+          -- 如果没有“解锁”步骤,直接返回 false
+          WHEN (SELECT MIN(step_index)
+                FROM is_job_ticket_step
+                WHERE ticket_id = :ticketId AND enable_unlock = 1) IS NULL
+            THEN 0
+          -- 如果没有“上锁”步骤,视为“解锁”先于“上锁”
+          WHEN (SELECT MIN(step_index)
+                FROM is_job_ticket_step
+                WHERE ticket_id = :ticketId AND enable_lock = 1) IS NULL
+            THEN 1
+          -- 两者都存在时,比较最小索引
+          WHEN (SELECT MIN(step_index)
+                FROM is_job_ticket_step
+                WHERE ticket_id = :ticketId AND enable_unlock = 1)
+             < (SELECT MIN(step_index)
+                FROM is_job_ticket_step
+                WHERE ticket_id = :ticketId AND enable_lock = 1)
+            THEN 1
+          ELSE 0
+        END
+    """
+    )
+    fun isUnLockBeforeLock(ticketId: Long): Boolean
+    @Query("""
+        select * from is_job_ticket_points ijtp
+        left join is_job_ticket ijt on ijtp.ticket_id = ijt.ticket_id
+        where ijt.ticket_status in ('1','2','3','4','7')
+    """)
+    fun getAllInUsePoints(): List<IsJobTicketPoints>
 }

+ 5 - 0
data/src/main/java/com/grkj/data/repository/IExceptionRepository.kt

@@ -37,4 +37,9 @@ interface IExceptionRepository {
      * 保存异常源数据
      */
     fun saveExceptionSourceData(exceptionSourceData: IsExceptionSourceStandard)
+
+    /**
+     * 根据异常数据源删除异常数据
+     */
+    fun deleteExceptionBySourceIds(selectedTicketId: List<Long>)
 }

+ 5 - 0
data/src/main/java/com/grkj/data/repository/IHardwareRepository.kt

@@ -370,4 +370,9 @@ interface IHardwareRepository {
      * 根据点位rfid获取点位id
      */
     fun getPointIdByPointNfc(pointRfid: String?): Long
+
+    /**
+     * 根据点位id获取rfidId
+     */
+    fun getRfidIdByPointIds(inUsePointIds: List<Long>): List<Long>
 }

+ 20 - 0
data/src/main/java/com/grkj/data/repository/IJobTicketRepository.kt

@@ -184,6 +184,16 @@ interface IJobTicketRepository {
      */
     fun getLockedPointsData(current: Int, size: Int): List<LockedPointVo>
 
+    /**
+     * 获取所有锁定中的点位
+     */
+    fun getAllLockedPointsData(): List<LockedPointVo>
+
+    /**
+     * 获取所有使用中的点位
+     */
+    fun getAllInUsePointsData(): List<Long>
+
     /**
      * 更新共锁人状态
      */
@@ -319,4 +329,14 @@ interface IJobTicketRepository {
      * 检查sop是否存在进心中的作业
      */
     fun checkSopHasJobInProgress(sopId: Long): Boolean
+
+    /**
+     * 是否优先解锁
+     */
+    fun isUnLockBeforeLock(ticketId: Long): Boolean
+
+    /**
+     * 检查是否有只有上锁的作业
+     */
+    fun checkOnlyLockJob(selectedTicketId: List<Long>): Boolean
 }

+ 1 - 1
data/src/main/java/com/grkj/data/repository/IUserRepository.kt

@@ -152,7 +152,7 @@ interface IUserRepository {
     /**
      * userId登录
      */
-    fun loginWithUserId(userId: Long?): Boolean
+    fun loginWithUserId(userId: Long?): LoginResultEnum
 
     /**
      * 根据用户名获取用户

+ 4 - 0
data/src/main/java/com/grkj/data/repository/impl/network/NetworkExceptionRepository.kt

@@ -36,4 +36,8 @@ class NetworkExceptionRepository @Inject constructor() : BaseRepository(), IExce
     override fun saveExceptionSourceData(exceptionSourceData: IsExceptionSourceStandard) {
         TODO("Not yet implemented")
     }
+
+    override fun deleteExceptionBySourceIds(selectedTicketId: List<Long>) {
+        TODO("Not yet implemented")
+    }
 }

+ 4 - 0
data/src/main/java/com/grkj/data/repository/impl/network/NetworkHardwareRepository.kt

@@ -268,6 +268,10 @@ class NetworkHardwareRepository  @Inject constructor() : BaseRepository(), IHard
         TODO("Not yet implemented")
     }
 
+    override fun getRfidIdByPointIds(inUsePointIds: List<Long>): List<Long> {
+        TODO("Not yet implemented")
+    }
+
     override fun clearCabinetSlots() {
         TODO("Not yet implemented")
     }

+ 18 - 2
data/src/main/java/com/grkj/data/repository/impl/network/NetworkJobTicketRepository.kt

@@ -27,7 +27,7 @@ import javax.inject.Singleton
  * 联网版作业票仓储
  */
 @Singleton
-class NetworkJobTicketRepository  @Inject constructor() : BaseRepository(), IJobTicketRepository{
+class NetworkJobTicketRepository @Inject constructor() : BaseRepository(), IJobTicketRepository {
     override fun createJob(
         selectedPointsData: List<JobTicketGroupDataVo<JobPointVo>>,
         selectedLockerData: List<JobTicketGroupDataVo<JobUserVo>>,
@@ -259,7 +259,23 @@ class NetworkJobTicketRepository  @Inject constructor() : BaseRepository(), IJob
         TODO("Not yet implemented")
     }
 
-    override fun checkSopHasJobInProgress(sopId: Long):Boolean {
+    override fun isUnLockBeforeLock(ticketId: Long): Boolean {
+        TODO("Not yet implemented")
+    }
+
+    override fun checkOnlyLockJob(selectedTicketId: List<Long>): Boolean {
+        TODO("Not yet implemented")
+    }
+
+    override fun getAllLockedPointsData(): List<LockedPointVo> {
+        TODO("Not yet implemented")
+    }
+
+    override fun getAllInUsePointsData(): List<Long> {
+        TODO("Not yet implemented")
+    }
+
+    override fun checkSopHasJobInProgress(sopId: Long): Boolean {
         TODO("Not yet implemented")
     }
 

+ 7 - 7
data/src/main/java/com/grkj/data/repository/impl/network/NetworkUserRepository.kt

@@ -23,27 +23,27 @@ class NetworkUserRepository @Inject constructor() : BaseRepository(), IUserRepos
     override fun loginWithAccount(
         username: String,
         password: String
-    ): Boolean {
+    ): LoginResultEnum {
         TODO("Not yet implemented")
     }
 
-    override fun loginWithCard(cardNo: String): Boolean {
+    override fun loginWithCard(cardNo: String): LoginResultEnum {
         TODO("Not yet implemented")
     }
 
-    override fun checkCard(cardNo: String): Boolean {
+    override fun checkCard(cardNo: String): LoginResultEnum {
         TODO("Not yet implemented")
     }
 
-    override suspend fun loginWithFingerprint(fingerprint: String): Boolean {
+    override suspend fun loginWithFingerprint(fingerprint: String): LoginResultEnum {
         TODO("Not yet implemented")
     }
 
-    override suspend fun checkFingerprint(fingerprint: String): Boolean {
+    override suspend fun checkFingerprint(fingerprint: String): LoginResultEnum {
         TODO("Not yet implemented")
     }
 
-    override fun loginWithFace(face: String): Boolean {
+    override fun loginWithFace(face: String): LoginResultEnum {
         TODO("Not yet implemented")
     }
 
@@ -106,7 +106,7 @@ class NetworkUserRepository @Inject constructor() : BaseRepository(), IUserRepos
         TODO("Not yet implemented")
     }
 
-    override fun loginWithUserId(userId: Long?): Boolean {
+    override fun loginWithUserId(userId: Long?): LoginResultEnum {
         TODO("Not yet implemented")
     }
 

+ 4 - 0
data/src/main/java/com/grkj/data/repository/impl/network/NetworkWorkflowRepository.kt

@@ -48,6 +48,10 @@ class NetworkWorkflowRepository @Inject constructor()  : BaseRepository(), IWork
         TODO("Not yet implemented")
     }
 
+    override fun getAllWorkflowModes(): List<WorkflowMode> {
+        TODO("Not yet implemented")
+    }
+
     override fun updateWorkflowMode(workflowMode: WorkflowMode?): Boolean {
         TODO("Not yet implemented")
     }

+ 10 - 2
data/src/main/java/com/grkj/data/repository/impl/standard/ExceptionRepository.kt

@@ -130,11 +130,11 @@ class ExceptionRepository @Inject constructor(
                         jobTicketData?.exStatus =
                             CommonDictDataEnum.JOB_TICKET_STATUS.commonDictRes.find { it.dictLabel == "异常" }?.dictValue?.toInt()
                         jobTicketData?.remark = exceptionSource.remark
-                        if (exceptionDataItem.exceptionDescription?.contains(CommonDictDataEnum.EXCEPTION_PROCESS_APPLICATION_JOB.commonDictRes.find {
+                        if (exceptionDataItem.processApplication == CommonDictDataEnum.EXCEPTION_PROCESS_APPLICATION_JOB.commonDictRes.find {
                                 it.dictLabel.contains(
                                     "结束作业"
                                 )
-                            }?.dictLabel) == true) {
+                            }?.dictLabel) {
                             jobTicketData?.ticketStatus = JobTicketStatusEnum.FINISHED.status
                         }
                         jobTicketData?.let {
@@ -167,4 +167,12 @@ class ExceptionRepository @Inject constructor(
     override fun saveExceptionSourceData(exceptionSourceData: IsExceptionSourceStandard) {
         exceptionDao.saveExceptionSourceData(exceptionSourceData)
     }
+
+    override fun deleteExceptionBySourceIds(selectedTicketId: List<Long>) {
+        val exceptionSourceStandards =
+            exceptionDao.getExceptionSourceDataBySourceDataIds(selectedTicketId)
+        exceptionDao.deleteExceptionByExceptionIds(exceptionSourceStandards.mapNotNull { it.exceptionId }
+            .distinct())
+        exceptionDao.deleteExceptionSourceDataById(exceptionSourceStandards.mapNotNull { it.sourceId })
+    }
 }

+ 4 - 0
data/src/main/java/com/grkj/data/repository/impl/standard/HardwareRepository.kt

@@ -197,6 +197,10 @@ class HardwareRepository @Inject constructor(
         callback(KeyPageRes(allKeyData.size, allKeyData.size, 0, allKeyData))
     }
 
+    override fun getRfidIdByPointIds(inUsePointIds: List<Long>): List<Long> {
+        return isolationPointDao.getRfidIdByPointIds(inUsePointIds)
+    }
+
     override fun getDictData(
         dictKey: String,
         callback: (List<CommonDictRes>) -> Unit

+ 19 - 0
data/src/main/java/com/grkj/data/repository/impl/standard/JobTicketRepository.kt

@@ -147,6 +147,11 @@ class JobTicketRepository @Inject constructor(
         return ticketId
     }
 
+    override fun getAllInUsePointsData(): List<Long> {
+        val allInUsePoints = jobTicketDao.getAllInUsePoints()
+        return allInUsePoints.mapNotNull { it.pointId }
+    }
+
     override fun getJobTicketBySopIds(sopIds: List<Long>): List<IsJobTicket> {
         return jobTicketDao.getTicketBySopIds(sopIds)
     }
@@ -249,6 +254,16 @@ class JobTicketRepository @Inject constructor(
         jobTicketDao.saveIsJobTicketStep(ticketStep)
     }
 
+    override fun checkOnlyLockJob(selectedTicketId: List<Long>): Boolean {
+        val ticketSteps = jobTicketDao.getStepsByTicketIds(selectedTicketId)
+        return ticketSteps.groupBy { it.ticketId }
+            .any { it.value.none { it.enableUnlock } && it.value.any { it.enableLock } }
+    }
+
+    override fun getAllLockedPointsData(): List<LockedPointVo> {
+        return jobTicketDao.getAllLockedPointsData()
+    }
+
     override fun checkSopHasJobInProgress(sopId: Long): Boolean {
         return jobTicketDao.checkSopHasJobInProgress(sopId) > 1
     }
@@ -1398,4 +1413,8 @@ class JobTicketRepository @Inject constructor(
         jobTicketDao.saveIsJobTicketStep(ticketStep)
         return ticketId
     }
+
+    override fun isUnLockBeforeLock(ticketId: Long): Boolean {
+        return jobTicketDao.isUnLockBeforeLock(ticketId)
+    }
 }

+ 4 - 4
data/src/main/java/com/grkj/data/repository/impl/standard/UserRepository.kt

@@ -391,7 +391,7 @@ class UserRepository @Inject constructor(
         return userDao.getFaceData()
     }
 
-    override fun loginWithUserId(userId: Long?): Boolean {
+    override fun loginWithUserId(userId: Long?): LoginResultEnum {
         return if (userId != null) {
             val sysUserDo = userDao.getUserInfoByUserId(userId.toString())
             if (sysUserDo != null) {
@@ -407,12 +407,12 @@ class UserRepository @Inject constructor(
                 logger.info("用户信息:{}", MainDomainData.userInfo.toString())
                 logger.info("用户角色:{}", MainDomainData.roleKeys)
                 logger.info("用户权限:{}", MainDomainData.permissions)
-                true
+                LoginResultEnum.FACE_VERIFY_SUCCESS
             } else {
-                false
+                LoginResultEnum.FACE_VERIFY_FAILED
             }
         } else {
-            false
+            LoginResultEnum.FACE_VERIFY_FAILED
         }
     }
 }

+ 3 - 3
data/src/main/java/com/grkj/data/repository/impl/standard/WorkflowRepository.kt

@@ -48,9 +48,9 @@ class WorkflowRepository @Inject constructor(val workflowStepDao: WorkflowStepDa
     override fun getNextStepIndex(modeId: Long): Int = workflowStepDao.getNextStepIndex(modeId)
 
     override fun getStepById(id: Long): WorkflowStep? = workflowStepDao.getStepById(id)
-
-    override fun isUnlockBeforeLock(modeId: Long): Boolean =
-        workflowStepDao.isUnlockBeforeLock(modeId)
+    override fun isUnlockBeforeLock(modeId: Long): Boolean {
+        return workflowStepDao.isUnlockBeforeLock(modeId)
+    }
 
     override fun getWorkflowModes(): List<WorkflowMode> = workflowStepDao.getWorkflowModes()
     override fun getAllWorkflowModes(): List<WorkflowMode> = workflowStepDao.getAllWorkflowModes()

+ 10 - 6
ui-base/src/main/java/com/grkj/ui_base/base/BaseViewModel.kt

@@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.liveData
 import androidx.lifecycle.viewModelScope
+import com.grkj.data.enums.LoginResultEnum
 import com.grkj.data.repository.IUserRepository
 import com.grkj.ui_base.utils.event.LoadingEvent
 import com.grkj.ui_base.utils.event.UiEvent
@@ -42,27 +43,30 @@ open class BaseViewModel constructor(
     /**
      * 检查人脸
      */
-    fun checkFace(faceB64: String): LiveData<Boolean> {
+    fun checkFace(faceB64: String): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
-            emit(userRepository?.checkFace(faceB64) == true)
+            emit(userRepository?.checkFace(faceB64) ?: LoginResultEnum.FACE_VERIFY_FAILED)
         }
     }
 
     /**
      * 检查指纹
      */
-    fun checkFinger(fingerB64: String): LiveData<Boolean> {
+    fun checkFinger(fingerB64: String): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
-            emit(userRepository?.checkFingerprint(fingerB64) == true)
+            emit(
+                userRepository?.checkFingerprint(fingerB64)
+                    ?: LoginResultEnum.FINGERPRINTER_VERIFY_FAILED
+            )
         }
     }
 
     /**
      * 检查卡片
      */
-    fun checkCard(cardNo: String): LiveData<Boolean> {
+    fun checkCard(cardNo: String): LiveData<LoginResultEnum> {
         return liveData(Dispatchers.IO) {
-            emit(userRepository?.checkCard(cardNo) == true)
+            emit(userRepository?.checkCard(cardNo) ?: LoginResultEnum.JOB_CARD_LOGIN_FAILED)
         }
     }