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

feat(作业管理)
- 新增我的待办功能
- 首页快捷入口和作业管理模块增加角标提醒
- 管理员角色和管理员用户禁止编辑

周文健 3 hónapja
szülő
commit
25ee0062fe
21 módosított fájl, 462 hozzáadás és 29 törlés
  1. 1 2
      app/src/main/java/com/grkj/iscs/features/main/dialog/data_manage/UpdateUserDialog.kt
  2. 3 0
      app/src/main/java/com/grkj/iscs/features/main/entity/QuickEntranceMenuItemEntity.kt
  3. 5 1
      app/src/main/java/com/grkj/iscs/features/main/fragment/data_manage/RoleManageFragment.kt
  4. 16 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/home/HomeFragment.kt
  5. 42 19
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/JobManageHomeFragment.kt
  6. 99 0
      app/src/main/java/com/grkj/iscs/features/main/fragment/job_manage/MyTodoListFragment.kt
  7. 18 0
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/home/HomeViewModel.kt
  8. 9 0
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobManageHomeViewModel.kt
  9. 14 0
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobManageViewModel.kt
  10. 3 2
      app/src/main/res/layout-land/item_home_quick_entrance.xml
  11. 112 0
      app/src/main/res/layout/fragment_my_todo_list.xml
  12. 3 2
      app/src/main/res/layout/item_home_quick_entrance.xml
  13. 14 0
      app/src/main/res/navigation/nav_job_manage.xml
  14. 1 0
      app/src/main/res/values-en/strings.xml
  15. 1 0
      app/src/main/res/values-zh/strings.xml
  16. 1 0
      app/src/main/res/values/strings.xml
  17. 45 1
      data/src/main/java/com/grkj/data/dao/JobTicketDao.kt
  18. 5 0
      data/src/main/java/com/grkj/data/enums/RoleFunctionalPermissionsEnum.kt
  19. 17 1
      data/src/main/java/com/grkj/data/repository/IJobTicketRepository.kt
  20. 11 0
      data/src/main/java/com/grkj/data/repository/impl/network/NetworkJobTicketRepository.kt
  21. 42 1
      data/src/main/java/com/grkj/data/repository/impl/standard/JobTicketRepository.kt

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

