|
@@ -0,0 +1,258 @@
|
|
|
|
|
+package com.grkj.iscs.features.main.entity
|
|
|
|
|
+
|
|
|
|
|
+import com.grkj.data.data.MainDomainData
|
|
|
|
|
+import com.grkj.data.enums.JobTicketStatusEnum
|
|
|
|
|
+import com.grkj.data.enums.OperationTypeEnum
|
|
|
|
|
+import com.grkj.data.enums.TodoStatusEnum
|
|
|
|
|
+import com.grkj.data.model.local.TodoStepJoin
|
|
|
|
|
+import com.grkj.data.model.vo.TodoItemVo
|
|
|
|
|
+import kotlin.collections.contains
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 转换todo数据
|
|
|
|
|
+ */
|
|
|
|
|
+fun TodoStepJoin.toTodoVo(sameTicketStepJoinData: List<TodoStepJoin>): TodoItemVo {
|
|
|
|
|
+ val isCreator = createBy == MainDomainData.userInfo?.userName
|
|
|
|
|
+ val type = OperationTypeEnum.fromJoin(this, isCreator)
|
|
|
|
|
+ val temp = this
|
|
|
|
|
+ return TodoItemVo().apply {
|
|
|
|
|
+ this.todoId = temp.stepId
|
|
|
|
|
+ this.ticketId = temp.ticketId
|
|
|
|
|
+ this.ticketName = temp.ticketName
|
|
|
|
|
+ this.ticketStatus = temp.ticketStatus
|
|
|
|
|
+ this.stepId = temp.stepId
|
|
|
|
|
+ this.workflowStepId = temp.workflowStepId
|
|
|
|
|
+ this.stepIndex = temp.stepIndex
|
|
|
|
|
+ this.isCurrentStep =
|
|
|
|
|
+ sameTicketStepJoinData.filter { it.stepStatus == "0" }
|
|
|
|
|
+ .minByOrNull { it.stepIndex }?.stepIndex == temp.stepIndex || (sameTicketStepJoinData.none {
|
|
|
|
|
+ it.stepStatus == "0"
|
|
|
|
|
+ } && temp.enableEndJob)
|
|
|
|
|
+ this.todoTitle = temp.stepTitleShort ?: temp.stepTitle
|
|
|
|
|
+ this.todoContent = temp.stepDescription
|
|
|
|
|
+ this.todoType = type
|
|
|
|
|
+ this.groupId = temp.groupId
|
|
|
|
|
+ this.groupName = temp.groupName
|
|
|
|
|
+ this.stepStatus = temp.stepStatus
|
|
|
|
|
+ this.stepUpdateTime = temp.stepUpdateTime
|
|
|
|
|
+ this.colockerStatus = temp.colockerStatus
|
|
|
|
|
+ this.pointStatus = temp.pointStatus
|
|
|
|
|
+ this.createTime = temp.ticketStartTime
|
|
|
|
|
+ this.enableSetLocker = temp.enableSetLocker
|
|
|
|
|
+ this.enableSetColocker = temp.enableSetColocker
|
|
|
|
|
+ this.enableAddColocker = temp.enableAddColocker
|
|
|
|
|
+ this.enableReduceColocker = temp.enableReduceColocker
|
|
|
|
|
+ this.enableLock = temp.enableLock
|
|
|
|
|
+ this.enableColock = temp.enableColock
|
|
|
|
|
+ this.enableReleaseColock = temp.enableReleaseColock
|
|
|
|
|
+ this.enableUnlock = temp.enableUnlock
|
|
|
|
|
+ this.enableEndJob = temp.enableEndJob
|
|
|
|
|
+ this.confirmUser = temp.confirmUser
|
|
|
|
|
+ this.confirmRoleCode = temp.confirmRoleCode
|
|
|
|
|
+ this.stepTitle = temp.stepTitle
|
|
|
|
|
+ this.stepTitleShort = temp.stepTitleShort
|
|
|
|
|
+ this.stepDescription = temp.stepDescription
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+fun splitTodoSteps(
|
|
|
|
|
+ all: List<TodoItemVo>,
|
|
|
|
|
+ waitLimit: Int = Int.MAX_VALUE // 限制“批次”数量
|
|
|
|
|
+): Int {
|
|
|
|
|
+ val tempTodo = mutableListOf<TodoItemVo>()
|
|
|
|
|
+ val tempWait = mutableListOf<TodoItemVo>()
|
|
|
|
|
+ val tempDone = mutableListOf<TodoItemVo>()
|
|
|
|
|
+
|
|
|
|
|
+ /* —— 1. 按 ticketId 分组 —— */
|
|
|
|
|
+ val grouped = all.groupBy { it.ticketId }
|
|
|
|
|
+
|
|
|
|
|
+ for ((_, steps) in grouped) {
|
|
|
|
|
+ var doneSteps =
|
|
|
|
|
+ steps.filter {
|
|
|
|
|
+ it.stepStatus == "1" && (!it.enableEndJob && it.ticketStatus in listOf(
|
|
|
|
|
+ JobTicketStatusEnum.SELECT_MEMBER.status,
|
|
|
|
|
+ JobTicketStatusEnum.LOCKING.status,
|
|
|
|
|
+ JobTicketStatusEnum.COLOCKING.status,
|
|
|
|
|
+ JobTicketStatusEnum.UNLOCKING.status,
|
|
|
|
|
+ JobTicketStatusEnum.PROGRESSING.status,
|
|
|
|
|
+ ) || it.ticketStatus == JobTicketStatusEnum.FINISHED.status)
|
|
|
|
|
+ }
|
|
|
|
|
+ val pendingSteps =
|
|
|
|
|
+ steps.filter {
|
|
|
|
|
+ it.stepStatus == "0" || (it.stepStatus == "1" && it.enableEndJob && it.ticketStatus in listOf(
|
|
|
|
|
+ JobTicketStatusEnum.SELECT_MEMBER.status,
|
|
|
|
|
+ JobTicketStatusEnum.LOCKING.status,
|
|
|
|
|
+ JobTicketStatusEnum.COLOCKING.status,
|
|
|
|
|
+ JobTicketStatusEnum.UNLOCKING.status,
|
|
|
|
|
+ JobTicketStatusEnum.PROGRESSING.status,
|
|
|
|
|
+ ))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* —— 当前步骤 → todoData —— */
|
|
|
|
|
+ val todoStep =
|
|
|
|
|
+ pendingSteps.filter { it.isCurrentStep }.findPredecessors()
|
|
|
|
|
+ tempTodo += todoStep.second
|
|
|
|
|
+ doneSteps = doneSteps.toMutableList().apply {
|
|
|
|
|
+ addAll(todoStep.third)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* —— 其它待办 → waitData —— */
|
|
|
|
|
+ val otherPending = pendingSteps.filter { it !in (todoStep.second + todoStep.third) }
|
|
|
|
|
+
|
|
|
|
|
+ /* ① 按 (stepIndex, actionKey) 分批 —— */
|
|
|
|
|
+ val byBatch = otherPending
|
|
|
|
|
+ .groupBy { it.stepIndex to actionKey(it) } // <─ 新增动作维度
|
|
|
|
|
+ .toSortedMap(
|
|
|
|
|
+ compareBy<Pair<Int, Int>> { it.first } // stepIndex 升序
|
|
|
|
|
+ .thenBy { it.second } // actionKey 字典序
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ var pickedBatch = 0
|
|
|
|
|
+ for ((_, batchList) in byBatch) {
|
|
|
|
|
+ if (pickedBatch >= waitLimit) break
|
|
|
|
|
+ if (batchList.isEmpty()) continue
|
|
|
|
|
+
|
|
|
|
|
+ val action = actionKey(batchList[0]) // 同批次动作一致,取任意一条判断即可
|
|
|
|
|
+
|
|
|
|
|
+ if (action == 1 || action == 4) {
|
|
|
|
|
+ // ✅ 上锁/解锁 → 同一 stepIndex 下多个 group 要全部保留
|
|
|
|
|
+ tempWait += batchList
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // ✅ 其他类型 → 只保留一条代表
|
|
|
|
|
+ tempWait.add(batchList.first())
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pickedBatch++
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tempDone += doneSteps
|
|
|
|
|
+ }
|
|
|
|
|
+ tempTodo.forEach {
|
|
|
|
|
+ it.todoStatus = TodoStatusEnum.TODO
|
|
|
|
|
+ }
|
|
|
|
|
+ tempWait.forEach {
|
|
|
|
|
+ it.todoStatus = TodoStatusEnum.WAIT
|
|
|
|
|
+ it.previousTodoItem = tempTodo.filter { todoData -> it.ticketId == todoData.ticketId }
|
|
|
|
|
+ }
|
|
|
|
|
+ tempDone.forEach {
|
|
|
|
|
+ it.todoStatus = TodoStatusEnum.DONE
|
|
|
|
|
+ }
|
|
|
|
|
+ /* —— 结果赋值 —— */
|
|
|
|
|
+ return tempTodo.size + tempWait.size
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 处理前置
|
|
|
|
|
+ */
|
|
|
|
|
+fun List<TodoItemVo>.findPredecessors(): Triple<List<TodoItemVo>, List<TodoItemVo>, List<TodoItemVo>> {
|
|
|
|
|
+ return when {
|
|
|
|
|
+ any { it.enableLock } && any { it.enableColock } -> {
|
|
|
|
|
+ if (this.any { it.pointStatus.any { it == "0" } }) {
|
|
|
|
|
+ Triple(filter { it.enableColock }, filter { it.enableLock }, mutableListOf())
|
|
|
|
|
+ } else if (this.any { it.pointStatus.all { it == "1" } } && this.any { it.colockerStatus.any { it == "0" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableColock },
|
|
|
|
|
+ filter { it.enableLock })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ mutableListOf(),
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableLock || it.enableColock })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ any { it.enableColock } && any { it.enableReleaseColock } -> {
|
|
|
|
|
+ if (this.any { it.colockerStatus.any { it == "0" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.enableReleaseColock },
|
|
|
|
|
+ filter { it.enableColock },
|
|
|
|
|
+ mutableListOf()
|
|
|
|
|
+ )
|
|
|
|
|
+ } else if (this.all { it.colockerStatus.all { it == "1" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableReleaseColock },
|
|
|
|
|
+ filter { it.enableColock })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ mutableListOf(),
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableReleaseColock || it.enableColock })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ any { it.enableReleaseColock } && any { it.enableUnlock } && any { it.enableEndJob } -> {
|
|
|
|
|
+ if (this.any { it.colockerStatus.any { it != "2" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.enableUnlock },
|
|
|
|
|
+ filter { it.enableReleaseColock },
|
|
|
|
|
+ mutableListOf()
|
|
|
|
|
+ )
|
|
|
|
|
+ } else if (this.all { it.colockerStatus.all { it == "2" } } && this.any { it.pointStatus.any { it != "2" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableUnlock },
|
|
|
|
|
+ filter { it.enableReleaseColock })
|
|
|
|
|
+ } else if (this.all { it.stepStatus == "0" } && this.all { it.pointStatus.all { it == "2" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.enableEndJob },
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableUnlock || it.enableReleaseColock })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ mutableListOf(),
|
|
|
|
|
+ filter { it.enableEndJob },
|
|
|
|
|
+ filter { it.enableUnlock || it.enableReleaseColock || it.todoType == OperationTypeEnum.CONFIRM }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ any { it.enableReleaseColock } && any { it.enableUnlock } -> {
|
|
|
|
|
+ if (this.any { it.colockerStatus.any { it != "2" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.enableUnlock },
|
|
|
|
|
+ filter { it.enableReleaseColock },
|
|
|
|
|
+ mutableListOf()
|
|
|
|
|
+ )
|
|
|
|
|
+ } else if (this.all { it.colockerStatus.all { it == "2" } } && this.any { it.pointStatus.any { it != "2" } }) {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableUnlock },
|
|
|
|
|
+ filter { it.enableReleaseColock })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ mutableListOf(),
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM },
|
|
|
|
|
+ filter { it.enableUnlock || it.enableReleaseColock })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ any { it.enableUnlock } && any { it.enableEndJob } -> {
|
|
|
|
|
+ if (this.any { it.pointStatus.any { it != "2" } }) {
|
|
|
|
|
+ Triple(filter { it.enableEndJob }, filter { it.enableUnlock }, mutableListOf())
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Triple(
|
|
|
|
|
+ mutableListOf(),
|
|
|
|
|
+ filter { it.enableEndJob },
|
|
|
|
|
+ filter { it.enableUnlock })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ else -> Triple(
|
|
|
|
|
+ filter { it.todoType == OperationTypeEnum.CONFIRM }, this, mutableListOf()
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* -------------------------------------------------------------
|
|
|
|
|
+ * 根据唯一的 enableXXX 返回动作标识
|
|
|
|
|
+ * ----------------------------------------------------------- */
|
|
|
|
|
+fun actionKey(item: TodoItemVo): Int = when {
|
|
|
|
|
+ item.enableLock -> 1
|
|
|
|
|
+ item.enableUnlock -> 4
|
|
|
|
|
+ item.enableColock -> 2
|
|
|
|
|
+ item.enableReleaseColock -> 3
|
|
|
|
|
+ item.enableEndJob -> 6
|
|
|
|
|
+ else -> 5
|
|
|
|
|
+}
|