Browse Source

refactor(更新)
- 创建sop作业完成

周文健 5 months ago
parent
commit
36cee53436
33 changed files with 1571 additions and 65 deletions
  1. BIN
      app/src/main/assets/data.db
  2. 1 1
      app/src/main/java/com/grkj/iscs/features/main/dialog/data_manage/AddPointDialog.kt
  3. 1 2
      app/src/main/java/com/grkj/iscs/features/main/dialog/data_manage/FilterPointDialog.kt
  4. 0 48
      app/src/main/java/com/grkj/iscs/features/main/enums/LockModeEnum.kt
  5. 1 2
      app/src/main/java/com/grkj/iscs/features/main/fragment/common/SelectMemberFragment.kt
  6. 6 3
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/CreateSopFragment.kt
  7. 371 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/CreateSopJobFragment.kt
  8. 1 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobManageHomeFragment.kt
  9. 89 0
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/CreateSopJobViewModel.kt
  10. 26 0
      app/src/main/java/com/grkj/iscs/utils/LockModeExtension.kt
  11. 413 0
      app/src/main/res/layout/fragment_create_sop_job.xml
  12. 11 0
      app/src/main/res/navigation/nav_job_manage.xml
  13. 10 0
      app/src/main/res/values-en/strings.xml
  14. 10 0
      app/src/main/res/values-zh/strings.xml
  15. 10 0
      app/src/main/res/values/strings.xml
  16. 70 0
      data/src/main/java/com/grkj/data/dao/IsSopDao.kt
  17. 58 0
      data/src/main/java/com/grkj/data/dao/JobTicketDao.kt
  18. 13 2
      data/src/main/java/com/grkj/data/database/ISCSDatabase.kt
  19. 1 1
      data/src/main/java/com/grkj/data/enums/IsolationPointPowerType.kt
  20. 25 0
      data/src/main/java/com/grkj/data/enums/LockModeEnum.kt
  21. 1 1
      data/src/main/java/com/grkj/data/enums/LockStepEnum.kt
  22. 1 1
      data/src/main/java/com/grkj/data/enums/RoleEnums.kt
  23. 57 0
      data/src/main/java/com/grkj/data/model/dos/IsJobTicket.kt
  24. 44 0
      data/src/main/java/com/grkj/data/model/dos/IsJobTicketKey.kt
  25. 38 0
      data/src/main/java/com/grkj/data/model/dos/IsJobTicketLock.kt
  26. 59 0
      data/src/main/java/com/grkj/data/model/dos/IsJobTicketPoints.kt
  27. 38 0
      data/src/main/java/com/grkj/data/model/dos/IsJobTicketStep.kt
  28. 38 0
      data/src/main/java/com/grkj/data/model/dos/IsJobTicketUser.kt
  29. 18 0
      data/src/main/java/com/grkj/data/model/vo/SopManageVo.kt
  30. 21 0
      data/src/main/java/com/grkj/data/repository/IJobTicketRepository.kt
  31. 16 0
      data/src/main/java/com/grkj/data/repository/ISopRepository.kt
  32. 97 0
      data/src/main/java/com/grkj/data/repository/impl/JobTicketRepository.kt
  33. 26 3
      data/src/main/java/com/grkj/data/repository/impl/SopRepository.kt

BIN
app/src/main/assets/data.db


+ 1 - 1
app/src/main/java/com/grkj/iscs/features/main/dialog/data_manage/AddPointDialog.kt

@@ -6,7 +6,7 @@ import com.grkj.data.model.vo.AddPointManageVo
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.DialogFilterPointBinding
 import com.grkj.iscs.features.main.dialog.TextDropDownDialog
-import com.grkj.iscs.features.main.enums.IsolationPointPowerType
+import com.grkj.data.enums.IsolationPointPowerType
 import com.grkj.ui_base.utils.extension.tipDialog
 import com.kongzue.dialogx.dialogs.PopTip
 import razerdp.basepopup.BasePopupWindow

+ 1 - 2
app/src/main/java/com/grkj/iscs/features/main/dialog/data_manage/FilterPointDialog.kt

@@ -3,11 +3,10 @@ package com.grkj.iscs.features.main.dialog.data_manage
 import android.content.Context
 import android.view.View
 import com.grkj.data.model.vo.PointManageFilterVo
-import com.grkj.data.model.vo.RoleManageFilterVo
 import com.grkj.iscs.R
 import com.grkj.iscs.databinding.DialogFilterPointBinding
 import com.grkj.iscs.features.main.dialog.TextDropDownDialog
-import com.grkj.iscs.features.main.enums.IsolationPointPowerType
+import com.grkj.data.enums.IsolationPointPowerType
 import razerdp.basepopup.BasePopupWindow
 
 /**

+ 0 - 48
app/src/main/java/com/grkj/iscs/features/main/enums/LockModeEnum.kt

@@ -1,48 +0,0 @@
-package com.grkj.iscs.features.main.enums
-
-import com.grkj.iscs.R
-import com.grkj.ui_base.utils.CommonUtils
-
-/**
- * 锁定模式
- */
-enum class LockModeEnum(val lockMode: List<LockStepEnum>, val description: String) {
-    LOCK_MODE_1(
-        listOf(
-            LockStepEnum.SELECT_MEMBER,
-            LockStepEnum.LOCK,
-            LockStepEnum.COLOCK,
-            LockStepEnum.UNLOCK
-        ), "上锁->共锁->解锁"
-    ),
-    LOCK_MODE_2(
-        listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.LOCK, LockStepEnum.UNLOCK),
-        "上锁->解锁"
-    ),
-    LOCK_MODE_3(
-        listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.UNLOCK, LockStepEnum.LOCK),
-        "解锁->上锁"
-    ),
-    LOCK_MODE_4(listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.LOCK), "上锁"),
-    LOCK_MODE_5(listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.UNLOCK), "解锁");
-}
-
-/**
- * 获取锁定模式字符串
- */
-fun LockModeEnum.getLockModeStr(): String {
-    return when (this) {
-        LockModeEnum.LOCK_MODE_1 -> CommonUtils.getStr(R.string.lock_mode_1).toString()
-        LockModeEnum.LOCK_MODE_2 -> CommonUtils.getStr(R.string.lock_mode_2).toString()
-        LockModeEnum.LOCK_MODE_3 -> CommonUtils.getStr(R.string.lock_mode_3).toString()
-        LockModeEnum.LOCK_MODE_4 -> CommonUtils.getStr(R.string.lock_mode_4).toString()
-        LockModeEnum.LOCK_MODE_5 -> CommonUtils.getStr(R.string.lock_mode_5).toString()
-    }
-}
-
-/**
- * 获取锁定模式类型
- */
-fun LockModeEnum.getLockModeType(): String {
-    return this.lockMode.map { it.type }.joinToString(",")
-}

+ 1 - 2
app/src/main/java/com/grkj/iscs/features/main/fragment/common/SelectMemberFragment.kt

@@ -7,14 +7,13 @@ 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.grkj.data.model.vo.PointManageVo
 import com.grkj.data.model.vo.UserManageVo
 import com.grkj.iscs.R
 import com.grkj.iscs.common.DataTransferConstants
 import com.grkj.iscs.databinding.FragmentSelectMemeberBinding
 import com.grkj.iscs.databinding.ItemSelectAllMemberBinding
 import com.grkj.iscs.databinding.ItemSelectMemberBinding
-import com.grkj.iscs.features.main.enums.RoleEnums
+import com.grkj.data.enums.RoleEnums
 import com.grkj.iscs.features.main.viewmodel.common.SelectMemberViewModel
 import com.grkj.ui_base.base.BaseFragment
 import com.grkj.ui_base.utils.CommonUtils

+ 6 - 3
app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/CreateSopFragment.kt

@@ -16,10 +16,10 @@ import com.grkj.iscs.databinding.FragmentCreateSopBinding
 import com.grkj.iscs.databinding.ItemSelectMemberBinding
 import com.grkj.iscs.databinding.ItemSelectPointBinding
 import com.grkj.iscs.features.main.dialog.TextDropDownDialog