@@ -43,6 +43,7 @@ class UpdateUserDialog(
 
         binding.cardcodeEt.isEnabled = false
         binding.usernameEt.isEnabled = false
+        binding.roleTv.isEnabled = userVo.userId != 1L
 
         // 预填数据
         binding.usernameEt.setText(userVo.userName)
@@ -96,8 +97,6 @@ class UpdateUserDialog(
             val card = binding.cardcodeEt.text.trim().toString()
             if (name.isBlank()) return@setOnClickListener PopTip.build()
                 .tip(R.string.please_input_nickname)
-            if (card.isBlank()) return@setOnClickListener PopTip.build()
-                .tip(R.string.please_input_card_code)
             if (selectedRoles.isEmpty()) return@setOnClickListener PopTip.build()
                 .tip(R.string.please_select_role)
             if (ISCSConfig.isWorkstationOn && selectedWorkstations.isEmpty()) return@setOnClickListener PopTip.build()

+ 3 - 0
app/src/main/java/com/grkj/iscs/features/main/entity/QuickEntranceMenuItemEntity.kt

@@ -31,6 +31,7 @@ data class QuickEntranceMenuItemEntity(
                 RoleFunctionalPermissionsEnum.ROLE_MANAGE -> R.mipmap.icon_data_manage_menu_role_manage
                 RoleFunctionalPermissionsEnum.WORKSTATION_MANAGE -> R.mipmap.icon_data_manage_menu_area_manage
                 RoleFunctionalPermissionsEnum.POINT_MANAGE -> R.mipmap.icon_data_manage_menu_point_manage
+                RoleFunctionalPermissionsEnum.TODO_LIST -> R.mipmap.icon_job_manage_in_progress_job
                 RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB -> R.mipmap.icon_job_manage_in_progress_job
                 RoleFunctionalPermissionsEnum.CREATE_SOP -> R.mipmap.icon_job_manage_create_sop
                 RoleFunctionalPermissionsEnum.SOP_MANAGE -> R.mipmap.icon_job_manage_sop_manage
@@ -64,6 +65,7 @@ data class QuickEntranceMenuItemEntity(
                 RoleFunctionalPermissionsEnum.USER_MANAGE, RoleFunctionalPermissionsEnum.ROLE_MANAGE,
                 RoleFunctionalPermissionsEnum.WORKSTATION_MANAGE, RoleFunctionalPermissionsEnum.POINT_MANAGE -> R.navigation.nav_data_manage
 
+                RoleFunctionalPermissionsEnum.TODO_LIST,
                 RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB,
                 RoleFunctionalPermissionsEnum.CREATE_SOP,
                 RoleFunctionalPermissionsEnum.SOP_MANAGE,
@@ -103,6 +105,7 @@ data class QuickEntranceMenuItemEntity(
                 RoleFunctionalPermissionsEnum.ROLE_MANAGE -> R.id.action_dataManageHomeFragment_to_roleManageFragment
                 RoleFunctionalPermissionsEnum.WORKSTATION_MANAGE -> R.id.action_dataManageHomeFragment_to_workstationManageFragment
                 RoleFunctionalPermissionsEnum.POINT_MANAGE -> R.id.action_dataManageHomeFragment_to_pointMangeFragment
+                RoleFunctionalPermissionsEnum.TODO_LIST -> R.id.action_jobManageHomeFragment_to_myTodoListFragment
                 RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB -> R.id.action_jobManageHomeFragment_to_inProgressJobManageFragment
                 RoleFunctionalPermissionsEnum.CREATE_SOP -> R.id.action_jobManageHomeFragment_to_createSopFragment
                 RoleFunctionalPermissionsEnum.SOP_MANAGE -> R.id.action_jobManageHomeFragment_to_sopManageFragment

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

@@ -146,6 +146,10 @@ class RoleManageFragment : BaseFragment<FragmentRoleManageBinding>() {
             setSelectAllListener()
         }
         itemBinding.root.setOnClickListener {
+            if (item.roleKey== RoleEnum.ADMIN.roleKey){
+                showToast(CommonUtils.getStr(R.string.admin_role_can_not_edit).toString())
+                return@setOnClickListener
+            }
             viewModel.getFunctionalPermissionsByRoleId(item.roleId)
                 .observe(this@RoleManageFragment) {
                     UpdateRoleDialog.show(UpdateRoleDataEntity().apply {
@@ -157,7 +161,7 @@ class RoleManageFragment : BaseFragment<FragmentRoleManageBinding>() {
                         isPreset = item.roleKey in RoleEnum.values().map { it.roleKey }
                     }) { data, dialog ->
                         if (data.roleKeys in RoleEnum.values()
-                                .map { it.roleKey } && data.isPreset == false
+                                .map { it.roleKey } && !data.isPreset
                         ) {
                             TipDialog.show(
                                 title = CommonUtils.getStr(com.grkj.ui_base.R.string.action_failed)

+ 16 - 0
app/src/main/java/com/grkj/iscs/features/main/fragment/home/HomeFragment.kt

@@ -192,6 +192,17 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
         super.initData()
         binding.quickEntranceRv.models = quickEntranceList
         getHomeData()
+        quickEntranceList.find { it.permission == RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB }
+            ?.let {
+                viewModel.getInProgressJobCount().observe(this) { badgeNum ->
+                    it.badgeNum = badgeNum
+                }
+            }
+        quickEntranceList.find { it.permission == RoleFunctionalPermissionsEnum.TODO_LIST }?.let {
+            viewModel.getMyToDoListJobCount().observe(this) { badgeNum ->
+                it.badgeNum = badgeNum
+            }
+        }
     }
 
     private fun getHomeData() {
@@ -260,6 +271,11 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
         val item = holder.getModel<QuickEntranceMenuItemEntity>()
         itemBinding.homeMenuIv.setImageResource(item.menuIconId)
         itemBinding.homeMenuTv.text = item.menuText
+        if (item.badgeNum == 0) {
+            itemBinding.quickEntranceLayout.hiddenBadge()
+        } else {
+            itemBinding.quickEntranceLayout.showTextBadge(item.badgeNum.toString())
+        }
         itemBinding.root.setOnClickListener {
             onMenuClick(item)
         }

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

@@ -29,47 +29,53 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
         MenuItemEntity(
             0,
             R.mipmap.icon_job_manage_in_progress_job,
+            RoleFunctionalPermissionsEnum.TODO_LIST.description,
+            RoleFunctionalPermissionsEnum.TODO_LIST.functionalPermission
+        ),
+        MenuItemEntity(
+            1,
+            R.mipmap.icon_job_manage_in_progress_job,
             RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB.description,
             RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB.functionalPermission
         ),
         MenuItemEntity(
-            1,
+            2,
             R.mipmap.icon_job_manage_create_sop,
             RoleFunctionalPermissionsEnum.CREATE_SOP.description,
             RoleFunctionalPermissionsEnum.CREATE_SOP.functionalPermission
         ),
         MenuItemEntity(
-            2,
+            3,
             R.mipmap.icon_job_manage_sop_manage,
             RoleFunctionalPermissionsEnum.SOP_MANAGE.description,
             RoleFunctionalPermissionsEnum.SOP_MANAGE.functionalPermission
         ),
         MenuItemEntity(
-            3,
+            4,
             R.mipmap.icon_data_manage_menu_point_manage,
             RoleFunctionalPermissionsEnum.EXCEPTION_JOB.description,
             RoleFunctionalPermissionsEnum.EXCEPTION_JOB.functionalPermission
         ),
         MenuItemEntity(
-            4,
+            5,
             R.mipmap.icon_job_manage_create_job,
             RoleFunctionalPermissionsEnum.CREATE_JOB.description,
             RoleFunctionalPermissionsEnum.CREATE_JOB.functionalPermission
         ),
         MenuItemEntity(
-            5,
+            6,
             R.mipmap.icon_data_manage_menu_point_manage,
             RoleFunctionalPermissionsEnum.JOB_MANAGE.description,
             RoleFunctionalPermissionsEnum.JOB_MANAGE.functionalPermission
         ),
         MenuItemEntity(
-            6,
+            7,
             R.mipmap.icon_data_manage_menu_point_manage,
             RoleFunctionalPermissionsEnum.CREATE_SOP_JOB.description,
             RoleFunctionalPermissionsEnum.CREATE_SOP_JOB.functionalPermission
         ),
         MenuItemEntity(
-            7,
+            8,
             R.mipmap.icon_data_manage_menu_point_manage,
             RoleFunctionalPermissionsEnum.LOCKED_POINT.description,
             RoleFunctionalPermissionsEnum.LOCKED_POINT.functionalPermission
@@ -120,12 +126,18 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
 
     override fun onResume() {
         super.onResume()
+        menuData = menuData.filter { MainDomainData.permissions.contains(it.permission) }
+            .toMutableList()
+        binding.homeMenuRv.models = menuData
         viewModel.getInProgressJobCount().observe(this) {
-            menuData =
-                menuData.filter { MainDomainData.permissions.contains(it.permission) }
-                    .toMutableList()
-            menuData.find { it.type == 0 }?.badgeNum = it
-            binding.homeMenuRv.models = menuData
+            menuData.find { it.permission == RoleFunctionalPermissionsEnum.IN_PROGRESS_JOB.functionalPermission }?.badgeNum =
+                it
+            binding.homeMenuRv.adapter?.notifyDataSetChanged()
+        }
+        viewModel.getMyToDoListJobCount().observe(this) {
+            menuData.find { it.permission == RoleFunctionalPermissionsEnum.TODO_LIST.functionalPermission }?.badgeNum =
+                it
+            binding.homeMenuRv.adapter?.notifyDataSetChanged()
         }
         BottomNavVisibilityEvent.sendBottomNavVisibilityEvent()
     }
@@ -134,34 +146,45 @@ class JobManageHomeFragment : BaseFragment<FragmentJobManageHomeBinding>() {
         BottomNavVisibilityEvent.sendBottomNavVisibilityEvent(false)
         when (menuType) {
             0 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_inProgressJobManageFragment)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_myTodoListFragment)
             }
 
             1 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_createSopFragment)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_inProgressJobManageFragment)
+
             }
 
             2 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_sopManageFragment)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_createSopFragment)
+
             }
 
             3 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_nav_exception_job_manage)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_sopManageFragment)
+
             }
 
             4 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_createJobFragment)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_nav_exception_job_manage)
