Selaa lähdekoodia

refactor(更新)
- 创建作业,作业详情

周文健 5 kuukautta sitten
vanhempi
sitoutus
5f34e14fdc
26 muutettua tiedostoa jossa 1313 lisäystä ja 25 poistoa
  1. 6 1
      app/src/main/java/com/grkj/iscs/common/DataTransferConstants.kt
  2. 8 2
      app/src/main/java/com/grkj/iscs/features/main/fragment/common/SelectPointFragment.kt
  3. 2 2
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/CreateJobFragment.kt
  4. 2 2
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/CreateSopFragment.kt
  5. 2 2
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/CreateSopJobFragment.kt
  6. 348 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/EditSopFragment.kt
  7. 1 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobManageHomeFragment.kt
  8. 143 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/SopManageFragment.kt
  9. 4 3
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobViewModel.kt
  10. 1 1
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/SopJobViewModel.kt
  11. 46 0
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/SopManageViewModel.kt
  12. 22 3
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/SopViewModel.kt
  13. 1 2
      app/src/main/res/layout/fragment_create_job.xml
  14. 1 2
      app/src/main/res/layout/fragment_create_sop.xml
  15. 1 2
      app/src/main/res/layout/fragment_create_sop_job.xml
  16. 377 0
      app/src/main/res/layout/fragment_edit_sop.xml
  17. 125 0
      app/src/main/res/layout/fragment_sop_manage.xml
  18. 44 0
      app/src/main/res/layout/item_sop_manage.xml
  19. 22 0
      app/src/main/res/navigation/nav_job_manage.xml
  20. 10 0
      app/src/main/res/values-en/strings.xml
  21. 10 0
      app/src/main/res/values-zh/strings.xml
  22. 10 0
      app/src/main/res/values/strings.xml
  23. 70 1
      data/src/main/java/com/grkj/data/dao/IsSopDao.kt
  24. 7 0
      data/src/main/java/com/grkj/data/model/vo/SopManageVo.kt
  25. 26 1
      data/src/main/java/com/grkj/data/repository/ISopRepository.kt
  26. 24 0
      data/src/main/java/com/grkj/data/repository/impl/SopRepository.kt

+ 6 - 1
app/src/main/java/com/grkj/iscs/common/DataTransferConstants.kt

@@ -30,5 +30,10 @@ object DataTransferConstants {
     /**
      * 是否可以选择共锁人
      */
-    const val KEY_CAN_SELECT_COLOCKER = "KEY_CAN_SELECT_COLOCKER"
+    const val KEY_CAN_SELECT_COLOCKER = "key_can_select_colocker"
+
+    /**
+     * 修改SOP的SopId
+     */
+    const val KEY_EDIT_SOP_SOP_ID = "key_edit_sop_sop_id"
 }

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

@@ -93,11 +93,17 @@ class SelectPointFragment : BaseFragment<FragmentSelectPointBinding>() {
         if (tempSelectedPointData is List<*>) {
             selectedPointData = (tempSelectedPointData as List<PointManageVo>).toMutableList()
         }
+        val previewStepTitle = GlobalDataTempStore.getInstance()
+            .getData(DataTransferConstants.KEY_PREVIEW_STEP_TITLE_DATA) as String
+        val previewStepIcon = GlobalDataTempStore.getInstance()
+            .getData(DataTransferConstants.KEY_PREVIEW_STEP_ICON_DATA) as Int
+        binding.previewStepTitle.text = previewStepTitle
+        binding.previewStepIv.setImageResource(previewStepIcon)
         viewModel.getPointData().observe(this) {
             binding.selectedPointRv.models = selectedPointData
             binding.unselectedPointRv.models = viewModel.pointManageData.apply {
-                forEach { it.isSelected == it.pointId in selectedPointData.map { it.pointId } }
-                sortBy { it.isSelected }
+                forEach { it.isSelected = it.pointId in selectedPointData.map { it.pointId } }
+                sortedBy { it.isSelected }
             }
         }
     }

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

@@ -18,7 +18,7 @@ import com.grkj.iscs.databinding.FragmentCreateJobBinding
 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.CreateJobViewModel
+import com.grkj.iscs.features.main.viewmodel.job_manage.JobViewModel
 import com.grkj.iscs.utils.getLockModeStr
 import com.grkj.iscs.utils.getLockModeType
 import com.grkj.ui_base.base.BaseFragment