-import com.grkj.iscs.features.main.enums.LockModeEnum
-import com.grkj.iscs.features.main.enums.getLockModeStr
-import com.grkj.iscs.features.main.enums.getLockModeType
+import com.grkj.data.enums.LockModeEnum
 import com.grkj.iscs.features.main.viewmodel.job_manage.CreateSopViewModel
+import com.grkj.iscs.utils.getLockModeStr
+import com.grkj.iscs.utils.getLockModeType
 import com.grkj.ui_base.base.BaseFragment
 import com.grkj.ui_base.dialog.TipDialog
 import com.grkj.ui_base.utils.CommonUtils
@@ -230,6 +230,9 @@ class CreateSopFragment : BaseFragment<FragmentCreateSopBinding>() {
                     countDownTime = 10,
                     onConfirmClick = {
                         clearData()
+                    },
+                    onCancelClick = {
+                        clearData()
                     }
                 )
             } else {

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

@@ -0,0 +1,371 @@
+package com.grkj.iscs.features.main.fragment.job_manage
+
+import android.widget.LinearLayout
+import androidx.core.view.isVisible
+import androidx.lifecycle.ViewModelProvider
+import com.drake.brv.BindingAdapter
+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.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.UserManageVo
+import com.grkj.iscs.R
+import com.grkj.iscs.common.DataTransferConstants
+import com.grkj.iscs.databinding.FragmentCreateSopJobBinding
+import com.grkj.iscs.databinding.ItemSelectMemberBinding
+import com.grkj.iscs.databinding.ItemSelectPointBinding
+import com.grkj.iscs.features.main.dialog.TextDropDownDialog
+import com.grkj.iscs.features.main.viewmodel.job_manage.CreateSopJobViewModel
+import com.grkj.ui_base.base.BaseFragment
+import com.grkj.ui_base.dialog.TipDialog
+import com.grkj.ui_base.utils.CommonUtils
+import com.kongzue.dialogx.dialogs.PopTip
+import com.sik.sikcore.data.GlobalDataTempStore
+import com.sik.sikcore.extension.setDebouncedClickListener
+
+/**
+ * 新建SOP作业
+ */
+class CreateSopJobFragment : BaseFragment<FragmentCreateSopJobBinding>() {
+    private val viewModel: CreateSopJobViewModel by lazy { ViewModelProvider(this)[CreateSopJobViewModel::class] }
+    private var selectedWorkstationId: Long? = null
+    private var selectedSopId: Long? = null
+    private var selectedPointData: List<PointManageVo> = mutableListOf()
+    private var selectedLockerData: List<UserManageVo> = mutableListOf()
+    private var selectedColockerData: List<UserManageVo> = mutableListOf()
+    private lateinit var textDropDownDialog: TextDropDownDialog
+    override fun getLayoutId(): Int {
+        return R.layout.fragment_create_sop_job
+    }
+
+    override fun initView() {
+        textDropDownDialog = TextDropDownDialog(requireContext())
+        textDropDownDialog.setWidthAsAnchorView(true)
+        binding.back.setDebouncedClickListener {
+            TipDialog.show(
+                title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_hint).toString(),
+                msg = CommonUtils.getStr(R.string.not_save_tip).toString(),
+                dialogType = TipDialog.DialogType.ERROR,
+                countDownTime = 10,
+                onConfirmClick = {
+                    navController.popBackStack()
+                })
+        }
+        binding.cancel.setDebouncedClickListener {
+            TipDialog.show(
+                title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_hint).toString(),
+                msg = CommonUtils.getStr(R.string.not_save_tip).toString(),
+                dialogType = TipDialog.DialogType.ERROR,
+                countDownTime = 10,
+                onConfirmClick = {
+                    navController.popBackStack()
+                })
+        }
+        binding.confirm.setDebouncedClickListener {
+            if (checkData()) {
+                TipDialog.show(
+                    title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_confirm).toString(),
+                    msg = CommonUtils.getStr(
+                        R.string.create_sop_job_tip,
+                        args = listOf<String>(binding.jobNameEt.text.toString()).toTypedArray()
+                    ).toString(),
+                    dialogType = TipDialog.DialogType.INFO,
+                    countDownTime = 10,
+                    onConfirmClick = {
+                        saveSopJob()
+                    })
+            }
+        }
+        binding.workstationTv.setOnClickListener {
+            setWorkstationData()
+        }
+        binding.sopTv.setDebouncedClickListener {
+            if (selectedWorkstationId == null) {
+                PopTip.tip(R.string.please_select_sop_workstation)
+                return@setDebouncedClickListener
+            } else {
+                viewModel.getSopByWorkstation(selectedWorkstationId!!).observe(this) {
+                    setSopData()
+                }
+            }
+        }
+        binding.noSelectedPointLayout.setDebouncedClickListener {
+            if (selectedWorkstationId == null) {
+                PopTip.tip(R.string.please_select_sop_workstation)
+                return@setDebouncedClickListener
+            }
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_SELECT_POINT_WORKSTATION_ID,
+                    selectedWorkstationId!!
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(DataTransferConstants.KEY_SELECTED_POINT_DATA, selectedPointData)
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_PREVIEW_STEP_TITLE_DATA,
+                    CommonUtils.getStr(R.string.create_sop_title).toString()
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_PREVIEW_STEP_ICON_DATA,
+                    R.mipmap.icon_data_manage_menu_point_manage
+                )
+            navController.navigate(R.id.action_createSopFragment_to_selectPointFragment)
+        }
+        binding.noSelectedMemberLayout.setDebouncedClickListener {
+            if (selectedWorkstationId == null) {
+                PopTip.tip(R.string.please_select_sop_workstation)
+                return@setDebouncedClickListener
+            }
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_SELECT_POINT_WORKSTATION_ID,
+                    selectedWorkstationId!!
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(DataTransferConstants.KEY_SELECTED_MEMBER_LOCKER_DATA, selectedLockerData)
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_SELECTED_MEMBER_COLOCKER_DATA,
+                    selectedColockerData
+                )
+            GlobalDataTempStore.getInstance().saveData(
+                DataTransferConstants.KEY_SELECTED_MEMBER_COLOCKER_DATA,
+                selectedColockerData
+            )
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_PREVIEW_STEP_TITLE_DATA,
+                    CommonUtils.getStr(R.string.create_sop_title).toString()
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_PREVIEW_STEP_ICON_DATA,
+                    R.mipmap.icon_data_manage_menu_point_manage
+                )
+            navController.navigate(R.id.action_createSopFragment_to_selectMemberFragment)
+        }
+        binding.selectMemberTv.setDebouncedClickListener {
+            if (selectedWorkstationId == null) {
+                PopTip.tip(R.string.please_select_sop_workstation)
+                return@setDebouncedClickListener
+            }
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_SELECT_POINT_WORKSTATION_ID,
+                    selectedWorkstationId!!
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(DataTransferConstants.KEY_SELECTED_MEMBER_LOCKER_DATA, selectedLockerData)
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_SELECTED_MEMBER_COLOCKER_DATA,
+                    selectedColockerData
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_PREVIEW_STEP_TITLE_DATA,
+                    CommonUtils.getStr(R.string.create_sop_title).toString()
+                )
+            GlobalDataTempStore.getInstance()
+                .saveData(
+                    DataTransferConstants.KEY_PREVIEW_STEP_ICON_DATA,
+                    R.mipmap.icon_data_manage_menu_point_manage
+                )
+            navController.navigate(R.id.action_createSopFragment_to_selectMemberFragment)
+        }
+        binding.pointRv.grid(6).setup {
+            addType<PointManageVo>(R.layout.item_select_point)
+            onBind {
+                onSelectedPointRVBinding(this)
+            }
+        }
+        binding.colockerRv.linear(orientation = LinearLayout.HORIZONTAL).setup {
+            addType<UserManageVo>(R.layout.item_select_member)
+            onBind {
+                onSelectedMemberRVBinding(this)
+            }
+        }
+    }
+
+    /**
+     * 保存sop
+     */
+    private fun saveSopJob() {
+        viewModel.createSopJob(
+            selectedPointData,
+            selectedLockerData,
+            selectedColockerData,
+            selectedSopId,
+            selectedWorkstationId!!,
+            binding.jobNameEt.text.toString()
+        ).observe(this) {
+            if (it) {
+                TipDialog.show(
+                    title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_succeed).toString(),
+                    msg = CommonUtils.getStr(R.string.sop_job_create_succeed).toString(),
+                    dialogType = TipDialog.DialogType.SUCCESS,
+                    countDownTime = 10,
+                    onConfirmClick = {
+                        clearData()
+                    },
+                    onCancelClick = {
+                        clearData()
+                    }
+                )
+            } else {
+                TipDialog.show(
+                    title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_failed).toString(),
+                    msg = CommonUtils.getStr(R.string.sop_job_create_failed).toString(),
+                    dialogType = TipDialog.DialogType.ERROR,
+                    showConfirm = false,
+                    countDownTime = 10
+                )
+            }
+        }
+    }
+
+    private fun clearData() {
+        binding.jobNameEt.setText("")
+        selectedLockerData = listOf()
+        selectedColockerData = listOf()
+        selectedPointData = listOf()
+        selectedSopId = null
+        selectedWorkstationId = null
+        binding.sopTv.text = ""
+        binding.workstationTv.text = ""
+        binding.noSelectedMemberLayout.isVisible = true
+        binding.noSelectedPointLayout.isVisible = true
+    }
+
+    /**
+     * 检查数据
+     */
+    private fun checkData(): Boolean {
+        if (selectedWorkstationId == null) {
+            PopTip.tip(R.string.please_select_sop_workstation)
+            return false
+        }
+        if (selectedSopId == null) {
+            PopTip.tip(R.string.please_select_sop)
+            return false
+        }
+        if (binding.jobNameEt.text.isEmpty()) {
+            PopTip.tip(R.string.please_input_job_name)
+            return false
+        }
+        if (selectedLockerData.isEmpty()) {
+            PopTip.tip(com.grkj.ui_base.R.string.select_locker)
+            return false
+        }
+        if (selectedColockerData.isEmpty()) {
+            PopTip.tip(com.grkj.ui_base.R.string.select_coloker)
+            return false
+        }
+        return true
+    }
+
+    private fun BindingAdapter.BindingViewHolder.onSelectedMemberRVBinding(holder: BindingAdapter.BindingViewHolder) {
+        val itemBinding = holder.getBinding<ItemSelectMemberBinding>()
+        val item = holder.getModel<UserManageVo>()
+        itemBinding.lockerName.text = item.nickName
+        itemBinding.lockerIcon.isSelected = true
+    }
+
+    private fun BindingAdapter.BindingViewHolder.onSelectedPointRVBinding(holder: BindingAdapter.BindingViewHolder) {
+        val itemBinding = holder.getBinding<ItemSelectPointBinding>()
+        val item = holder.getModel<PointManageVo>()
+        itemBinding.pointName.text = item.pointName.toString()
+        itemBinding.pointIcon.setImageResource(R.mipmap.icon_data_manage_menu_point_manage)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        if (GlobalDataTempStore.getInstance()
+                .hasData(DataTransferConstants.KEY_SELECTED_MEMBER_LOCKER_DATA)
+        ) {
+            selectedLockerData = GlobalDataTempStore.getInstance()
+                .getData(DataTransferConstants.KEY_SELECTED_MEMBER_LOCKER_DATA)
+                ?.let { return@let it as List<UserManageVo> } ?: listOf()
+        }
+
+        if (GlobalDataTempStore.getInstance()
+                .hasData(DataTransferConstants.KEY_SELECTED_MEMBER_COLOCKER_DATA)
+        ) {
+            selectedColockerData = GlobalDataTempStore.getInstance()
+                .getData(DataTransferConstants.KEY_SELECTED_MEMBER_COLOCKER_DATA)
+                ?.let { return@let it as List<UserManageVo> } ?: listOf()
+        }
+        binding.noSelectedMemberLayout.isVisible =
+            selectedColockerData.isEmpty() && selectedLockerData.isEmpty()
+        binding.noSelectedPointLayout.isVisible = selectedPointData.isEmpty()
+        if (selectedColockerData.isNotEmpty()) {
+            binding.colockerRv.models = selectedColockerData
+        }
+        if (selectedLockerData.isNotEmpty()) {
+            val userData = selectedLockerData.first()
+            binding.lockerName.text = userData.nickName
+        }
+        if (selectedPointData.isNotEmpty()) {
+            binding.pointRv.models = selectedPointData
+        }
+    }
+
+    /**
+     * 设置sop区域
+     */
+    private fun setWorkstationData() {
+        viewModel.getWorkstationData().observe(this) {
+            textDropDownDialog.setData(
+                viewModel.workstationData.map {
+                    TextDropDownDialog.SimpleTextDropDownEntity(
+                        dataId = it.workstationId,
+                        dataText = it.workstationName
+                    )
+                })
+            textDropDownDialog.setOnItemSelectListener {
+                binding.workstationTv.text = it.getShowText()
+                selectedWorkstationId = it.getId()
+            }
+            textDropDownDialog.showPopupWindow(binding.workstationTv)
+        }
+    }
+
+    /**
+     * 设置sop数据
+     */
+    private fun setSopData() {
+        textDropDownDialog.setData(
+            viewModel.sopData.map {
+                TextDropDownDialog.SimpleTextDropDownEntity(
+                    dataId = it.sopId,
+                    dataText = it.sopName ?: ""
+                )
+            })
+        textDropDownDialog.setOnItemSelectListener {
+            binding.sopTv.text = it.getShowText()
+            selectedSopId = it.getId()
+            loadSopData(it.getId())
+        }
+        textDropDownDialog.showPopupWindow(binding.sopTv)
+    }
+
+    /**
+     * 加载sop数据
+     */
+    private fun loadSopData(sopId: Long) {
+        viewModel.loadSopData(sopId).observe(this) {
+            selectedColockerData = viewModel.sopColockerData
+            selectedLockerData = viewModel.sopLockerData
+            selectedPointData = viewModel.sopPoints
+            binding.pointRv.models = selectedPointData
+            binding.lockerName.text = selectedLockerData.first().nickName
+            binding.colockerRv.models = selectedColockerData
+            binding.noSelectedMemberLayout.isVisible =
+                selectedColockerData.isEmpty() && selectedLockerData.isEmpty()
+            binding.noSelectedPointLayout.isVisible = selectedPointData.isEmpty()
+        }
+    }
+}

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