+
             }
 
             5 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_jobManageFragment)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_createJobFragment)
+
             }
 
             6 -> {
-                navController.navigate(R.id.action_jobManageHomeFragment_to_createSopJobFragment)
+                navController.navigate(R.id.action_jobManageHomeFragment_to_jobManageFragment)
+
             }
 
             7 -> {
+                navController.navigate(R.id.action_jobManageHomeFragment_to_createSopJobFragment)
+
+            }
+
+            8 -> {
                 navController.navigate(R.id.action_jobManageHomeFragment_to_lockedPointsFragment)
             }
         }

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

@@ -0,0 +1,99 @@
+package com.grkj.iscs.features.main.fragment.job_manage
+
+import android.graphics.Color
+import androidx.core.view.isVisible
+import androidx.fragment.app.viewModels
+import com.drake.brv.BindingAdapter
+import com.drake.brv.annotaion.DividerOrientation
+import com.drake.brv.utils.divider
+import com.drake.brv.utils.linear
+import com.drake.brv.utils.models
+import com.drake.brv.utils.setup
+import com.grkj.data.enums.JobTicketStatusEnum
+import com.grkj.data.model.vo.JobTicketManageVo
+import com.grkj.iscs.R
+import com.grkj.iscs.common.DataTransferConstants
+import com.grkj.iscs.databinding.FragmentInProgressJobManageBinding
+import com.grkj.iscs.databinding.FragmentMyTodoListBinding
+import com.grkj.iscs.databinding.ItemJobManageBinding
+import com.grkj.iscs.features.main.viewmodel.job_manage.JobManageViewModel
+import com.grkj.ui_base.base.BaseFragment
+import com.sik.sikcore.data.GlobalDataTempStore
+import com.sik.sikcore.extension.setDebouncedClickListener
+import dagger.hilt.android.AndroidEntryPoint
+import kotlin.getValue
+
+/**
+ * 我的待办
+ */
+@AndroidEntryPoint
+class MyTodoListFragment : BaseFragment<FragmentMyTodoListBinding>() {
+    private val viewModel: JobManageViewModel by viewModels()
+    override fun getLayoutId(): Int {
+        return R.layout.fragment_my_todo_list
+    }
+
+    override fun initView() {
+        binding.back.setDebouncedClickListener {
+            navController.popBackStack()
+        }
+        binding.refreshLayout.setOnRefreshListener {
+            getData(nextPage = false)
+        }
+        binding.refreshLayout.setOnLoadMoreListener {
+            getData()
+        }
+        binding.listRv.linear().divider {
+            this.setColor(Color.BLACK)
+            this.startVisible = false
+            this.endVisible = true
+            this.orientation = DividerOrientation.VERTICAL
+        }.setup {
+            addType<JobTicketManageVo>(R.layout.item_job_manage)
+            onBind {
+                onListDataBinding(this)
+            }
+        }
+    }
+
+    private fun onListDataBinding(holder: BindingAdapter.BindingViewHolder) {
+        val itemBinding = holder.getBinding<ItemJobManageBinding>()
+        val item = holder.getModel<JobTicketManageVo>()
+        itemBinding.jobName.text = item.ticketName
+        itemBinding.status.text = JobTicketStatusEnum.getTicketStatusStr(item.ticketStatus)
+        itemBinding.select.isVisible = false
+        itemBinding.view.setDebouncedClickListener {
+            GlobalDataTempStore.getInstance()
+                .saveData(DataTransferConstants.KEY_JOB_TICKET_ID, item.ticketId)
+            if (item.exStatus == viewModel.jobTicketStatus.find { it.dictLabel == "异常" }?.dictValue?.toInt()) {
+                viewModel.getExceptionIdByTicketId(item.ticketId)
+                    .observe(this@MyTodoListFragment) {
+                        GlobalDataTempStore.getInstance()
+                            .saveData(DataTransferConstants.KEY_EXCEPTION_ID, it)
+                        navController.navigate(R.id.action_myTodoListFragment_to_nav_exception_job_manage)
+                    }
+            } else {
+                navController.navigate(R.id.action_myTodoListFragment_to_jobExecuteFragment)
+            }
+        }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        getData(nextPage = false)
+    }
+
+    private fun getData(nextPage: Boolean = true) {
+        viewModel.getMyTodoList(nextPage).observe(this) {
+            binding.refreshLayout.finishRefresh()
+            binding.refreshLayout.finishLoadMore()
+            val data = viewModel.jobManageDataList
+            if (data.isEmpty()) {
+                binding.state.showEmpty()
+            } else {
+                binding.state.showContent()
+            }
+            binding.listRv.models = data
+        }
+    }
+}

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