@@ -38,7 +38,7 @@ import kotlin.coroutines.suspendCoroutine
  * 新建作业
  */
 class CreateJobFragment : BaseFragment<FragmentCreateJobBinding>() {
-    private val viewModel: CreateJobViewModel by lazy { ViewModelProvider(this)[CreateJobViewModel::class] }
+    private val viewModel: JobViewModel by lazy { ViewModelProvider(this)[JobViewModel::class] }
     private var selectedLockMode: String? = null
     private var selectedWorkstationId: Long? = null
     private var selectedPointData: List<PointManageVo> = mutableListOf()

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

@@ -18,7 +18,7 @@ import com.grkj.iscs.databinding.ItemSelectPointBinding
 import com.grkj.iscs.features.main.dialog.TextDropDownDialog
 import com.grkj.data.enums.LockModeEnum
 import com.grkj.data.enums.LockStepEnum
-import com.grkj.iscs.features.main.viewmodel.job_manage.CreateSopViewModel
+import com.grkj.iscs.features.main.viewmodel.job_manage.SopViewModel
 import com.grkj.iscs.utils.getLockModeStr
 import com.grkj.iscs.utils.getLockModeType
 import com.grkj.ui_base.base.BaseFragment
@@ -32,7 +32,7 @@ import com.sik.sikcore.extension.setDebouncedClickListener
  * 新建SOP
  */
 class CreateSopFragment : BaseFragment<FragmentCreateSopBinding>() {
-    private val viewModel: CreateSopViewModel by lazy { ViewModelProvider(this)[CreateSopViewModel::class] }
+    private val viewModel: SopViewModel by lazy { ViewModelProvider(this)[SopViewModel::class] }
     private var selectedLockMode: String? = null
     private var selectedWorkstationId: Long? = null
     private var selectedPointData: List<PointManageVo> = mutableListOf()

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

@@ -18,7 +18,7 @@ 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.iscs.features.main.viewmodel.job_manage.SopJobViewModel
 import com.grkj.ui_base.base.BaseFragment
 import com.grkj.ui_base.dialog.TipDialog
 import com.grkj.ui_base.utils.CommonUtils
@@ -30,7 +30,7 @@ import com.sik.sikcore.extension.setDebouncedClickListener
  * 新建SOP作业
  */
 class CreateSopJobFragment : BaseFragment<FragmentCreateSopJobBinding>() {
-    private val viewModel: CreateSopJobViewModel by lazy { ViewModelProvider(this)[CreateSopJobViewModel::class] }
+    private val viewModel: SopJobViewModel by lazy { ViewModelProvider(this)[SopJobViewModel::class] }
     private var selectedWorkstationId: Long? = null
     private var selectedSopId: Long? = null
     private var selectedSop: SopManageVo? = null

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

@@ -0,0 +1,348 @@
+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.ItemSelectMemberBinding
+import com.grkj.iscs.databinding.ItemSelectPointBinding
+import com.grkj.iscs.features.main.dialog.TextDropDownDialog
+import com.grkj.data.enums.LockModeEnum
+import com.grkj.data.enums.LockStepEnum
+import com.grkj.data.enums.RoleEnums
+import com.grkj.iscs.databinding.FragmentEditSopBinding
+import com.grkj.iscs.features.main.viewmodel.job_manage.SopViewModel
+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
+import com.kongzue.dialogx.dialogs.PopTip
+import com.sik.sikcore.data.GlobalDataTempStore
+import com.sik.sikcore.extension.setDebouncedClickListener
+
+/**
+ * 修改SOP
+ */
+class EditSopFragment : BaseFragment<FragmentEditSopBinding>() {
+    private val viewModel: SopViewModel by lazy { ViewModelProvider(this)[SopViewModel::class] }
+    private var selectedLockMode: String? = null
+    private var selectedWorkstationId: 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_edit_sop
+    }
+
+    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.sop_save_tip,
+                        args = listOf<String>(binding.sopNameEt.text.toString()).toTypedArray()
+                    ).toString(),
+                    dialogType = TipDialog.DialogType.INFO,
+                    countDownTime = 10,
+                    onConfirmClick = {
+                        saveSop()
+                    })
+            }
+        }
+        binding.workstationTv.setOnClickListener {
+            setWorkstationData()
+        }
+        binding.lockModeTv.setOnClickListener {
+            setLockModeData()
+        }
+        binding.selectPointTv.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.edit_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_editSopFragment_to_selectPointFragment)
+        }
+        binding.selectMemberTv.setDebouncedClickListener {
+            if (selectedWorkstationId == null) {
+                PopTip.tip(R.string.please_select_sop_workstation)
+                return@setDebouncedClickListener
+            }
+            if (selectedLockMode == null) {
+                PopTip.tip(R.string.please_select_lock_mode)
+                return@setDebouncedClickListener
+            }
+            GlobalDataTempStore.getInstance().saveData(
+                DataTransferConstants.KEY_CAN_SELECT_COLOCKER, selectedLockMode?.contains(
+                    LockStepEnum.COLOCK.type.toString()
+                ) == true
+            )
+            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.edit_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_editSopFragment_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 saveSop() {
+        viewModel.saveSop(
+            selectedPointData,
+            selectedLockerData,
+            selectedColockerData,
+            selectedLockMode,
+            selectedWorkstationId!!,
+            binding.sopNameEt.text.toString(),
+            viewModel.selectedSopData?.sopId ?: 0
+        ).observe(this) {
+            if (it) {
+                TipDialog.show(
+                    title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_succeed).toString(),
+                    msg = CommonUtils.getStr(R.string.sop_save_succeed).toString(),
+                    dialogType = TipDialog.DialogType.SUCCESS,
+                    countDownTime = 10,
+                )
+            } else {
+                TipDialog.show(
+                    title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_failed).toString(),
+                    msg = CommonUtils.getStr(R.string.sop_save_failed).toString(),
+                    dialogType = TipDialog.DialogType.ERROR,
+                    showConfirm = false,
+                    countDownTime = 10
+                )
+            }
+        }
+    }
+
+    /**
+     * 检查数据
+     */
+    private fun checkData(): Boolean {
+        if (selectedWorkstationId == null) {
+            PopTip.tip(R.string.please_select_sop_workstation)
+            return false
+        }
+        if (selectedLockMode == null) {
+            PopTip.tip(R.string.please_select_lock_mode)
+            return false
+        }
+        if (binding.sopNameEt.text.isEmpty()) {
+            PopTip.tip(R.string.please_input_sop_name)
+            return false
+        }
+        if (selectedPointData.isEmpty()) {
+            PopTip.tip(R.string.please_must_select_at_least_one_point)
+            return false
+        }
+        if (selectedLockerData.isEmpty()) {
+            PopTip.tip(com.grkj.ui_base.R.string.select_locker)
+            return false
+        }
+        if (selectedLockMode?.contains(
+                LockStepEnum.COLOCK.type.toString()
+            ) == true && 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 initData() {
+        super.initData()
+        val sopId = GlobalDataTempStore.getInstance()
+            .getData(DataTransferConstants.KEY_EDIT_SOP_SOP_ID) as Long
+        viewModel.getSopDataBySopId(sopId).observe(this) {
+            selectedPointData = viewModel.selectedSopPointData
+            selectedLockMode = viewModel.selectedSopData?.lockMode
+            selectedWorkstationId = viewModel.selectedSopData?.workstationId
+            binding.workstationTv.text = viewModel.selectedSopData?.workstationName
+            binding.sopNameEt.setText(viewModel.selectedSopData?.sopName)
+            binding.lockModeTv.text = LockModeEnum.values()
+                .find { it.getLockModeType() == selectedLockMode }?.description
+            selectedLockerData = viewModel.selectedSopUserData.filter {
+                it.roleKeys.contains(
+                    RoleEnums.JTLOCKER.roleKey
+                )
+            }
+            selectedColockerData = viewModel.selectedSopUserData.filter {
+                it.roleKeys.contains(
+                    RoleEnums.JTCOLOCKER.roleKey
+                )
+            }
+            binding.lockerName.text = selectedLockerData.first().nickName
+            binding.colockerRv.models = selectedColockerData
+            binding.pointRv.models = selectedPointData
+            binding.selectColockerLayout.isVisible =
+                selectedLockMode?.contains(LockStepEnum.COLOCK.type.toString()) == true
+        }
+    }
+
+    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()
+        }
+
+        if (GlobalDataTempStore.getInstance()
+                .hasData(DataTransferConstants.KEY_SELECTED_POINT_DATA)
+        ) {
+            selectedPointData = GlobalDataTempStore.getInstance()
+                .getData(DataTransferConstants.KEY_SELECTED_POINT_DATA)
+                ?.let { return@let it as List<PointManageVo> } ?: listOf()
+        }
+        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
+        }
+    }
+
+    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)
+        }
+    }
+
+    private fun setLockModeData() {
+        textDropDownDialog.setData(
+            LockModeEnum.values().map {
+                TextDropDownDialog.SimpleTextDropDownEntity(
+                    dataTag = it.getLockModeType(),
+                    dataText = it.getLockModeStr()
+                )
+            })
+        textDropDownDialog.setOnItemSelectListener {
+            binding.lockModeTv.text = it.getShowText()
+            selectedLockMode = it.getTag()
+            binding.selectColockerLayout.isVisible = selectedLockMode?.contains(
+                LockStepEnum.COLOCK.type.toString()
+            ) == true
+        }
+        textDropDownDialog.showPopupWindow(binding.lockModeTv)
+    }
+}

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