@@ -137,7 +137,7 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
             }
 
             6 -> {
-
+                navController.navigate(R.id.action_jobManageHomeFragment_to_createSopJobFragment)
             }
 
             7 -> {

+ 89 - 0
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/CreateSopJobViewModel.kt

@@ -0,0 +1,89 @@
+package com.grkj.iscs.features.main.viewmodel.job_manage
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.liveData
+import com.grkj.data.model.dos.IsWorkstation
+import com.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.SopManageVo
+import com.grkj.data.model.vo.UserManageVo
+import com.grkj.data.repository.ISopRepository
+import com.grkj.data.repository.IWorkstationRepository
+import com.grkj.data.repository.impl.SopRepository
+import com.grkj.data.repository.impl.WorkstationRepository
+import com.grkj.data.enums.RoleEnums
+import com.grkj.data.repository.IJobTicketRepository
+import com.grkj.data.repository.impl.JobTicketRepository
+import com.grkj.ui_base.base.BaseViewModel
+import kotlinx.coroutines.Dispatchers
+
+/**
+ * 新建sop界面模型
+ */
+class CreateSopJobViewModel : BaseViewModel() {
+    private val workstationRepository: IWorkstationRepository by lazy { WorkstationRepository.instance }
+    private val sopRepository: ISopRepository by lazy { SopRepository.instance }
+    private val jobTicketRepository: IJobTicketRepository by lazy { JobTicketRepository.instance }
+    var workstationData: List<IsWorkstation> = listOf()
+    var sopData: List<SopManageVo> = listOf()
+    var sopPoints: List<PointManageVo> = listOf()
+    var sopLockerData: List<UserManageVo> = listOf()
+    var sopColockerData: List<UserManageVo> = listOf()
+
+    /**
+     * 初始化岗位数据
+     */
+    fun getWorkstationData(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            workstationData = workstationRepository.getWorkStationData()
+            emit(true)
+        }
+    }
+
+    /**
+     * 根据岗位id获取SOP
+     */
+    fun getSopByWorkstation(workstationId: Long): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            sopData = sopRepository.getSopDataByWorkstationId(workstationId)
+            emit(true)
+        }
+    }
+
+    /**
+     * 加载sop数据
+     */
+    fun loadSopData(sopId: Long): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            val tempSopUsers = sopRepository.getSopUsersBySopId(sopId)
+            sopLockerData = tempSopUsers.filter { it.roleKeys.contains(RoleEnums.JTLOCKER.roleKey) }
+            sopColockerData =
+                tempSopUsers.filter { it.roleKeys.contains(RoleEnums.JTCOLOCKER.roleKey) }
+            sopPoints = sopRepository.getSopPointsBySopId(sopId)
+            emit(true)
+        }
+    }
+
+    /**
+     * 创建sop作业
+     */
+    fun createSopJob(
+        selectedSopPoints: List<PointManageVo>,
+        selectedLockerData: List<UserManageVo>,
+        selectedColockerData: List<UserManageVo>,
+        sopId: Long?,
+        workstationId: Long,
+        jobName: String
+    ): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            jobTicketRepository.createSopJob(
+                selectedSopPoints,
+                selectedLockerData,
+                selectedColockerData,
+                sopId,
+                workstationId,
+                jobName
+            )
+            emit(true)
+        }
+    }
+}