@@ -106,4 +106,22 @@ class HomeViewModel @Inject constructor(
             }
         }
     }
+
+    /**
+     * 获取正在进行中的作业
+     */
+    fun getInProgressJobCount(): LiveData<Int> {
+        return liveData(Dispatchers.IO) {
+            emit(jobTicketRepository.getInProgressJobSize())
+        }
+    }
+
+    /**
+     * 获取我的待办的作业
+     */
+    fun getMyToDoListJobCount(): LiveData<Int> {
+        return liveData(Dispatchers.IO) {
+            emit(jobTicketRepository.getMyToDoListJobCount())
+        }
+    }
 }

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

@@ -20,4 +20,13 @@ class JobManageHomeViewModel @Inject constructor(
             emit(jobTicketRepository.getInProgressJobSize())
         }
     }
+
+    /**
+     * 获取我的待办的作业
+     */
+    fun getMyToDoListJobCount(): LiveData<Int> {
+        return liveData(Dispatchers.IO) {
+            emit(jobTicketRepository.getMyToDoListJobCount())
+        }
+    }
 }

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

@@ -52,6 +52,20 @@ class JobManageViewModel @Inject constructor(
         }
     }
 
+    fun getMyTodoList(nextPage: Boolean): LiveData<Boolean> {
+        if (nextPage) {
+            current += 1
+        } else {
+            current = 0
+            jobManageDataList.clear()
+        }
+        return liveData(Dispatchers.IO) {
+            jobTicketStatus = DataBusiness.fetchDict(DictConstants.KEY_JOB_TICKET_STATUS)
+            jobManageDataList.addAll(jobTicketRepository.getMyTodoList(current, size))
+            emit(true)
+        }
+    }
+
     /**
      * 根据作业id获取异常id
      */