@@ -121,7 +121,7 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
             }
 
             2 -> {
-
+                navController.navigate(R.id.action_jobManageHomeFragment_to_sopManageFragment)
             }
 
             3 -> {

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

@@ -0,0 +1,143 @@
+package com.grkj.iscs.features.main.fragment.job_manage
+
+import android.graphics.Color
+import androidx.lifecycle.ViewModelProvider
+import com.drake.brv.BindingAdapter
+import com.drake.brv.annotaion.DividerOrientation
+import com.drake.brv.utils.divider
+import com.drake.brv.utils.linear
+import com.drake.brv.utils.models
+import com.drake.brv.utils.setup
+import com.grkj.data.model.vo.SopManageVo
+import com.grkj.data.model.vo.UserManageVo
+import com.grkj.iscs.R
+import com.grkj.iscs.common.DataTransferConstants
+import com.grkj.iscs.databinding.FragmentSopManageBinding
+import com.grkj.iscs.databinding.ItemSopManageBinding
+import com.grkj.iscs.databinding.ItemUserManageUserBinding
+import com.grkj.iscs.features.main.viewmodel.job_manage.SopManageViewModel
+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
+
+/**
+ * 用户管理
+ */
+class SopManageFragment : BaseFragment<FragmentSopManageBinding>() {
+    private val viewModel: SopManageViewModel by lazy { ViewModelProvider(this)[SopManageViewModel::class] }
+    override fun getLayoutId(): Int {
+        return R.layout.fragment_sop_manage
+    }
+
+    override fun initView() {
+        binding.back.setDebouncedClickListener {
+            navController.popBackStack()
+        }
+        binding.deleteSop.setDebouncedClickListener {
+            deleteSelectedSop()
+        }
+        binding.refreshLayout.setOnRefreshListener {
+            getSopData(nextPage = false)
+        }
+        binding.refreshLayout.setOnLoadMoreListener {
+            getSopData()
+        }
+        binding.sopListRv.linear().divider {
+            this.setColor(Color.BLACK)
+            this.startVisible = false
+            this.endVisible = true
+            this.orientation = DividerOrientation.VERTICAL
+        }.setup {
+            addType<SopManageVo>(R.layout.item_sop_manage)
+            onBind {
+                onSopDataBinding(this)
+            }
+        }
+        setSelectAllListener()
+    }
+
+    private fun deleteSelectedSop() {
+        if (viewModel.sopManageDataList.none { it.isSelected }) {
+            PopTip.tip(R.string.please_select_sop)
+            return
+        }
+        TipDialog.show(
+            msg = CommonUtils.getStr(R.string.check_delete_sop).toString(),
+            countDownTime = 10,
+            onConfirmClick = {
+                viewModel.deleteSelectedSop().observe(this) {
+                    if (it) {
+                        TipDialog.show(
+                            dialogType = TipDialog.DialogType.SUCCESS,
+                            msg = CommonUtils.getStr(R.string.sop_manage_delete_succeed)
+                                .toString(),
+                            showConfirm = false,
+                            countDownTime = 10,
+                            onConfirmClick = {
+                                getSopData(false)
+                            },
+                            onCancelClick = {
+                                getSopData(false)
+                            }
+                        )
+                    } else {
+                        TipDialog.show(
+                            dialogType = TipDialog.DialogType.ERROR,
+                            msg = CommonUtils.getStr(R.string.sop_manage_delete_failed)
+                                .toString(),
+                            showConfirm = false,
+                            countDownTime = 10
+                        )
+                    }
+                }
+            })
+    }
+
+    private fun setSelectAllListener() {
+        binding.selectAll.setOnCheckedChangeListener { v, checked ->
+            viewModel.sopManageDataList.forEach { it.isSelected = checked }
+            binding.sopListRv.adapter?.notifyDataSetChanged()
+        }
+    }
+
+    private fun BindingAdapter.BindingViewHolder.onSopDataBinding(holder: BindingAdapter.BindingViewHolder) {
+        val itemBinding = holder.getBinding<ItemSopManageBinding>()
+        val item = holder.getModel<SopManageVo>()
+        itemBinding.sopName.text = item.sopName
+        itemBinding.workstation.text = item.workstationName
+        itemBinding.select.setOnCheckedChangeListener(null)
+        itemBinding.select.isChecked = item.isSelected
+        itemBinding.select.setOnCheckedChangeListener { _, checked ->
+            item.isSelected = checked
+            binding.selectAll.setOnCheckedChangeListener(null)
+            binding.selectAll.isChecked = viewModel.sopManageDataList.all { it.isSelected }
+            setSelectAllListener()
+        }
+        itemBinding.view.setDebouncedClickListener {
+            GlobalDataTempStore.getInstance()
+                .saveData(DataTransferConstants.KEY_EDIT_SOP_SOP_ID, item.sopId)
+            navController.navigate(R.id.action_sopManageFragment_to_editSopFragment)
+        }
+    }
+
+    override fun initData() {
+        super.initData()
+        getSopData(nextPage = false)
+    }
+
+    private fun getSopData(nextPage: Boolean = true) {
+        viewModel.getSopData(nextPage).observe(this) {
+            if (!nextPage) {
+                binding.selectAll.setOnCheckedChangeListener(null)
+                binding.selectAll.isChecked = false
+                setSelectAllListener()
+            }
+            binding.refreshLayout.finishRefresh()
+            binding.refreshLayout.finishLoadMore()
+            binding.sopListRv.models = viewModel.sopManageDataList
+        }
+    }
+}

+ 4 - 3
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/CreateJobViewModel.kt → app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobViewModel.kt

@@ -17,7 +17,7 @@ import kotlinx.coroutines.Dispatchers
 /**
  * 新建sop界面模型
  */
-class CreateJobViewModel : BaseViewModel() {
+class JobViewModel : 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 }
@@ -42,10 +42,11 @@ class CreateJobViewModel : BaseViewModel() {
         selectedColockerData: List<UserManageVo>,
         lockMode: String?,
         workstationId: Long,
-        sopName: String
+        sopName: String,
+        sopId: Long = 0
     ): LiveData<Long> {
         return liveData(Dispatchers.IO) {
-            val sopId = sopRepository.saveSop(sopName, workstationId, lockMode)
+            val sopId = sopRepository.saveSop(sopId,sopName, workstationId, lockMode)
             sopRepository.saveSopPoint(selectedPointsData, sopId)
             sopRepository.saveSopUser(selectedLockerData, selectedColockerData, sopId)
             emit(sopId)

+ 1 - 1
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/CreateSopJobViewModel.kt → app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/SopJobViewModel.kt

@@ -19,7 +19,7 @@ import kotlinx.coroutines.Dispatchers
 /**
  * 新建sop界面模型
  */
-class CreateSopJobViewModel : BaseViewModel() {
+class SopJobViewModel : 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 }

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

@@ -0,0 +1,46 @@
+package com.grkj.iscs.features.main.viewmodel.job_manage
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.liveData
+import com.grkj.data.model.vo.SopManageVo
+import com.grkj.data.repository.ISopRepository
+import com.grkj.data.repository.impl.SopRepository
+import com.grkj.ui_base.base.BaseViewModel
+import kotlinx.coroutines.Dispatchers
+
+/**
+ * SOP管理
+ */
+class SopManageViewModel : BaseViewModel() {
+    private val sopRepository: ISopRepository by lazy { SopRepository.instance }
+    var sopManageDataList: MutableList<SopManageVo> = mutableListOf()
+    private var current: Int = 0
+    private var size: Int = 50
+
+    /**
+     * 删除选中的sop
+     */
+    fun deleteSelectedSop(): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            sopRepository.deleteSopBySopId(sopManageDataList.filter { it.isSelected == true }
+                .map { it.sopId })
+            emit(true)
+        }
+    }
+
+    /**
+     * 获取sop数据
+     */
+    fun getSopData(nextPage: Boolean): LiveData<Boolean> {
+        if (nextPage) {
+            current += 1
+        } else {
+            current = 0
+            sopManageDataList.clear()
+        }
+        return liveData(Dispatchers.IO) {
+            sopManageDataList.addAll(sopRepository.getSopDataPage(current, size))
+            emit(true)
+        }
+    }
+}

+ 22 - 3
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/CreateSopViewModel.kt → app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/SopViewModel.kt

@@ -4,6 +4,7 @@ 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
@@ -15,10 +16,13 @@ import kotlinx.coroutines.Dispatchers
 /**
  * 新建sop界面模型
  */
-class CreateSopViewModel : BaseViewModel() {
+class SopViewModel : BaseViewModel() {
     private val workstationRepository: IWorkstationRepository by lazy { WorkstationRepository.instance }
     private val sopRepository: ISopRepository by lazy { SopRepository.instance }
     var workstationData: List<IsWorkstation> = listOf()
+    var selectedSopData: SopManageVo? = null
+    var selectedSopPointData: List<PointManageVo> = mutableListOf()
+    var selectedSopUserData: List<UserManageVo> = mutableListOf()
 
     /**
      * 初始化岗位数据
@@ -39,13 +43,28 @@ class CreateSopViewModel : BaseViewModel() {
         selectedColockerData: List<UserManageVo>,
         lockMode: String?,
         workstationId: Long,
-        sopName: String
+        sopName: String,
+        sopId: Long = 0
     ): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            val sopId = sopRepository.saveSop(sopName, workstationId, lockMode)
+            sopRepository.deleteSopPointsBySopId(listOf(sopId))
+            sopRepository.deleteSopUsersBySopId(listOf(sopId))
+            val sopId = sopRepository.saveSop(sopId,sopName, workstationId, lockMode)
             sopRepository.saveSopPoint(selectedPointsData, sopId)
             sopRepository.saveSopUser(selectedLockerData, selectedColockerData, sopId)
             emit(true)
         }
     }
+
+    /**
+     * 根据sopId获取sop相关数据
+     */
+    fun getSopDataBySopId(sopId: Long): LiveData<Boolean> {
+        return liveData(Dispatchers.IO) {
+            selectedSopPointData = sopRepository.getSopPointsBySopId(sopId)
+            selectedSopUserData = sopRepository.getSopUsersBySopId(sopId)
+            selectedSopData = sopRepository.getSopDataBySopId(sopId)
+            emit(true)
+        }
+    }
 }

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

@@ -324,6 +324,7 @@
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
                             android:gravity="center"
+                            android:paddingBottom="10dp"
                             android:orientation="vertical">
 
                             <ImageView
@@ -338,8 +339,6 @@
                                 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>

+ 1 - 2
app/src/main/res/layout/fragment_create_sop.xml

@@ -324,6 +324,7 @@
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
                             android:gravity="center"
+                            android:paddingBottom="10dp"
                             android:orientation="vertical">
 
                             <ImageView
@@ -338,8 +339,6 @@
                                 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>

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

@@ -309,6 +309,7 @@
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
                             android:gravity="center"
+                            android:paddingBottom="10dp"
                             android:orientation="vertical">
 
                             <ImageView
@@ -323,8 +324,6 @@
                                 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>

+ 377 - 0
app/src/main/res/layout/fragment_edit_sop.xml

@@ -0,0 +1,377 @@
+<?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/edit_sop_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:gravity="center_vertical"
+                android:orientation="horizontal"
+                android:paddingHorizontal="16dp">
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/lock_mode"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+
+                <TextView
+                    android:id="@+id/lock_mode_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_lock_mode"
+                    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/create_sop_name"
+                    android:textColor="@color/black"
+                    android:textSize="18sp" />
+
+                <EditText
+                    android:id="@+id/sop_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_sop_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" />
+
+                <TextView
+                    android:id="@+id/select_point_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" />
+
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/point_rv"
+                android:layout_width="match_parent"
+                android:layout_height="240dp"
+                android:paddingBottom="10dp" />
+
+        </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" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:gravity="center"
+                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:paddingBottom="10dp"
+                        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:textColor="@color/black"
+                            android:textSize="20sp" />
+                    </LinearLayout>
+                </LinearLayout>
+
+                <LinearLayout
+                    android:id="@+id/select_colocker_layout"
+                    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>
+
+        <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>

+ 125 - 0
app/src/main/res/layout/fragment_sop_manage.xml

@@ -0,0 +1,125 @@
+<?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/sop_manage_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:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingHorizontal="10dp"
+            android:paddingVertical="10dp">
+
+            <TextView
+                android:id="@+id/delete_sop"
+                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/delete"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginHorizontal="20dp"
+            android:layout_marginTop="10dp"
+            android:background="@drawable/common_card_bg"
+            android:divider="@drawable/divider_table"
+            android:showDividers="middle">
+
+            <CheckBox
+                android:id="@+id/select_all"
+                android:layout_width="30dp"
+                android:layout_height="30dp"
+                android:layout_gravity="center"
+                android:layout_margin="10dp" />
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/sop_manage_sop_name"
+                android:textSize="18sp" />
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/sop_manage_workstation"
+                android:textSize="18sp" />
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center"
+                android:text="@string/detail"
+                android:textSize="18sp" />
+        </LinearLayout>
+
+        <com.scwang.smart.refresh.layout.SmartRefreshLayout
+            android:id="@+id/refresh_layout"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginHorizontal="20dp"
+            android:layout_marginBottom="10dp">
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/sop_list_rv"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="@drawable/common_card_bg" />
+        </com.scwang.smart.refresh.layout.SmartRefreshLayout>
+    </LinearLayout>
+</layout>

+ 44 - 0
app/src/main/res/layout/item_sop_manage.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:divider="@drawable/divider_table"
+        android:showDividers="middle">
+
+        <CheckBox
+            android:id="@+id/select"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            android:layout_gravity="center"
+            android:layout_margin="10dp" />
+
+        <TextView
+            android:id="@+id/sop_name"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:ellipsize="end"
+            android:gravity="center"
+            android:singleLine="true"
+            android:textSize="18sp" />
+
+        <TextView
+            android:id="@+id/workstation"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:gravity="center"
+            android:textSize="18sp" />
+
+        <TextView
+            android:id="@+id/view"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:gravity="center"
+            android:text="@string/user_manage_view"
+            android:textSize="18sp" />
+    </LinearLayout>
+</layout>

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

@@ -17,6 +17,9 @@
         <action
             android:id="@+id/action_jobManageHomeFragment_to_createSopJobFragment"
             app:destination="@id/createSopJobFragment" />
+        <action
+            android:id="@+id/action_jobManageHomeFragment_to_sopManageFragment"
+            app:destination="@id/sopManageFragment" />
     </fragment>
     <fragment
         android:id="@+id/createJobFragment"
@@ -60,4 +63,23 @@
             android:id="@+id/action_createSopJobFragment_to_selectMemberFragment"
             app:destination="@id/selectMemberFragment" />
     </fragment>
+    <fragment
+        android:id="@+id/sopManageFragment"
+        android:name="com.grkj.iscs.features.main.fragment.job_manage.SopManageFragment"
+        android:label="SopManageFragment" >
+        <action
+            android:id="@+id/action_sopManageFragment_to_editSopFragment"
+            app:destination="@id/editSopFragment" />
+    </fragment>
+    <fragment
+        android:id="@+id/editSopFragment"
+        android:name="com.grkj.iscs.features.main.fragment.job_manage.EditSopFragment"
+        android:label="EditSopFragment" >
+        <action
+            android:id="@+id/action_editSopFragment_to_selectMemberFragment"
+            app:destination="@id/selectMemberFragment" />
+        <action
+            android:id="@+id/action_editSopFragment_to_selectPointFragment"
+            app:destination="@id/selectPointFragment" />
+    </fragment>
 </navigation>

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

@@ -128,4 +128,14 @@
     <string name="job_create_failed">Job create failed</string>
     <string name="job_save_tip">Are you sure you want to execute the job \"%1$s\"?</string>
     <string name="save_sop_check">Create SOP</string>
+    <string name="sop_manage_title">SOP manage</string>
+    <string name="sop_manage_sop_name">SOP name</string>
+    <string name="sop_manage_workstation">workstation</string>
+    <string name="detail">detail</string>
+    <string name="check_delete_sop">Are you sure to delete selected SOP?</string>
+    <string name="sop_manage_delete_failed">Delete selected SOP failed</string>
+    <string name="sop_manage_delete_succeed">Delete selected SOP succeed </string>
+    <string name="edit_sop_title">SOP detail</string>
+    <string name="sop_save_succeed">SOP save succeed</string>
+    <string name="sop_save_failed">SOP save failed</string>
 </resources>

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

@@ -128,4 +128,14 @@
     <string name="job_create_failed">作业执行失败</string>
     <string name="job_save_tip">确定要执行作业\"%1$s\"吗?</string>
     <string name="save_sop_check">生成SOP</string>
+    <string name="sop_manage_title">SOP管理</string>
+    <string name="sop_manage_sop_name">SOP名称</string>
+    <string name="sop_manage_workstation">所属岗位</string>
+    <string name="detail">详情</string>
+    <string name="check_delete_sop">您确定要删除选中的SOP吗</string>
+    <string name="sop_manage_delete_failed">无法删除选中的SOP</string>
+    <string name="sop_manage_delete_succeed">删除选中的SOP成功</string>
+    <string name="edit_sop_title">SOP详情</string>
+    <string name="sop_save_succeed">SOP保存成功</string>
+    <string name="sop_save_failed">SOP保存失败</string>
 </resources>

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

@@ -127,4 +127,14 @@
     <string name="job_create_failed">作业执行失败</string>
     <string name="job_save_tip">确定要执行作业\"%1$s\"吗?</string>
     <string name="save_sop_check">生成SOP</string>
+    <string name="sop_manage_title">SOP管理</string>
+    <string name="sop_manage_sop_name">SOP名称</string>
+    <string name="sop_manage_workstation">所属岗位</string>
+    <string name="detail">详情</string>
+    <string name="check_delete_sop">您确定要删除选中的SOP吗</string>
+    <string name="sop_manage_delete_failed">无法删除选中的SOP</string>
+    <string name="sop_manage_delete_succeed">删除选中的SOP成功</string>
+    <string name="edit_sop_title">SOP详情</string>
+    <string name="sop_save_succeed">SOP保存成功</string>
+    <string name="sop_save_failed">SOP保存失败</string>
 </resources>

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

@@ -40,7 +40,20 @@ interface IsSopDao {
     /**
      * 根据岗位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")
+    @Query(
+        """
+        select sop_id as sopId,
+            `is`.sop_name as sopName,
+            `is`.sop_type as sopType,
+            `is`.lock_mode as LockMode,
+            `is`.workstation_id as workstationId,
+            iw.workstation_name as workstationName,
+            `is`.del_flag as delFlag 
+            from is_sop `is` 
+            left join is_workstation iw on `is`.workstation_id = iw.workstation_id
+            where `is`.workstation_id = :workstationId
+    """
+    )
     fun getSopDataByWorkstationId(workstationId: Long): List<SopManageVo>
 
     /**
@@ -99,4 +112,60 @@ interface IsSopDao {
      */
     @Query("select * from is_sop where sop_id = :sopId")
     fun getSopDataBySopId(sopId: Long): IsSop
+
+    /**
+     * 获取sop数据分页
+     */
+    @Query(
+        """
+        select sop_id as sopId,
+            `is`.sop_name as sopName,
+            `is`.sop_type as sopType,
+            `is`.lock_mode as LockMode,
+            `is`.workstation_id as workstationId,
+            iw.workstation_name as workstationName,
+            `is`.del_flag as delFlag 
+            from is_sop `is` 
+            left join is_workstation iw on `is`.workstation_id = iw.workstation_id
+            limit :size offset :offset
+    """
+    )
+    fun getSopDataPage(size: Int, offset: Int): List<SopManageVo>
+
+    /**
+     * 根据sopId删除sop
+     */
+    @Query("delete from is_sop where sop_id in (:sopIds)")
+    fun deleteSopBySopId(sopIds: List<Long>)
+
+    /**
+     * 根据sopId删除sop点位
+     */
+    @Query("delete from is_sop_points where sop_id in (:sopIds)")
+    fun deleteSopPointsBySopId(sopIds: List<Long>)
+
+    /**
+     * 根据sopId删除sop用户
+     */
+    @Query("delete from is_sop_user where sop_id in (:sopIds)")
+    fun deleteSopUsersBySopId(sopIds: List<Long>)
+
+    /**
+     * 根据sopId获取数据
+     */
+    @Query(
+        """
+        select sop_id as sopId,
+            `is`.sop_name as sopName,
+            `is`.sop_type as sopType,
+            `is`.lock_mode as lockMode,
+            `is`.workstation_id as workstationId,
+            iw.workstation_name as workstationName,
+            `is`.del_flag as delFlag 
+            from is_sop `is` 
+            left join is_workstation iw on `is`.workstation_id = iw.workstation_id
+            where `is`.sop_id = :sopId
+    """
+    )
+    fun getSopManageDataBySopId(sopId: Long): SopManageVo
 }

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

@@ -1,5 +1,7 @@
 package com.grkj.data.model.vo
 
+import androidx.room.Ignore
+
 /**
  * Sop管理数据
  */
@@ -14,5 +16,10 @@ class SopManageVo {
 
     var workstationId: Long = 0
 
+    var workstationName: String = ""
+
     var delFlag: String? = "0"
+
+    @Ignore
+    var isSelected = false
 }

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

@@ -11,7 +11,7 @@ interface ISopRepository {
     /**
      * 保存sop
      */
-    fun saveSop(sopName: String, workstationId: Long, lockMode: String?): Long
+    fun saveSop(sopId: Long,sopName: String, workstationId: Long, lockMode: String?): Long
 
     /**
      * 保存sop点位
@@ -41,4 +41,29 @@ interface ISopRepository {
      * 根据sopId获取SOP用户
      */
     fun getSopUsersBySopId(sopId: Long): List<UserManageVo>
+
+    /**
+     * sopId列表
+     */
+    fun deleteSopBySopId(sopIds: List<Long>)
+
+    /**
+     * 获取sop数据分页
+     */
+    fun getSopDataPage(current: Int, size: Int): List<SopManageVo>
+
+    /**
+     * 根据sopId获取sop数据
+     */
+    fun getSopDataBySopId(sopId: Long): SopManageVo
+
+    /**
+     * 根据sopId列表删除点位数据
+     */
+    fun deleteSopPointsBySopId(sopIds: List<Long>)
+
+    /**
+     * 根据sopId列表删除用户数据
+     */
+    fun deleteSopUsersBySopId(sopIds: List<Long>)
 }

+ 24 - 0
data/src/main/java/com/grkj/data/repository/impl/SopRepository.kt

@@ -18,11 +18,13 @@ class SopRepository : ISopRepository {
     private val isSopDao: IsSopDao by lazy { ISCSDatabase.instance.isSopDao() }
 
     override fun saveSop(
+        sopId: Long,
         sopName: String,
         workstationId: Long,
         lockMode: String?
     ): Long {
         val isSop = IsSop()
+        isSop.sopId = sopId
         isSop.sopName = sopName
         isSop.workstationId = workstationId
         isSop.lockMode = lockMode
@@ -76,6 +78,28 @@ class SopRepository : ISopRepository {
         return isSopDao.getSopUsersBySopId(sopId)
     }
 
+    override fun deleteSopBySopId(sopIds: List<Long>) {
+        isSopDao.deleteSopBySopId(sopIds)
+        isSopDao.deleteSopPointsBySopId(sopIds)
+        isSopDao.deleteSopUsersBySopId(sopIds)
+    }
+
+    override fun getSopDataPage(current: Int, size: Int): List<SopManageVo> {
+        return isSopDao.getSopDataPage(size, current * size)
+    }
+
+    override fun getSopDataBySopId(sopId: Long): SopManageVo {
+        return isSopDao.getSopManageDataBySopId(sopId)
+    }
+
+    override fun deleteSopPointsBySopId(sopIds: List<Long>) {
+        isSopDao.deleteSopPointsBySopId(sopIds)
+    }
+
+    override fun deleteSopUsersBySopId(sopIds: List<Long>) {
+        isSopDao.deleteSopUsersBySopId(sopIds)
+    }
+
     companion object {
         /**
          * 单例