+ 26 - 0
app/src/main/java/com/grkj/iscs/utils/LockModeExtension.kt

@@ -0,0 +1,26 @@
+package com.grkj.iscs.utils
+
+import com.grkj.data.enums.LockModeEnum
+import com.grkj.iscs.R
+import com.grkj.ui_base.utils.CommonUtils
+
+
+/**
+ * 获取锁定模式字符串
+ */
+fun LockModeEnum.getLockModeStr(): String {
+    return when (this) {
+        LockModeEnum.LOCK_MODE_1 -> CommonUtils.getStr(R.string.lock_mode_1).toString()
+        LockModeEnum.LOCK_MODE_2 -> CommonUtils.getStr(R.string.lock_mode_2).toString()
+        LockModeEnum.LOCK_MODE_3 -> CommonUtils.getStr(R.string.lock_mode_3).toString()
+        LockModeEnum.LOCK_MODE_4 -> CommonUtils.getStr(R.string.lock_mode_4).toString()
+        LockModeEnum.LOCK_MODE_5 -> CommonUtils.getStr(R.string.lock_mode_5).toString()
+    }
+}
+
+/**
+ * 获取锁定模式类型
+ */
+fun LockModeEnum.getLockModeType(): String {
+    return this.lockMode.map { it.type }.joinToString(",")
+}

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

@@ -0,0 +1,413 @@
+<?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="20dp"
+        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="10dp"
+            android:paddingVertical="5dp">
+
+            <ImageView
+                android:layout_width="20dp"
+                android:layout_height="20dp"
+                android:src="@mipmap/icon_data_manage_menu_user_manage" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:layout_weight="1"
+                android:text="@string/create_sop_job_title"
+                android:textColor="@color/black"
+                android:textSize="24sp" />
+
+            <TextView
+                android:id="@+id/back"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:background="@drawable/common_dialog_btn"
+                android:paddingHorizontal="20dp"
+                android:text="@string/back"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+        </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:background="@color/black" />
+
+        <LinearLayout
+            android:id="@+id/base_info_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="20dp"
+            android:layout_marginTop="20dp"
+            android:layout_marginBottom="10dp"
+            android:background="@drawable/home_card_bg"
+            android:gravity="center_vertical"
+            android:orientation="vertical">
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:layout_weight="1"
+                android:text="@string/base_info_title"
+                android:textColor="@color/black"
+                android:textSize="24sp" />
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:background="@color/black" />
+
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:gravity="center_vertical"
+                android:orientation="horizontal"
+                android:paddingHorizontal="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/sop_workstation"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+
+                <TextView
+                    android:id="@+id/workstation_tv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:background="@drawable/bg_common_input"
+                    android:drawableRight="@drawable/icon_drop_down"
+                    android:hint="@string/please_select_sop_workstation"
+                    android:maxLines="1"
+                    android:paddingHorizontal="10dp"
+                    android:paddingVertical="2dp"
+                    android:singleLine="true"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:layout_marginLeft="36dp"
+                android:gravity="center_vertical"
+                android:orientation="horizontal"
+                android:paddingHorizontal="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/create_sop_job_sop"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+
+                <TextView
+                    android:id="@+id/sop_tv"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:background="@drawable/bg_common_input"
+                    android:drawableRight="@drawable/icon_drop_down"
+                    android:hint="@string/please_select_sop"
+                    android:maxLines="1"
+                    android:paddingHorizontal="10dp"
+                    android:paddingVertical="2dp"
+                    android:singleLine="true"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="20dp"
+                android:gravity="center_vertical"
+                android:orientation="horizontal"
+                android:paddingHorizontal="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/job_name"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+
+                <EditText
+                    android:id="@+id/job_name_et"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:background="@drawable/bg_common_input"
+                    android:hint="@string/please_input_job_name"
+                    android:maxLines="1"
+                    android:paddingHorizontal="10dp"
+                    android:paddingVertical="2dp"
+                    android:singleLine="true"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+            </LinearLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/point_info_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="20dp"
+            android:layout_marginVertical="10dp"
+            android:background="@drawable/home_card_bg"
+            android:gravity="center_vertical"
+            android:orientation="vertical">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_weight="1"
+                    android:text="@string/point_info_title"
+                    android:textColor="@color/black"
+                    android:textSize="24sp" />
+
+            </LinearLayout>
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:background="@color/black" />
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/point_rv"
+                    android:layout_width="match_parent"
+                    android:layout_height="240dp"
+                    android:paddingBottom="10dp" />
+
+                <LinearLayout
+                    android:id="@+id/no_selected_point_layout"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:background="@drawable/card_white_bg"
+                    android:gravity="center"
+                    android:orientation="vertical">
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity="center"
+                        android:paddingHorizontal="20dp"
+                        android:paddingVertical="10dp"
+                        android:text="@string/show_points_when_selected_sop"
+                        android:textColor="@color/black"
+                        android:textSize="20sp" />
+                </LinearLayout>
+            </FrameLayout>
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/member_info_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="20dp"
+            android:layout_marginVertical="10dp"
+            android:background="@drawable/home_card_bg"
+            android:gravity="center_vertical"
+            android:orientation="vertical">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_weight="1"
+                    android:text="@string/member_info_title"
+                    android:textColor="@color/black"
+                    android:textSize="24sp" />
+
+                <TextView
+                    android:id="@+id/select_member_tv"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginRight="10dp"
+                    android:background="@drawable/common_dialog_btn"
+                    android:paddingHorizontal="20dp"
+                    android:text="@string/select"
+                    android:textColor="@color/black"
+                    android:textSize="20sp" />
+            </LinearLayout>
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:background="@color/black" />
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:orientation="horizontal">
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:background="@drawable/home_card_bg"
+                        android:orientation="vertical">
+
+                        <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:gravity="center"
+                            android:paddingHorizontal="20dp"
+                            android:paddingVertical="10dp"
+                            android:text="@string/locker"
+                            android:textColor="@color/black"
+                            android:textSize="24sp" />
+
+                        <View
+                            android:layout_width="match_parent"
+                            android:layout_height="1dp"
+                            android:background="@color/black" />
+
+                        <LinearLayout
+                            android:layout_width="match_parent"
+                            android:layout_height="match_parent"
+                            android:gravity="center"
+                            android:orientation="vertical">
+
+                            <ImageView
+                                android:layout_width="50dp"
+                                android:layout_height="50dp"
+                                android:layout_marginTop="10dp"
+                                android:src="@mipmap/icon_data_manage_menu_user_manage"
+                                android:tint="@color/black" />
+
+                            <TextView
+                                android:id="@+id/locker_name"
+                                android:layout_width="wrap_content"
+                                android:layout_height="wrap_content"
+                                android:gravity="center"
+                                android:paddingHorizontal="20dp"
+                                android:paddingVertical="10dp"
+                                android:textColor="@color/black"
+                                android:textSize="20sp" />
+                        </LinearLayout>
+                    </LinearLayout>
+
+                    <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="match_parent"
+                        android:layout_weight="1"
+                        android:background="@drawable/home_card_bg"
+                        android:orientation="vertical">
+
+                        <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:gravity="center"
+                            android:paddingHorizontal="20dp"
+                            android:paddingVertical="10dp"
+                            android:text="@string/colocker"
+                            android:textColor="@color/black"
+                            android:textSize="24sp" />
+
+                        <View
+                            android:layout_width="match_parent"
+                            android:layout_height="1dp"
+                            android:background="@color/black" />
+
+                        <androidx.recyclerview.widget.RecyclerView
+                            android:id="@+id/colocker_rv"
+                            android:layout_width="wrap_content"
+                            android:layout_height="match_parent" />
+                    </LinearLayout>
+
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/no_selected_member_layout"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:background="@drawable/card_white_bg"
+                    android:gravity="center"
+                    android:orientation="vertical">
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity="center"
+                        android:paddingHorizontal="20dp"
+                        android:paddingVertical="10dp"
+                        android:text="@string/show_member_when_selected_sop"
+                        android:textColor="@color/black"
+                        android:textSize="20sp" />
+                </LinearLayout>
+            </FrameLayout>
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right"
+            android:orientation="horizontal"
+            android:padding="10dp">
+
+            <TextView
+                android:id="@+id/confirm"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:background="@drawable/common_dialog_btn"
+                android:paddingHorizontal="20dp"
+                android:text="@string/confirm"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/cancel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="10dp"
+                android:background="@drawable/common_dialog_btn"
+                android:paddingHorizontal="20dp"
+                android:text="@string/cancel"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+        </LinearLayout>
+    </LinearLayout>
+</layout>

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