+ 3 - 2
app/src/main/res/layout-land/item_home_quick_entrance.xml

@@ -9,7 +9,8 @@
         android:gravity="center_horizontal"
         android:orientation="vertical">
 
-        <FrameLayout
+        <cn.bingoogolapple.badgeview.BGABadgeFrameLayout
+            android:id="@+id/quick_entrance_layout"
             android:layout_width="@dimen/home_item_quick_entrance_iv_layout"
             android:layout_height="@dimen/home_item_quick_entrance_iv_layout"
             android:background="@drawable/bg_home_menu_item">
@@ -19,7 +20,7 @@
                 android:layout_width="@dimen/home_item_quick_entrance_iv"
                 android:layout_height="@dimen/home_item_quick_entrance_iv"
                 android:layout_gravity="center" />
-        </FrameLayout>
+        </cn.bingoogolapple.badgeview.BGABadgeFrameLayout>
 
         <TextView
             android:id="@+id/home_menu_tv"

+ 112 - 0
app/src/main/res/layout/fragment_my_todo_list.xml

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

+ 3 - 2
app/src/main/res/layout/item_home_quick_entrance.xml

@@ -9,7 +9,8 @@
         android:gravity="center_horizontal"
         android:orientation="vertical">
 
-        <FrameLayout
+        <cn.bingoogolapple.badgeview.BGABadgeFrameLayout
+            android:id="@+id/quick_entrance_layout"
             android:layout_width="@dimen/home_item_quick_entrance_iv_layout"
             android:layout_height="@dimen/home_item_quick_entrance_iv_layout"
             android:background="@drawable/bg_home_menu_item">
