feat(task): 优化任务列表和审批功能
- 更新TaskExtraItem数据结构,将index/id/processStatus/aiDescription字段 替换为taskId/desc/numberNo字段 - 在Service中新增pushToNext、recommendHandler、recommendBackNode、backTo 等工作流相关API接口 - 在ReviewActivity中实现完整的审批流程,包括同意和驳回操作 - 在TaskListActivity中实现可视区域任务数据同步和动态索引更新 - 优化语音识别的额外数据提供机制,支持当前可见任务列表的准确传递 - 添加工作流实例ID和活动ID的参数传递功能
这个提交包含在:
父节点
f20255947c
当前提交
d6eb9bd3bd
@ -4,7 +4,7 @@ package com.nova.brain.glass.model.data
|
|||||||
// "text": "查看下C919第45架机的零部件采购情况",
|
// "text": "查看下C919第45架机的零部件采购情况",
|
||||||
// "scence": "home",
|
// "scence": "home",
|
||||||
// "extra": [
|
// "extra": [
|
||||||
// { "index": 1, "id": "xxx", "taskType": "审核任务", "processStatus": "进行中", "aiDescription": "..." }
|
// { "taskId": "xxx", "taskType": "审核任务", "desc": "...", "numberNo": 1 }
|
||||||
// ],
|
// ],
|
||||||
// "actions": ["goToDecisionCenter"]
|
// "actions": ["goToDecisionCenter"]
|
||||||
//}
|
//}
|
||||||
@ -17,9 +17,8 @@ data class RecognizeData(
|
|||||||
|
|
||||||
// list 场景下传给服务端,帮助 NLP 定位用户所说的任务
|
// list 场景下传给服务端,帮助 NLP 定位用户所说的任务
|
||||||
data class TaskExtraItem(
|
data class TaskExtraItem(
|
||||||
val index: Int, // 列表中的显示序号(1-based)
|
val taskId: String,
|
||||||
val id: String,
|
|
||||||
val taskType: String,
|
val taskType: String,
|
||||||
val processStatus: String,
|
val desc: String,
|
||||||
val aiDescription: String
|
val numberNo: Int // 当前可见列表中的显示序号(1-based)
|
||||||
)
|
)
|
||||||
@ -2,7 +2,16 @@ package com.nova.brain.glass.repository
|
|||||||
|
|
||||||
import com.nova.brain.glass.model.RecognizeModel
|
import com.nova.brain.glass.model.RecognizeModel
|
||||||
import com.nova.brain.glass.model.data.ChatData
|
import com.nova.brain.glass.model.data.ChatData
|
||||||
|
import com.nova.brain.glass.model.data.ApiResponse
|
||||||
|
import com.nova.brain.glass.model.data.BackToData
|
||||||
|
import com.nova.brain.glass.model.data.BackToRequest
|
||||||
import com.nova.brain.glass.model.data.RecognizeData
|
import com.nova.brain.glass.model.data.RecognizeData
|
||||||
|
import com.nova.brain.glass.model.data.PushToNextData
|
||||||
|
import com.nova.brain.glass.model.data.PushToNextRequest
|
||||||
|
import com.nova.brain.glass.model.data.RecommendBackNodeData
|
||||||
|
import com.nova.brain.glass.model.data.RecommendBackNodeRequest
|
||||||
|
import com.nova.brain.glass.model.data.RecommendHandlerData
|
||||||
|
import com.nova.brain.glass.model.data.RecommendHandlerRequest
|
||||||
import com.nova.brain.glass.model.data.TaskListData
|
import com.nova.brain.glass.model.data.TaskListData
|
||||||
import com.nova.brain.glass.model.TaskSearchResponse
|
import com.nova.brain.glass.model.TaskSearchResponse
|
||||||
import com.nova.brain.glass.model.data.TopicData
|
import com.nova.brain.glass.model.data.TopicData
|
||||||
@ -12,6 +21,7 @@ import okhttp3.RequestBody
|
|||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Headers
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
import retrofit2.http.Streaming
|
import retrofit2.http.Streaming
|
||||||
|
|
||||||
@ -36,4 +46,16 @@ interface Service {
|
|||||||
@POST("/cbrain-gateway/cbrain-task-server/cbrain-task/task/glassesTaskSearch")
|
@POST("/cbrain-gateway/cbrain-task-server/cbrain-task/task/glassesTaskSearch")
|
||||||
fun glassesTaskSearch(@Body body: TaskListData): Observable<TaskSearchResponse>
|
fun glassesTaskSearch(@Body body: TaskListData): Observable<TaskSearchResponse>
|
||||||
|
|
||||||
|
@POST("/cbrain-gateway/cbrain-execute/cbrain-execute/workflow/instance/pushToNext")
|
||||||
|
fun pushToNext(@Body body: PushToNextRequest): Observable<ApiResponse<PushToNextData>>
|
||||||
|
|
||||||
|
@POST("/cbrain-gateway/cbrain-execute/cbrain-execute/glasses/recommendHandler")
|
||||||
|
fun recommendHandler(@Body body: RecommendHandlerRequest): Observable<ApiResponse<RecommendHandlerData>>
|
||||||
|
|
||||||
|
@POST("/cbrain-gateway/cbrain-execute/cbrain-execute/glasses/recommendBackNode")
|
||||||
|
fun recommendBackNode(@Body body: RecommendBackNodeRequest): Observable<ApiResponse<RecommendBackNodeData>>
|
||||||
|
|
||||||
|
@POST("/cbrain-gateway/cbrain-execute/cbrain-execute/workflow/instance/backTo")
|
||||||
|
fun backTo(@Body body: BackToRequest): Observable<ApiResponse<BackToData>>
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6,11 +6,22 @@ import com.nova.brain.glass.databinding.ActivityReviewBinding
|
|||||||
import com.nova.brain.glass.helper.OfflineCmdListener
|
import com.nova.brain.glass.helper.OfflineCmdListener
|
||||||
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
||||||
import com.nova.brain.glass.model.ItemItem
|
import com.nova.brain.glass.model.ItemItem
|
||||||
|
import com.nova.brain.glass.model.data.BackToRequest
|
||||||
|
import com.nova.brain.glass.model.data.PushToNextRequest
|
||||||
|
import com.nova.brain.glass.model.data.RecommendBackNodeRequest
|
||||||
|
import com.nova.brain.glass.model.data.RecommendHandlerRequest
|
||||||
|
import com.nova.brain.glass.repository.Service
|
||||||
import com.nova.brain.glass.viewmodel.ItemListVM
|
import com.nova.brain.glass.viewmodel.ItemListVM
|
||||||
import com.xuqm.base.adapter.BasePagedAdapter
|
import com.xuqm.base.adapter.BasePagedAdapter
|
||||||
import com.xuqm.base.adapter.CommonPagedAdapter
|
import com.xuqm.base.adapter.CommonPagedAdapter
|
||||||
import com.xuqm.base.adapter.ViewHolder
|
import com.xuqm.base.adapter.ViewHolder
|
||||||
|
import com.xuqm.base.di.manager.HttpManager
|
||||||
|
import com.xuqm.base.extensions.showMessage
|
||||||
import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
|
import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
|
||||||
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
class ReviewActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, ActivityReviewBinding>() {
|
class ReviewActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, ActivityReviewBinding>() {
|
||||||
override fun getLayoutId(): Int = R.layout.activity_review
|
override fun getLayoutId(): Int = R.layout.activity_review
|
||||||
@ -18,6 +29,17 @@ class ReviewActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, Ac
|
|||||||
|
|
||||||
override fun getRecyclerOrientation(): Int = RecyclerView.HORIZONTAL
|
override fun getRecyclerOrientation(): Int = RecyclerView.HORIZONTAL
|
||||||
|
|
||||||
|
private var isSubmitting = false
|
||||||
|
private var submitDisposable: Disposable? = null
|
||||||
|
|
||||||
|
private val workProcessInstanceId: String by lazy {
|
||||||
|
intent.getStringExtra("workProcessInstanceId").orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val currentActivityId: String by lazy {
|
||||||
|
intent.getStringExtra("currentActivityId").orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
private val listener = object : OfflineCmdListener {
|
private val listener = object : OfflineCmdListener {
|
||||||
override fun onOfflineCmd(cmd: String) {
|
override fun onOfflineCmd(cmd: String) {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
@ -26,18 +48,21 @@ class ReviewActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, Ac
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
"驳回", "拒绝", "不同意" -> {
|
"驳回", "拒绝", "不同意" -> {
|
||||||
finish()
|
submitBack()
|
||||||
}
|
}
|
||||||
"同意","通过"->{
|
"同意", "通过", "拟同意" -> {
|
||||||
finish()
|
submitAgree()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initData() {
|
override fun initData() {
|
||||||
super.initData()
|
super.initData()
|
||||||
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
binding.tvTaskHeader.text = intent.getStringExtra("taskType").orEmpty()
|
||||||
|
binding.content.text = intent.getStringExtra("content").orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -53,26 +78,140 @@ class ReviewActivity : BaseListFormLayoutNormalActivity<ItemItem, ItemListVM, Ac
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
submitDisposable?.dispose()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun submitAgree() {
|
||||||
|
if (isSubmitting) return
|
||||||
|
if (workProcessInstanceId.isBlank() || currentActivityId.isBlank()) {
|
||||||
|
"缺少流程参数,无法同意".showMessage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isSubmitting = true
|
||||||
|
submitDisposable?.dispose()
|
||||||
|
val service = HttpManager.getApi(Service::class.java)
|
||||||
|
submitDisposable = service.pushToNext(
|
||||||
|
PushToNextRequest(
|
||||||
|
workProcessInstanceId = workProcessInstanceId,
|
||||||
|
currentActivityId = currentActivityId,
|
||||||
|
needHandle = 1,
|
||||||
|
innerRequest = true
|
||||||
|
)
|
||||||
|
).flatMap { response ->
|
||||||
|
if (response.status != 200 || response.data == null) {
|
||||||
|
return@flatMap Observable.error(
|
||||||
|
IllegalStateException(if (response.msg.isBlank()) "同意失败" else response.msg)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val needHandlerActivityIds = response.data.result.orEmpty().mapNotNull { it.activityId }.distinct()
|
||||||
|
if (needHandlerActivityIds.isEmpty()) {
|
||||||
|
Observable.just(emptyList())
|
||||||
|
} else {
|
||||||
|
service.recommendHandler(
|
||||||
|
RecommendHandlerRequest(
|
||||||
|
workProcessInstanceId = workProcessInstanceId,
|
||||||
|
needHandlerActivityIds = needHandlerActivityIds
|
||||||
|
)
|
||||||
|
).flatMap { recommendResponse ->
|
||||||
|
if (recommendResponse.status != 200 || recommendResponse.data == null) {
|
||||||
|
return@flatMap Observable.error(
|
||||||
|
IllegalStateException(
|
||||||
|
if (recommendResponse.msg.isBlank()) "推荐处理人失败" else recommendResponse.msg
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Observable.just(recommendResponse.data.selectedHandler.orEmpty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.flatMap { selectedHandler ->
|
||||||
|
service.pushToNext(
|
||||||
|
PushToNextRequest(
|
||||||
|
workProcessInstanceId = workProcessInstanceId,
|
||||||
|
currentActivityId = currentActivityId,
|
||||||
|
needHandle = 0,
|
||||||
|
innerRequest = true,
|
||||||
|
comment = "拟同意",
|
||||||
|
selectedHandler = selectedHandler
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doFinally { isSubmitting = false }
|
||||||
|
.subscribe({ response ->
|
||||||
|
if (response.status == 200) {
|
||||||
|
"已同意".showMessage()
|
||||||
|
finish()
|
||||||
|
} else {
|
||||||
|
(if (response.msg.isBlank()) "同意失败" else response.msg).showMessage()
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
(e.message ?: "同意失败").showMessage()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun submitBack() {
|
||||||
|
if (isSubmitting) return
|
||||||
|
if (workProcessInstanceId.isBlank() || currentActivityId.isBlank()) {
|
||||||
|
"缺少流程参数,无法回退".showMessage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isSubmitting = true
|
||||||
|
submitDisposable?.dispose()
|
||||||
|
val service = HttpManager.getApi(Service::class.java)
|
||||||
|
submitDisposable = service.recommendBackNode(
|
||||||
|
RecommendBackNodeRequest(
|
||||||
|
workProcessInstanceId = workProcessInstanceId,
|
||||||
|
currentActivityId = currentActivityId
|
||||||
|
)
|
||||||
|
).flatMap { response ->
|
||||||
|
if (response.status != 200 || response.data?.backToActivityId.isNullOrBlank()) {
|
||||||
|
return@flatMap Observable.error(
|
||||||
|
IllegalStateException(if (response.msg.isBlank()) "推荐回退节点失败" else response.msg)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
service.backTo(
|
||||||
|
BackToRequest(
|
||||||
|
workProcessInstanceId = workProcessInstanceId,
|
||||||
|
currentActivityId = currentActivityId,
|
||||||
|
backToActivityId = response.data?.backToActivityId.orEmpty(),
|
||||||
|
comment = "驳回,请线下沟通原因"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.doFinally { isSubmitting = false }
|
||||||
|
.subscribe({ response ->
|
||||||
|
if (response.status == 200) {
|
||||||
|
"已回退".showMessage()
|
||||||
|
finish()
|
||||||
|
} else {
|
||||||
|
(if (response.msg.isBlank()) "回退失败" else response.msg).showMessage()
|
||||||
|
}
|
||||||
|
}, { e ->
|
||||||
|
(e.message ?: "回退失败").showMessage()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_item) {
|
private val adapter = object : CommonPagedAdapter<ItemItem>(R.layout.item_item) {
|
||||||
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
|
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
|
||||||
holder
|
holder
|
||||||
.setText(R.id.text, item.text)
|
.setText(R.id.text, item.text)
|
||||||
.setClickListener(R.id.text
|
.setClickListener(R.id.text) {
|
||||||
) {
|
|
||||||
when (item.text) {
|
when (item.text) {
|
||||||
"同意" -> {
|
"同意" -> {
|
||||||
finish()
|
submitAgree()
|
||||||
}
|
}
|
||||||
"拒绝" -> {
|
"拒绝" -> {
|
||||||
finish()
|
submitBack()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
|
override fun adapter(): BasePagedAdapter<ItemItem> = adapter
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ class TaskListActivity :
|
|||||||
override fun getLayoutId(): Int = R.layout.activity_task_list
|
override fun getLayoutId(): Int = R.layout.activity_task_list
|
||||||
override fun fullscreen(): Boolean = true
|
override fun fullscreen(): Boolean = true
|
||||||
private var pageStartPosition = 0
|
private var pageStartPosition = 0
|
||||||
|
private var visibleTaskExtras: List<TaskExtraItem> = emptyList()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val EXIT_CMDS = setOf("退出", "返回", "退回", "关闭")
|
private val EXIT_CMDS = setOf("退出", "返回", "退回", "关闭")
|
||||||
@ -41,6 +42,15 @@ class TaskListActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
|
override fun onChanged() {
|
||||||
|
binding.baseRecyclerView.post { refreshVisibleOrder() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||||
|
binding.baseRecyclerView.post { refreshVisibleOrder() }
|
||||||
|
}
|
||||||
|
})
|
||||||
binding.baseRecyclerView.post {
|
binding.baseRecyclerView.post {
|
||||||
refreshVisibleOrder()
|
refreshVisibleOrder()
|
||||||
}
|
}
|
||||||
@ -100,7 +110,9 @@ class TaskListActivity :
|
|||||||
private fun refreshVisibleOrder() {
|
private fun refreshVisibleOrder() {
|
||||||
val lm = binding.baseRecyclerView.layoutManager as? LinearLayoutManager ?: return
|
val lm = binding.baseRecyclerView.layoutManager as? LinearLayoutManager ?: return
|
||||||
val firstVisible = lm.findFirstVisibleItemPosition()
|
val firstVisible = lm.findFirstVisibleItemPosition()
|
||||||
if (firstVisible == RecyclerView.NO_POSITION || firstVisible == pageStartPosition) return
|
if (firstVisible == RecyclerView.NO_POSITION) return
|
||||||
|
updateVisibleTaskExtras(lm, firstVisible)
|
||||||
|
if (firstVisible == pageStartPosition) return
|
||||||
pageStartPosition = firstVisible
|
pageStartPosition = firstVisible
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
@ -121,6 +133,20 @@ class TaskListActivity :
|
|||||||
Intent(this, ReviewActivity::class.java)
|
Intent(this, ReviewActivity::class.java)
|
||||||
.putExtra("taskId", item.id)
|
.putExtra("taskId", item.id)
|
||||||
.putExtra("taskType", item.taskType)
|
.putExtra("taskType", item.taskType)
|
||||||
|
.putExtra("content", item.aiDescription)
|
||||||
|
.putExtra(
|
||||||
|
"workProcessInstanceId",
|
||||||
|
item.params.firstNotBlank("processInstanceId", "work_process_instance_id")
|
||||||
|
)
|
||||||
|
.putExtra(
|
||||||
|
"currentActivityId",
|
||||||
|
item.params.firstNotBlank(
|
||||||
|
"currentActivityId",
|
||||||
|
"current_activity_id",
|
||||||
|
"activityId",
|
||||||
|
"activity_id"
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else -> Log.d("TaskListActivity", "unknown taskType: ${item.taskType}")
|
else -> Log.d("TaskListActivity", "unknown taskType: ${item.taskType}")
|
||||||
}
|
}
|
||||||
@ -132,15 +158,7 @@ class TaskListActivity :
|
|||||||
OfflineCmdServiceHelper.addOnLineListener(offlineCmdListener)
|
OfflineCmdServiceHelper.addOnLineListener(offlineCmdListener)
|
||||||
AsrHelper.scene = "list"
|
AsrHelper.scene = "list"
|
||||||
AsrHelper.extraProvider = {
|
AsrHelper.extraProvider = {
|
||||||
viewModel.currentItems.mapIndexed { i, item ->
|
if (visibleTaskExtras.isNotEmpty()) visibleTaskExtras else buildTaskExtra(viewModel.currentItems)
|
||||||
TaskExtraItem(
|
|
||||||
index = i + 1,
|
|
||||||
id = item.id,
|
|
||||||
taskType = item.taskType,
|
|
||||||
processStatus = item.processStatus,
|
|
||||||
aiDescription = item.aiDescription
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AsrHelper.onGoToDecisionCenter = { action ->
|
AsrHelper.onGoToDecisionCenter = { action ->
|
||||||
Log.d("TaskListActivity", "recognize result: $action")
|
Log.d("TaskListActivity", "recognize result: $action")
|
||||||
@ -166,6 +184,42 @@ class TaskListActivity :
|
|||||||
AsrHelper.onOpenTaskDetail = null
|
AsrHelper.onOpenTaskDetail = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateVisibleTaskExtras(
|
||||||
|
lm: LinearLayoutManager,
|
||||||
|
firstVisible: Int = lm.findFirstVisibleItemPosition()
|
||||||
|
) {
|
||||||
|
val items = viewModel.currentItems
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
visibleTaskExtras = emptyList()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val lastVisible = lm.findLastVisibleItemPosition()
|
||||||
|
if (firstVisible == RecyclerView.NO_POSITION || lastVisible == RecyclerView.NO_POSITION) {
|
||||||
|
visibleTaskExtras = buildTaskExtra(items)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val safeFirst = firstVisible.coerceAtLeast(0).coerceAtMost(items.lastIndex)
|
||||||
|
val safeLast = lastVisible.coerceAtLeast(0).coerceAtMost(items.lastIndex)
|
||||||
|
visibleTaskExtras = if (safeFirst <= safeLast) {
|
||||||
|
buildTaskExtra(items.subList(safeFirst, safeLast + 1))
|
||||||
|
} else {
|
||||||
|
buildTaskExtra(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildTaskExtra(items: List<TaskItem>): List<TaskExtraItem> =
|
||||||
|
items.mapIndexed { index, item ->
|
||||||
|
TaskExtraItem(
|
||||||
|
taskId = item.id,
|
||||||
|
taskType = item.taskType,
|
||||||
|
desc = item.aiDescription,
|
||||||
|
numberNo = index + 1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Map<String, String>.firstNotBlank(vararg keys: String): String =
|
||||||
|
keys.firstNotNullOfOrNull { key -> this[key]?.takeIf { it.isNotBlank() } }.orEmpty()
|
||||||
|
|
||||||
private val adapter = object : CommonPagedAdapter<TaskItem>(R.layout.item_task_list) {
|
private val adapter = object : CommonPagedAdapter<TaskItem>(R.layout.item_task_list) {
|
||||||
override fun convert(holder: ViewHolder, item: TaskItem, position: Int) {
|
override fun convert(holder: ViewHolder, item: TaskItem, position: Int) {
|
||||||
val displayPosition = (position - pageStartPosition + 1).coerceAtLeast(1)
|
val displayPosition = (position - pageStartPosition + 1).coerceAtLeast(1)
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户