@@ -14,6 +14,9 @@
         <action
             android:id="@+id/action_jobManageHomeFragment_to_createSopFragment"
             app:destination="@id/createSopFragment" />
+        <action
+            android:id="@+id/action_jobManageHomeFragment_to_createSopJobFragment"
+            app:destination="@id/createSopJobFragment" />
     </fragment>
     <fragment
         android:id="@+id/createJobFragment"
@@ -42,4 +45,12 @@
         android:id="@+id/selectPointFragment"
         android:name="com.grkj.iscs.features.main.fragment.common.SelectPointFragment"
         android:label="SelectPointFragment" />
+    <fragment
+        android:id="@+id/createSopJobFragment"
+        android:name="com.grkj.iscs.features.main.fragment.job_manage.CreateSopJobFragment"
+        android:label="CreateSopJobFragment">
+        <action
+            android:id="@+id/action_createSopJobFragment_to_selectMemberFragment"
+            app:destination="@id/selectMemberFragment" />
+    </fragment>
 </navigation>

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

@@ -110,4 +110,14 @@
     <string name="lock_mode_4">lock</string>
     <string name="lock_mode_5">unlock</string>
     <string name="sop_save_tip">Do you want to save "%1$s"?</string>
+    <string name="create_sop_job_title">Create SOP job</string>
+    <string name="create_sop_job_sop">SOP</string>
+    <string name="job_name">Job name</string>
+    <string name="please_select_sop">please select SOP</string>
+    <string name="please_input_job_name">please input job name</string>
+    <string name="show_points_when_selected_sop">Show SOP points when the sop has selected</string>
+    <string name="show_member_when_selected_sop">Show SOP members when the sop has selected</string>
+    <string name="create_sop_job_tip">Are you sure you want to execute the job "%1$s"?</string>
+    <string name="sop_job_create_succeed">Create SOP job succeed</string>
+    <string name="sop_job_create_failed">Create SOP job failed</string>
 </resources>

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

@@ -110,4 +110,14 @@
     <string name="lock_mode_4">上锁</string>
     <string name="lock_mode_5">解锁</string>
     <string name="sop_save_tip">确定要保存"%1$s"吗?</string>
+    <string name="create_sop_job_title">新建SOP作业</string>
+    <string name="create_sop_job_sop">SOP</string>
+    <string name="job_name">作业名称</string>
+    <string name="please_select_sop">请选择SOP</string>
+    <string name="please_input_job_name">请输入作业名称</string>
+    <string name="show_points_when_selected_sop">选择SOP后,将自动展示SOP的点位信息。</string>
+    <string name="show_member_when_selected_sop">选择SOP后,将自动展示SOP的人员信息。</string>
+    <string name="create_sop_job_tip">确定要执行作业"%1$s"吗?</string>
+    <string name="sop_job_create_succeed">SOP作业创建成功</string>
+    <string name="sop_job_create_failed">SOP作业创建失败</string>
 </resources>

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

@@ -109,4 +109,14 @@
     <string name="lock_mode_4">上锁</string>
     <string name="lock_mode_5">解锁</string>
     <string name="sop_save_tip">确定要保存"%1$s"吗?</string>
+    <string name="create_sop_job_title">新建SOP作业</string>
+    <string name="create_sop_job_sop">SOP</string>
+    <string name="job_name">作业名称</string>
+    <string name="please_select_sop">请选择SOP</string>
+    <string name="please_input_job_name">请输入作业名称</string>
+    <string name="show_points_when_selected_sop">选择SOP后,将自动展示SOP的点位信息。</string>
+    <string name="show_member_when_selected_sop">选择SOP后,将自动展示SOP的人员信息。</string>
+    <string name="create_sop_job_tip">确定要执行作业"%1$s"吗?</string>
+    <string name="sop_job_create_succeed">SOP作业创建成功</string>
+    <string name="sop_job_create_failed">SOP作业创建失败</string>
 </resources>

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

@@ -3,14 +3,21 @@ package com.grkj.data.dao
 import androidx.room.Dao
 import androidx.room.Insert
 import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.TypeConverters
+import com.grkj.data.converters.Converters
 import com.grkj.data.model.dos.IsSop
 import com.grkj.data.model.dos.IsSopPoints
 import com.grkj.data.model.dos.IsSopUser
+import com.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.SopManageVo
+import com.grkj.data.model.vo.UserManageVo
 
 /**
  * sop数据库操作
  */
 @Dao