@@ -19,7 +20,7 @@
                 android:layout_width="@dimen/home_item_quick_entrance_iv"
                 android:layout_height="@dimen/home_item_quick_entrance_iv"
                 android:layout_gravity="center" />
-        </FrameLayout>
+        </cn.bingoogolapple.badgeview.BGABadgeFrameLayout>
 
         <TextView
             android:id="@+id/home_menu_tv"

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

@@ -33,6 +33,9 @@
         <action
             android:id="@+id/action_jobManageHomeFragment_to_nav_exception_job_manage"
             app:destination="@id/nav_exception_job_manage" />
+        <action
+            android:id="@+id/action_jobManageHomeFragment_to_myTodoListFragment"
+            app:destination="@id/myTodoListFragment" />
     </fragment>
     <fragment
         android:id="@+id/createJobFragment"
@@ -196,4 +199,15 @@
         android:id="@+id/exceptionJobFragment2"
         android:name="com.grkj.iscs.features.main.fragment.exception_manage.ExceptionJobFragment"
         android:label="ExceptionJobFragment" />
+    <fragment
+        android:id="@+id/myTodoListFragment"
+        android:name="com.grkj.iscs.features.main.fragment.job_manage.MyTodoListFragment"
+        android:label="MyTodoListFragment">
+        <action
+            android:id="@+id/action_myTodoListFragment_to_jobExecuteFragment"
+            app:destination="@id/jobExecuteFragment" />
+        <action
+            android:id="@+id/action_myTodoListFragment_to_nav_exception_job_manage"
+            app:destination="@id/exceptionJobFragment2" />
+    </fragment>
 </navigation>

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

@@ -480,5 +480,6 @@
     <string name="selected_quick_entrance">Configurable shortcut entrances (up to 8 shortcut entrances can be added)</string>
     <string name="all_quick_entrance">All Quick Entrances</string>
     <string name="quick_entrance_most_set_tip">Up to 8 quick entry points can be set</string>
+    <string name="admin_role_can_not_edit">Admin role can not edit</string>
 
 </resources>

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

@@ -480,5 +480,6 @@
     <string name="selected_quick_entrance">已配置的快捷入口(最多添加8个快捷入口)</string>
     <string name="all_quick_entrance">所有快捷入口</string>
     <string name="quick_entrance_most_set_tip">快捷入口最多设置8个</string>
+    <string name="admin_role_can_not_edit">管理员角色无法编辑</string>
 
 </resources>

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

@@ -483,5 +483,6 @@
     <string name="selected_quick_entrance">已配置的快捷入口(最多添加8个快捷入口)</string>
     <string name="all_quick_entrance">所有快捷入口</string>
     <string name="quick_entrance_most_set_tip">快捷入口最多设置8个</string>
+    <string name="admin_role_can_not_edit">管理员角色无法编辑</string>
 
 </resources>

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

@@ -365,6 +365,21 @@ interface JobTicketDao {
         exStatusList: List<String>
     ): Int
 