+@TypeConverters(Converters::class)    // 注册下面要写的 Converters
 interface IsSopDao {
     /**
      * 保存sop
@@ -29,4 +36,67 @@ interface IsSopDao {
      */
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     fun saveSopUsers(isSopUsers: List<IsSopUser>)
+
+    /**
+     * 根据岗位id获取sop数据
+     */
+    @Query("select sop_id as sopId,sop_name as sopName,sop_type as sopType,lock_mode as LockMode,workstation_id as workstationId,del_flag as delFlag from is_sop where workstation_id = :workstationId")
+    fun getSopDataByWorkstationId(workstationId: Long): List<SopManageVo>
+
+    /**
+     * 根据sopId获取sop点位数据
+     */
+    @Query(
+        """
+        select iip.point_id as pointId,
+        iip.point_name as pointName,
+        iip.remark as pointFunction
+        from is_sop_points isp
+        left join is_isolation_point iip on isp.point_id = iip.point_id
+        where isp.del_flag = 0
+        and sop_id = :sopId
+    """
+    )
+    fun getSopPointsBySopId(sopId: Long): List<PointManageVo>
+
+    /**
+     * 根据sopId获取SOP用户数据
+     */
+    @Query(
+        """
+            SELECT
+              su.user_id                         AS userId,
+              su.nick_name                       AS nickName,
+              su.user_name                       AS userName,
+              -- 聚合所有卡号(如果没卡则结果里 cardCodes 会是 NULL 或空)
+              GROUP_CONCAT(DISTINCT ijc.card_code)       AS cardCodes,
+        
+              GROUP_CONCAT(DISTINCT sr.role_id)           AS roleIds,
+              GROUP_CONCAT(DISTINCT sr.role_name)         AS roleNames,
+              isu.user_role          AS roleKeys,
+              GROUP_CONCAT(DISTINCT iw.workstation_id)    AS workstationIds,
+              GROUP_CONCAT(DISTINCT iw.workstation_name)  AS workstationNames,
+        
+              su.status                            AS status
+            FROM is_sop_user isu 
+            LEFT JOIN sys_user su on su.user_id = isu.user_id
+            LEFT JOIN sys_user_role sur ON su.user_id = sur.user_id
+            LEFT JOIN sys_role sr       ON sur.role_id = sr.role_id
+            LEFT JOIN is_job_card ijc   ON ijc.user_id = su.user_id
+            LEFT JOIN is_user_workstation iuw ON iuw.user_id = su.user_id
+            LEFT JOIN is_workstation iw ON iw.workstation_id = iuw.workstation_id
+            WHERE su.del_flag = 0 and isu.sop_id = :sopId
+            GROUP BY
+              su.user_id,
+              su.nick_name,
+              su.status
+    """
+    )
+    fun getSopUsersBySopId(sopId: Long): List<UserManageVo>
+
+    /**
+     * 根据sopId获取SOP数据
+     */
+    @Query("select * from is_sop where sop_id = :sopId")
+    fun getSopDataBySopId(sopId: Long): IsSop
 }

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

@@ -0,0 +1,58 @@
+package com.grkj.data.dao
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.TypeConverter
+import androidx.room.TypeConverters
+import com.grkj.data.converters.Converters
+import com.grkj.data.model.dos.IsJobTicket
+import com.grkj.data.model.dos.IsJobTicketKey
+import com.grkj.data.model.dos.IsJobTicketLock
+import com.grkj.data.model.dos.IsJobTicketPoints
+import com.grkj.data.model.dos.IsJobTicketStep
+import com.grkj.data.model.dos.IsJobTicketUser
+
+/**
+ * 作业票数据库操作
+ */
+@Dao
+@TypeConverters(Converters::class)    // 注册下面要写的 Converters
+interface JobTicketDao {
+    /**
+     * 保存作业票
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    fun saveIsJobTicket(ticket: IsJobTicket): Long
+
+    /**
+     * 保存作业票钥匙
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    fun saveIsJobTicketKey(ticket: List<IsJobTicketKey>)
+
+    /**
+     * 保存作业票锁
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    fun saveIsJobTicketLock(ticket: List<IsJobTicketLock>)
+
+    /**
+     * 保存作业票点位
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    fun saveIsJobTicketPoints(ticket: List<IsJobTicketPoints>): List<Long>
+
+    /**
+     * 保存作业票步骤
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    fun saveIsJobTicketStep(ticket: List<IsJobTicketStep>)
+
+    /**
+     * 保存作业票用户
+     */
+    @Insert(onConflict = OnConflictStrategy.REPLACE)
+    fun saveIsJobTicketUser(ticket: List<IsJobTicketUser>)
+
+}

+ 13 - 2
data/src/main/java/com/grkj/data/database/ISCSDatabase.kt

@@ -7,12 +7,19 @@ import androidx.room.RoomDatabase
 import com.grkj.data.dao.HardwareDao
 import com.grkj.data.dao.IsSopDao
 import com.grkj.data.dao.IsolationPointDao
+import com.grkj.data.dao.JobTicketDao
 import com.grkj.data.dao.RfidTokenDao
 import com.grkj.data.dao.RoleDao
 import com.grkj.data.dao.UserDao
 import com.grkj.data.dao.WorkstationDao
 import com.grkj.data.model.dos.IsIsolationPoint
 import com.grkj.data.model.dos.IsJobCardDo
+import com.grkj.data.model.dos.IsJobTicket
+import com.grkj.data.model.dos.IsJobTicketKey
+import com.grkj.data.model.dos.IsJobTicketLock
+import com.grkj.data.model.dos.IsJobTicketPoints
+import com.grkj.data.model.dos.IsJobTicketStep
+import com.grkj.data.model.dos.IsJobTicketUser
 import com.grkj.data.model.dos.IsRfidToken
 import com.grkj.data.model.dos.IsSop
 import com.grkj.data.model.dos.IsSopPoints
@@ -29,9 +36,11 @@ import com.sik.sikcore.SIKCore
  * 本地数据库
  */
 @Database(
-    entities = [IsJobCardDo::class, SysUserDo::class, SysUserCharacteristicDo::class,
+    entities = [
+        IsJobCardDo::class, SysUserDo::class, SysUserCharacteristicDo::class,
         SysRole::class, SysUserRole::class, IsUserWorkstation::class, IsWorkstation::class, IsIsolationPoint::class, IsRfidToken::class,
-        IsSop::class, IsSopUser::class, IsSopPoints::class],
+        IsSop::class, IsSopUser::class, IsSopPoints::class, IsJobTicket::class, IsJobTicketKey::class, IsJobTicketLock::class, IsJobTicketPoints::class, IsJobTicketStep::class, IsJobTicketUser::class,
+    ],
     version = ISCSMigrations.VERSION
 )
 abstract class ISCSDatabase : RoomDatabase() {
@@ -64,4 +73,6 @@ abstract class ISCSDatabase : RoomDatabase() {
     abstract fun rfidTokenDao(): RfidTokenDao
 
     abstract fun isSopDao(): IsSopDao
+
+    abstract fun jobTicketDao(): JobTicketDao
 }

+ 1 - 1
app/src/main/java/com/grkj/iscs/features/main/enums/IsolationPointPowerType.kt → data/src/main/java/com/grkj/data/enums/IsolationPointPowerType.kt

@@ -1,4 +1,4 @@
-package com.grkj.iscs.features.main.enums
+package com.grkj.data.enums
 
 /**
  * 能量源

+ 25 - 0
data/src/main/java/com/grkj/data/enums/LockModeEnum.kt

@@ -0,0 +1,25 @@
+package com.grkj.data.enums
+
+/**
+ * 锁定模式
+ */
+enum class LockModeEnum(val lockMode: List<LockStepEnum>, val description: String) {
+    LOCK_MODE_1(
+        listOf(
+            LockStepEnum.SELECT_MEMBER,
+            LockStepEnum.LOCK,
+            LockStepEnum.COLOCK,
+            LockStepEnum.UNLOCK
+        ), "上锁->共锁->解锁"
+    ),
+    LOCK_MODE_2(
+        listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.LOCK, LockStepEnum.UNLOCK),
+        "上锁->解锁"
+    ),
+    LOCK_MODE_3(
+        listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.UNLOCK, LockStepEnum.LOCK),
+        "解锁->上锁"
+    ),
+    LOCK_MODE_4(listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.LOCK), "上锁"),
+    LOCK_MODE_5(listOf(LockStepEnum.SELECT_MEMBER, LockStepEnum.UNLOCK), "解锁");
+}

+ 1 - 1
app/src/main/java/com/grkj/iscs/features/main/enums/LockStepEnum.kt → data/src/main/java/com/grkj/data/enums/LockStepEnum.kt

@@ -1,4 +1,4 @@
-package com.grkj.iscs.features.main.enums
+package com.grkj.data.enums
 
 /**
  * 锁定步骤枚举

+ 1 - 1
app/src/main/java/com/grkj/iscs/features/main/enums/RoleEnums.kt → data/src/main/java/com/grkj/data/enums/RoleEnums.kt

@@ -1,4 +1,4 @@
-package com.grkj.iscs.features.main.enums
+package com.grkj.data.enums
 
 /**
  * 角色枚举

+ 57 - 0
data/src/main/java/com/grkj/data/model/dos/IsJobTicket.kt

@@ -0,0 +1,57 @@
+package com.grkj.data.model.dos
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import com.sik.sikcore.date.TimeUtils
+
+/**
+ * SOP
+ */
+@Entity(tableName = "is_job_ticket")
+class IsJobTicket : BaseBean() {
+    @PrimaryKey(autoGenerate = true)
+    @ColumnInfo("ticket_id")
+    var ticketId: Long = 0
+
+    @ColumnInfo("ticket_code")
+    var ticketCode: String? = null
+
+    @ColumnInfo("ticket_name")
+    var ticketName: String = ""
+
+    @ColumnInfo("workshop_id")
+    var workshopId: Long? = null
+
+    @ColumnInfo("workarea_id")
+    var workareaId: Long? = null
+
+    @ColumnInfo("workstation_id")
+    var workstationId: Long = 0
+
+    @ColumnInfo("machinery_id")
+    var machineryId: Long? = null
+
+    @ColumnInfo("sop_id")
+    var sopId: Long? = null
+
+    @ColumnInfo("ticket_type")
+    var ticketType: String? = null
+
+    @ColumnInfo("ticket_content")
+    var ticketContent: String? = null
+
+    @ColumnInfo("ticket_status")
+    var ticketStatus: String? = "0"
+
+    @ColumnInfo("ticket_start_time")
+    var ticketStartTime: String? = TimeUtils.nowString(TimeUtils.DEFAULT_DATE_HOUR_MIN_SEC_FORMAT)
+
+    @ColumnInfo("ticket_end_time")
+    var ticketEndTime: String? = null
+
+    @ColumnInfo("del_flag")
+    var delFlag: String? = "0"
+
+
+}

+ 44 - 0
data/src/main/java/com/grkj/data/model/dos/IsJobTicketKey.kt

@@ -0,0 +1,44 @@
+package com.grkj.data.model.dos
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * is_job_ticket_key
+ */
+@Entity(tableName = "is_job_ticket_key")
+class IsJobTicketKey : BaseBean() {
+    @PrimaryKey(autoGenerate = true)
+    @ColumnInfo("record_id")
+    var recordId: Long = 0
+	
+	@ColumnInfo("ticket_id")
+    var ticketId: Long = 0
+	
+	@ColumnInfo("key_id")
+    var keyId: Long? = null
+	
+	@ColumnInfo("from_hardware_id")
+    var fromHardwareId: Long? = null
+	
+	@ColumnInfo("to_hardware_id")
+    var toHardwareId: Long? = null	
+
+    @ColumnInfo("collect_time")
+    var collectTime: String? = null
+
+    @ColumnInfo("give_back_time")
+    var giveBackTime: String? = null
+	
+	@ColumnInfo("key_status")
+    var keyStatus: String? = "0"
+	
+	@ColumnInfo("ticket_type")
+    var ticketType: Long? = null
+
+    @ColumnInfo("del_flag")
+    var delFlag: String? = "0"
+	
+
+}

+ 38 - 0
data/src/main/java/com/grkj/data/model/dos/IsJobTicketLock.kt

@@ -0,0 +1,38 @@
+package com.grkj.data.model.dos
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * is_job_ticket_lock
+ */
+@Entity(tableName = "is_job_ticket_lock")
+class IsJobTicketLock : BaseBean() {
+    @PrimaryKey(autoGenerate = true)
+    @ColumnInfo("record_id")
+    var recordId: Long = 0
+	
+	@ColumnInfo("ticket_id")
+    var ticketId: Long = 0
+	
+	@ColumnInfo("lock_id")
+    var lockId: Long? = null
+	
+	@ColumnInfo("isolation_point_id")
+    var isolationPointId: Long ? = null
+	
+	@ColumnInfo("lock_status")
+    var lockStatus: String? = "0"
+	
+	@ColumnInfo("from_hardware_id")
+    var fromHardwareId: Long? = null	
+	
+	@ColumnInfo("to_hardware_id")
+    var toHardwareId: Long? = null	
+
+    @ColumnInfo("del_flag")
+    var delFlag: String? = "0"
+	
+
+}

+ 59 - 0
data/src/main/java/com/grkj/data/model/dos/IsJobTicketPoints.kt

@@ -0,0 +1,59 @@
+package com.grkj.data.model.dos
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * is_job_ticket_points
+ */
+@Entity(tableName = "is_job_ticket_points")
+class IsJobTicketPoints : BaseBean() {
+    @PrimaryKey(autoGenerate = true)
+    @ColumnInfo("record_id")
+    var recordId: Long = 0
+
+    @ColumnInfo("ticket_id")
+    var ticketId: Long = 0
+
+    @ColumnInfo("workshop_id")
+    var workshopId: Long? = null
+
+    @ColumnInfo("workarea_id")
+    var workareaId: Long? = null
+
+    @ColumnInfo("machinery_id")
+    var machineryId: Long? = null
+
+    @ColumnInfo("workstation_id")
+    var workstationId: Long = 0
+
+    @ColumnInfo("unlock_time")
+    var unlockTime: String? = null
+
+    @ColumnInfo("point_id")
+    var pointId: Long? = null
+
+    @ColumnInfo("point_status")
+    var pointStatus: String? = "0"
+
+    @ColumnInfo("lock_id")
+    var lockId: Long? = null
+
+    @ColumnInfo("locked_by_key_id")
+    var lockedByKeyId: Long? = null
+
+    @ColumnInfo("unlocked_by_key_id")
+    var unlockedByKeyId: Long? = null
+
+    @ColumnInfo("lock_time")
+    var lockTime: String? = null
+
+    @ColumnInfo("pre_point_id")
+    var prePointId: Long? = null
+
+    @ColumnInfo("del_flag")
+    var delFlag: String? = "0"
+
+
+}

+ 38 - 0
data/src/main/java/com/grkj/data/model/dos/IsJobTicketStep.kt

@@ -0,0 +1,38 @@
+package com.grkj.data.model.dos
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * is_job_ticket_step
+ */
+@Entity(tableName = "is_job_ticket_step")
+class IsJobTicketStep : BaseBean() {
+    @PrimaryKey(autoGenerate = true)
+    @ColumnInfo("step_id")
+    var stepId: Long = 0
+
+    @ColumnInfo("ticket_id")
+    var ticketId: Long = 0
+
+    @ColumnInfo("step_index")
+    var stepIndex: Int = 0
+
+    @ColumnInfo("step_status")
+    var stepStatus: String = "0"
+
+    @ColumnInfo("step_type")
+    var stepType: String? = null
+
+    @ColumnInfo("step_content")
+    var stepContent: String? = null
+
+    @ColumnInfo("android_step_content")
+    var androidStepContent: String? = null
+
+    @ColumnInfo("del_flag")
+    var delFlag: String? = "0"
+
+
+}

+ 38 - 0
data/src/main/java/com/grkj/data/model/dos/IsJobTicketUser.kt

@@ -0,0 +1,38 @@
+package com.grkj.data.model.dos
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * is_job_ticket_user
+ */
+@Entity(tableName = "is_job_ticket_user")
+class IsJobTicketUser : BaseBean() {
+    @PrimaryKey(autoGenerate = true)
+    @ColumnInfo("record_id")
+    var recordId: Long = 0
+	
+	@ColumnInfo("ticket_id")
+    var ticketId: Long = 0
+	
+	@ColumnInfo("user_id")
+    var userId: Long = 0
+	
+	@ColumnInfo("user_name")
+    var userName: String? = null
+	
+	@ColumnInfo("user_type")
+    var userType: String? = null
+	
+	@ColumnInfo("user_role")
+    var userRole: String? = null
+	
+	@ColumnInfo("job_status")
+    var jobStatus: String? = "0"
+
+    @ColumnInfo("del_flag")
+    var delFlag: String? = "0"
+	
+
+}

+ 18 - 0
data/src/main/java/com/grkj/data/model/vo/SopManageVo.kt

@@ -0,0 +1,18 @@
+package com.grkj.data.model.vo
+
+/**
+ * Sop管理数据
+ */
+class SopManageVo {
+    var sopId: Long = 0
+
+    var sopName: String? = null
+
+    var sopType: String? = null
+
+    var lockMode: String? = null
+
+    var workstationId: Long = 0
+
+    var delFlag: String? = "0"
+}

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