+    /**
+     * 获取我的待办的作业数量
+     */
+    @Query(
+        """select count(DISTINCT ijt.ticket_id) from is_job_ticket ijt 
+            left join is_job_ticket_user ijtu on ijt.ticket_id = ijtu.ticket_id
+            where ijt.ticket_status in (1,2,3,4,7) and (:isAdmin = 1 OR  ex_status is NUll or ex_status NOT IN (:exStatusList)) and ijtu.user_id = :userId
+        """
+    )
+    fun getMyTodoJobSize(
+        isAdmin: Boolean,
+        exStatusList: List<String>,
+        userId: Long
+    ): Int
+
     /**
      * 获取所有作业数量
      */
@@ -602,7 +617,10 @@ interface JobTicketDao {
         where ijtp.point_id in (:pointIds) and ijtp.ticket_id != :ticketId
     """
     )
-    fun getProgressTicketIdsByPointsAndExceptTicketId(ticketId: Long, pointIds: List<Long?>): List<Long>
+    fun getProgressTicketIdsByPointsAndExceptTicketId(
+        ticketId: Long,
+        pointIds: List<Long?>
+    ): List<Long>
 
     /**
      * 更新作业票挂锁数据
@@ -652,4 +670,30 @@ interface JobTicketDao {
      */
     @Query("select group_id from is_job_ticket_points where point_id = :pointId and ticket_id = :ticketId")
     fun getGroupIdByPointIdAndTicketId(pointId: Long, ticketId: Long): Long
+
+    /**
+     * 我的待办列表
+     */
+    @Query("""
+        select ijt.ticket_id as ticketId,
+        ijt.ticket_name as ticketName,
+        ijt.ticket_status as ticketStatus,
+        ijt.workstation_id as workstationId,
+        ijt.sop_id as sopId,
+        ijt.mode_id,
+        ijt.ex_status,
+        ijt.remark
+        from is_job_ticket ijt
+        left join is_job_ticket_user ijtu on ijt.ticket_id = ijtu.ticket_id
+        where ijt.ticket_status in (1,2,3,4,7) and (:isAdmin = 1 OR  ex_status is NUll or ex_status NOT IN (:exStatusList)) and ijtu.user_id = :userId
+        group by ijt.ticket_id
+        limit :size offset :offset
+    """)
+    fun getMyTodoJob(
+        isAdmin: Boolean,
+        exStatusList: List<String>,
+        userId: Long,
+        size: Int,
+        offset: Int
+    ): List<JobTicketManageVo>
 }

+ 5 - 0
data/src/main/java/com/grkj/data/enums/RoleFunctionalPermissionsEnum.kt

@@ -37,6 +37,9 @@ enum class RoleFunctionalPermissionsEnum(
     FACE_SETTING("user_info:face_setting", "设置人脸", 1, listOf()),
     CARD_SETTING("user_info:card_setting", "设置工卡", 1, listOf()),
     LOGOUT("user_info:logout", "退出登录", 1, listOf()),
+
+    TODO_LIST("home:todo_list", "我的待办", 1, listOf()),
+
     USER_INFO_HOME(
         "user_info",
         "用户信息",
@@ -64,6 +67,7 @@ enum class RoleFunctionalPermissionsEnum(
         "job_ticket_manage",
         "作业管理", 0,
         listOf(
+            TODO_LIST,
             IN_PROGRESS_JOB,
             CREATE_SOP,
             SOP_MANAGE,
@@ -81,6 +85,7 @@ enum class RoleFunctionalPermissionsEnum(
     ),
     HOME("Home", "主页", 0, listOf()),
     ;
+
     companion object {
         /**
          * 返回去除了指定枚举及其所有子节点后的列表

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

@@ -216,7 +216,13 @@ interface IJobTicketRepository {
     /**
      * 更新钥匙取出
      */
-    fun updateKeyTake(ticketId: Long, keyNfc: String, serialNo: String, virtualKey: Boolean = false, callback: (Boolean) -> Unit)
+    fun updateKeyTake(
+        ticketId: Long,
+        keyNfc: String,
+        serialNo: String,
+        virtualKey: Boolean = false,
+        callback: (Boolean) -> Unit
+    )
 
     /**
      * 上报锁具归还
@@ -297,4 +303,14 @@ interface IJobTicketRepository {
      * 根据点位id和作业id获取分组id
      */
     fun getGroupIdByPointIdAndTicketId(pointId: Long, ticketId: Long): Long
+
+    /**
+     * 获取我的待办数量
+     */
+    fun getMyToDoListJobCount(): Int
+
+    /**
+     * 获取我的待办列表
+     */
+    fun getMyTodoList(current: Int, size: Int): Collection<JobTicketManageVo>
 }

+ 11 - 0
data/src/main/java/com/grkj/data/repository/impl/network/NetworkJobTicketRepository.kt

@@ -250,6 +250,17 @@ class NetworkJobTicketRepository  @Inject constructor() : BaseRepository(), IJob
         TODO("Not yet implemented")
     }
 
+    override fun getMyToDoListJobCount(): Int {
+        TODO("Not yet implemented")
+    }
+
+    override fun getMyTodoList(
+        current: Int,
+        size: Int
+    ): Collection<JobTicketManageVo> {
+        TODO("Not yet implemented")
+    }
+
     override fun isNextLockOrUnLock(ticketId: Long): NextJobPrompt {
         TODO("Not yet implemented")
     }

+ 42 - 1
data/src/main/java/com/grkj/data/repository/impl/standard/JobTicketRepository.kt

@@ -231,6 +231,45 @@ class JobTicketRepository @Inject constructor(
         jobTicketDao.saveIsJobTicketStep(ticketStep)
     }
 
+    override fun getMyTodoList(
+        current: Int,
+        size: Int
+    ): List<JobTicketManageVo> {
+        val isAdmin = MainDomainData.roleKeys.orEmpty()
+            .contains(RoleEnum.ADMIN.roleKey)
+
+        // 普通用户要排除 "异常" 状态
+        val exStatusList = CommonDictDataEnum.JOB_TICKET_STATUS
+            .commonDictRes
+            .filter { it.dictLabel == "异常" }
+            .mapNotNull { it.dictValue }
+            .ifEmpty { listOf("") }  // 管理员也能传,但不会被用到
+        return jobTicketDao.getMyTodoJob(
+            isAdmin = isAdmin,
+            exStatusList = exStatusList,
+            userId = MainDomainData.userInfo?.userId ?: 0,
+            size = size,
+            offset = current * size
+        )
+    }
+
+    override fun getMyToDoListJobCount(): Int {
+        val isAdmin = MainDomainData.roleKeys.orEmpty()
+            .contains(RoleEnum.ADMIN.roleKey)
+
+        // 普通用户要排除 "异常" 状态
+        val exStatusList = CommonDictDataEnum.JOB_TICKET_STATUS
+            .commonDictRes
+            .filter { it.dictLabel == "异常" }
+            .mapNotNull { it.dictValue }
+            .ifEmpty { listOf("") }  // 管理员也能传,但不会被用到
+        return jobTicketDao.getMyTodoJobSize(
+            isAdmin = isAdmin,
+            exStatusList = exStatusList,
+            userId = MainDomainData.userInfo?.userId ?: 0
+        )
+    }
+
     override fun updateCoincideToUnLock(ticketDetail: TicketDetailRes, groupId: Long) {
         ticketDetail.noUnlockTicketPointsVOSet?.filter { it.groupId == groupId }
             ?.forEach { jobTicketPointsVO ->
@@ -327,7 +366,9 @@ class JobTicketRepository @Inject constructor(
 
     override fun hasJobCross(ticketId: Long): Boolean {
         val points = jobTicketDao.getJobTicketPointsDataByTicketId(ticketId)
-        val ticketIds = jobTicketDao.getProgressTicketIdsByPointsAndExceptTicketId(ticketId,points.map { it.pointId })
+        val ticketIds = jobTicketDao.getProgressTicketIdsByPointsAndExceptTicketId(
+            ticketId,
+            points.map { it.pointId })
         return ticketIds.size > 1
     }