@@ -0,0 +1,21 @@
+package com.grkj.data.repository
+
+import com.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.UserManageVo
+
+/**
+ * 作业票仓储
+ */
+interface IJobTicketRepository {
+    /**
+     * 创建sop作业
+     */
+    fun createSopJob(
+        selectedSopPoints: List<PointManageVo>,
+        selectedLockerData: List<UserManageVo>,
+        selectedColockerData: List<UserManageVo>,
+        sopId: Long?,
+        workstationId: Long,
+        jobName: String
+    )
+}

+ 16 - 0
data/src/main/java/com/grkj/data/repository/ISopRepository.kt

@@ -1,6 +1,7 @@
 package com.grkj.data.repository
 
 import com.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.SopManageVo
 import com.grkj.data.model.vo.UserManageVo
 
 /**
@@ -25,4 +26,19 @@ interface ISopRepository {
         selectedColockerData: List<UserManageVo>,
         sopId: Long
     )
+
+    /**
+     * 根据岗位id获取sop
+     */
+    fun getSopDataByWorkstationId(workstationId: Long): List<SopManageVo>
+
+    /**
+     * 根据sopId获取sop点位
+     */
+    fun getSopPointsBySopId(sopId: Long): List<PointManageVo>
+
+    /**
+     * 根据sopId获取SOP用户
+     */
+    fun getSopUsersBySopId(sopId: Long): List<UserManageVo>
 }

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

@@ -0,0 +1,97 @@
+package com.grkj.data.repository.impl
+
+import com.grkj.data.dao.IsSopDao
+import com.grkj.data.dao.JobTicketDao
+import com.grkj.data.database.ISCSDatabase
+import com.grkj.data.enums.LockStepEnum
+import com.grkj.data.model.dos.IsJobTicket
+import com.grkj.data.model.dos.IsJobTicketKey
+import com.grkj.data.model.dos.IsJobTicketLock
+import com.grkj.data.model.dos.IsJobTicketPoints
+import com.grkj.data.model.dos.IsJobTicketStep
+import com.grkj.data.model.dos.IsJobTicketUser
+import com.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.UserManageVo
+import com.grkj.data.repository.IJobTicketRepository
+
+/**
+ * 作业票实现
+ */
+class JobTicketRepository : IJobTicketRepository {
+    private val jobTicketDao: JobTicketDao by lazy { ISCSDatabase.instance.jobTicketDao() }
+    private val sopDao: IsSopDao by lazy { ISCSDatabase.instance.isSopDao() }
+    override fun createSopJob(
+        selectedSopPoints: List<PointManageVo>,
+        selectedLockerData: List<UserManageVo>,
+        selectedColockerData: List<UserManageVo>,
+        sopId: Long?,
+        workstationId: Long,
+        jobName: String
+    ) {
+        val isJobTicket = IsJobTicket()
+        isJobTicket.ticketName = jobName
+        isJobTicket.workstationId = workstationId
+        isJobTicket.sopId = sopId
+        val ticketId = jobTicketDao.saveIsJobTicket(isJobTicket)
+        val ticketPoints = selectedSopPoints.map {
+            val isJobTicketPoint = IsJobTicketPoints()
+            isJobTicketPoint.ticketId = ticketId
+            isJobTicketPoint.pointId = it.pointId
+            isJobTicketPoint.workstationId = workstationId
+            isJobTicketPoint
+        }
+        val ticketPointIds = jobTicketDao.saveIsJobTicketPoints(ticketPoints)
+        val ticketUsers = (selectedLockerData + selectedColockerData).map {
+            val isJobticketUser = IsJobTicketUser()
+            isJobticketUser.userId = it.userId
+            isJobticketUser.ticketId = ticketId
+            isJobticketUser.userName = it.userName
+            isJobticketUser.userRole = it.roleKeys.joinToString(",")
+            isJobticketUser
+        }
+        jobTicketDao.saveIsJobTicketUser(ticketUsers)
+        val ticketKeys = mutableListOf<IsJobTicketKey>().apply {
+            ticketPointIds.forEach {
+                val isJobTicketKey = IsJobTicketKey()
+                isJobTicketKey.ticketId = ticketId
+                add(isJobTicketKey)
+            }
+        }
+        jobTicketDao.saveIsJobTicketKey(ticketKeys)
+        val ticketLocks = mutableListOf<IsJobTicketLock>().apply {
+            ticketPointIds.forEach { point ->
+                val isJobTicketLock = IsJobTicketLock()
+                isJobTicketLock.ticketId = ticketId
+                isJobTicketLock.isolationPointId = point
+                add(isJobTicketLock)
+            }
+        }
+        jobTicketDao.saveIsJobTicketLock(ticketLocks)
+        val sopData = sopDao.getSopDataBySopId(sopId!!)
+        val ticketStep = mutableListOf<IsJobTicketStep>().apply {
+            sopData.lockMode?.split(",")?.forEachIndexed { index, stepType ->
+                val isJobTicketStep = IsJobTicketStep()
+                isJobTicketStep.ticketId = ticketId
+                isJobTicketStep.stepType = stepType
+                isJobTicketStep.stepIndex = index
+                isJobTicketStep.stepContent =
+                    LockStepEnum.values().find { it.type == stepType.toInt() }?.description
+                isJobTicketStep.androidStepContent =
+                    LockStepEnum.values().find { it.type == stepType.toInt() }?.description
+                add(isJobTicketStep)
+            }
+        }
+        jobTicketDao.saveIsJobTicketStep(ticketStep)
+    }
+
+
+    companion object {
+        /**
+         * 单例
+         */
+        @JvmStatic
+        val instance: JobTicketRepository by lazy {
+            JobTicketRepository()
+        }
+    }
+}

+ 26 - 3
data/src/main/java/com/grkj/data/repository/impl/SopRepository.kt

@@ -2,10 +2,12 @@ package com.grkj.data.repository.impl
 
 import com.grkj.data.dao.IsSopDao
 import com.grkj.data.database.ISCSDatabase
+import com.grkj.data.enums.RoleEnums
 import com.grkj.data.model.dos.IsSop
 import com.grkj.data.model.dos.IsSopPoints
 import com.grkj.data.model.dos.IsSopUser
 import com.grkj.data.model.vo.PointManageVo
+import com.grkj.data.model.vo.SopManageVo
 import com.grkj.data.model.vo.UserManageVo
 import com.grkj.data.repository.ISopRepository
 
@@ -42,15 +44,36 @@ class SopRepository : ISopRepository {
         selectedColockerData: List<UserManageVo>,
         sopId: Long
     ) {
-        val isSopUsers = (selectedLockerData + selectedColockerData).map {
+        val isSopLockerUsers = selectedLockerData.map {
             val isSopUser = IsSopUser()
             isSopUser.userId = it.userId
             isSopUser.userName = it.userName
-            isSopUser.userRole = it.roleKeys.joinToString(",")
+            isSopUser.userRole = RoleEnums.JTLOCKER.roleKey
             isSopUser.sopId = sopId
             isSopUser
         }
-        isSopDao.saveSopUsers(isSopUsers)
+        val isSopColockerUsers = selectedColockerData.map {
+            val isSopUser = IsSopUser()
+            isSopUser.userId = it.userId
+            isSopUser.userName = it.userName
+            isSopUser.userRole = RoleEnums.JTCOLOCKER.roleKey
+            isSopUser.sopId = sopId
+            isSopUser
+        }
+        isSopDao.saveSopUsers(isSopLockerUsers)
+        isSopDao.saveSopUsers(isSopColockerUsers)
+    }
+
+    override fun getSopDataByWorkstationId(workstationId: Long): List<SopManageVo> {
+        return isSopDao.getSopDataByWorkstationId(workstationId)
+    }
+
+    override fun getSopPointsBySopId(sopId: Long): List<PointManageVo> {
+        return isSopDao.getSopPointsBySopId(sopId)
+    }
+
+    override fun getSopUsersBySopId(sopId: Long): List<UserManageVo> {
+        return isSopDao.getSopUsersBySopId(sopId)
     }
 
     companion object {