feat(task): 添加任务中心语音识别功能
- 新增 goToTaskCenter 回调函数用于处理任务中心跳转 - 修改 ASR 处理逻辑支持 goToTaskCenter 和 goToDecisionCenter 两种操作 - 扩展 RecognizeParams 数据类添加任务相关参数字段 - 更新 TaskItem 数据模型增加任务类型、参数和状态信息 - 修改 Service 接口返回 TaskSearchResponse 类型 - 在 ChatActivity 中处理语音识别结果并调用相应功能 - 实现 TaskListActivity 的初始化数据加载和任务列表显示 - 更新 WelcomeActivity 添加任务中心跳转功能 - 完善 TaskListVM 从服务端获取真实任务数据
这个提交包含在:
父节点
7bc0a53ed9
当前提交
f143b900ff
@ -62,6 +62,9 @@ object AsrHelper : OfflineCmdListener {
|
||||
/** goToDecisionCenter 命中时的回调,由各 Activity 在 onResume/onPause 中注册/清空 */
|
||||
var onGoToDecisionCenter: ((action: RecognizeAction) -> Unit)? = null
|
||||
|
||||
/** goToTaskCenter 命中时的回调,由各 Activity 在 onResume/onPause 中注册/清空 */
|
||||
var onGoToTaskCenter: ((action: RecognizeAction) -> Unit)? = null
|
||||
|
||||
/** scene == "decision" 时直接用 ASR 文本发起对话,由 ChatActivity 注册 */
|
||||
var onDirectChat: ((text: String) -> Unit)? = null
|
||||
|
||||
@ -193,10 +196,10 @@ object AsrHelper : OfflineCmdListener {
|
||||
text = text,
|
||||
scence = scene,
|
||||
onSuccess = { action ->
|
||||
if (action.name == "goToDecisionCenter") {
|
||||
onGoToDecisionCenter?.invoke(action)
|
||||
} else {
|
||||
"需要跳转任务列表".showMessage()
|
||||
when (action.name) {
|
||||
"goToDecisionCenter" -> onGoToDecisionCenter?.invoke(action)
|
||||
"goToTaskCenter" -> onGoToTaskCenter?.invoke(action)
|
||||
else -> Log.d(TAG, "unhandled action: $action")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -44,5 +44,13 @@ data class RecognizeAction(
|
||||
)
|
||||
|
||||
data class RecognizeParams(
|
||||
val question: String,
|
||||
val question: String? = null,
|
||||
// goToTaskCenter params
|
||||
val dateRange: Int? = null,
|
||||
val dateTpye: Int? = null,
|
||||
val isOverdue: Int? = null,
|
||||
val keyword: String? = null,
|
||||
val taskType: String? = null,
|
||||
val tenantId: Int? = null,
|
||||
val userId: String? = null,
|
||||
)
|
||||
@ -2,6 +2,12 @@ package com.nova.brain.glass.model
|
||||
|
||||
import com.xuqm.base.adapter.BaseItem
|
||||
|
||||
data class TaskItem(val id: String): BaseItem() {
|
||||
data class TaskItem(
|
||||
val id: String,
|
||||
val taskType: String = "",
|
||||
val params: Map<String, String> = emptyMap(),
|
||||
val processStatus: String = "",
|
||||
val aiDescription: String = ""
|
||||
) : BaseItem() {
|
||||
var selected: Boolean = false
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import com.nova.brain.glass.model.RecognizeModel
|
||||
import com.nova.brain.glass.model.data.ChatData
|
||||
import com.nova.brain.glass.model.data.RecognizeData
|
||||
import com.nova.brain.glass.model.data.TaskListData
|
||||
import com.nova.brain.glass.model.TaskSearchResponse
|
||||
import com.nova.brain.glass.model.data.TopicData
|
||||
import com.nova.brain.glass.model.data.TopicModel
|
||||
import io.reactivex.Observable
|
||||
@ -33,6 +34,6 @@ interface Service {
|
||||
fun tbtopic(@Body body: TopicData): Observable<TopicModel>
|
||||
|
||||
@POST("/cbrain-gateway/cbrain-task-server/cbrain-task/task/glassesTaskSearch")
|
||||
fun glassesTaskSearch(@Body body: TaskListData): Observable<TopicModel>
|
||||
fun glassesTaskSearch(@Body body: TaskListData): Observable<TaskSearchResponse>
|
||||
|
||||
}
|
||||
@ -108,7 +108,7 @@ class ChatActivity : BaseListFormLayoutNormalActivity<ChatItem, ChatVM, Activity
|
||||
OfflineCmdServiceHelper.addOnLineListener(listener)
|
||||
AsrHelper.scene = "decision"
|
||||
AsrHelper.onGoToDecisionCenter = { action ->
|
||||
viewModel.demoPostSse(action.params.question)
|
||||
viewModel.demoPostSse(action.params.question!!)
|
||||
}
|
||||
AsrHelper.onDirectChat = { text ->
|
||||
viewModel.demoPostSse(text)
|
||||
|
||||
@ -9,6 +9,7 @@ import com.nova.brain.glass.databinding.ActivityTaskListBinding
|
||||
import com.nova.brain.glass.helper.OfflineCmdListener
|
||||
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
||||
import com.nova.brain.glass.model.TaskItem
|
||||
import com.nova.brain.glass.model.data.TaskListData
|
||||
import com.nova.brain.glass.viewmodel.TaskListVM
|
||||
import com.xuqm.base.adapter.BasePagedAdapter
|
||||
import com.xuqm.base.adapter.CommonPagedAdapter
|
||||
@ -73,6 +74,19 @@ class TaskListActivity :
|
||||
}
|
||||
}
|
||||
|
||||
override fun initData() {
|
||||
viewModel.searchParams = TaskListData(
|
||||
taskType = intent.getStringExtra("taskType") ?: "",
|
||||
keyword = intent.getStringExtra("keyword") ?: "",
|
||||
dateRange = intent.getIntExtra("dateRange", 0),
|
||||
dateType = intent.getIntExtra("dateType", 0),
|
||||
isOverdue = intent.getIntExtra("isOverdue", 2),
|
||||
tenantId = intent.getIntExtra("tenantId", 1),
|
||||
userId = intent.getStringExtra("userId") ?: ""
|
||||
)
|
||||
super.initData()
|
||||
}
|
||||
|
||||
private val offlineCmdListener = object : OfflineCmdListener {
|
||||
override fun onOfflineCmd(cmd: String) {
|
||||
runOnUiThread { dispatchVoiceCmd(cmd) }
|
||||
@ -182,10 +196,10 @@ class TaskListActivity :
|
||||
private val adapter = object : CommonPagedAdapter<TaskItem>(R.layout.item_task_list) {
|
||||
override fun convert(holder: ViewHolder, item: TaskItem, position: Int) {
|
||||
val displayPosition = (position - pageStartPosition + 1).coerceAtLeast(1)
|
||||
val title = "${displayPosition}. ${item.aiDescription}【${item.processStatus}】"
|
||||
holder
|
||||
.setText(R.id.tv_title, "${displayPosition}.[$position]张三提交的出差预算申请审核任务,从上海到北京,3月23开始3月24结束,预算金额¥1800元。【已逾期】")
|
||||
.setClickListener(R.id.tv_title
|
||||
) {
|
||||
.setText(R.id.tv_title, title)
|
||||
.setClickListener(R.id.tv_title) {
|
||||
openTask(position)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import com.nova.brain.glass.helper.AsrHelper
|
||||
import com.nova.brain.glass.helper.IntentRecognizeHelper
|
||||
import com.nova.brain.glass.helper.OfflineCmdListener
|
||||
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
||||
import com.nova.brain.glass.model.RecognizeParams
|
||||
import com.nova.brain.glass.viewmodel.WelcomeVM
|
||||
import com.xuqm.base.ui.BaseActivity
|
||||
|
||||
@ -59,13 +60,15 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
||||
IntentRecognizeHelper.recognize(
|
||||
text = "查看我的任务列表?",
|
||||
onSuccess = { action ->
|
||||
if (action.name == "goToDecisionCenter") {
|
||||
startActivity(
|
||||
when (action.name) {
|
||||
"goToDecisionCenter" -> startActivity(
|
||||
Intent(this, ChatActivity::class.java)
|
||||
.putExtra("question", action.params.question)
|
||||
)
|
||||
} else {
|
||||
Log.d("WelcomeActivity", "triggerRecognize onSuccess: $action")
|
||||
"goToTaskCenter" -> startActivity(
|
||||
intentForTaskList(action.params)
|
||||
)
|
||||
else -> Log.d("WelcomeActivity", "triggerRecognize onSuccess: $action")
|
||||
}
|
||||
},
|
||||
onComplete = {
|
||||
@ -101,14 +104,29 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
||||
.putExtra("question", action.params.question)
|
||||
)
|
||||
}
|
||||
AsrHelper.onGoToTaskCenter = { action ->
|
||||
startActivity(intentForTaskList(action.params))
|
||||
}
|
||||
}
|
||||
|
||||
private fun intentForTaskList(params: RecognizeParams) =
|
||||
Intent(this, TaskListActivity::class.java).apply {
|
||||
putExtra("taskType", params.taskType ?: "")
|
||||
putExtra("keyword", params.keyword ?: "")
|
||||
putExtra("dateRange", params.dateRange ?: 0)
|
||||
putExtra("dateType", params.dateTpye ?: 0)
|
||||
putExtra("isOverdue", params.isOverdue ?: 2)
|
||||
putExtra("tenantId", params.tenantId ?: 1)
|
||||
putExtra("userId", params.userId ?: "")
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
OfflineCmdServiceHelper.removeOnLineListener(offlineCmdListener)
|
||||
OfflineCmdServiceHelper.removeListenerWelcome()
|
||||
dotsHandler.removeCallbacks(dotsRunnable)
|
||||
AsrHelper.onGoToDecisionCenter = null
|
||||
AsrHelper.onGoToTaskCenter = null
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
@ -1,18 +1,40 @@
|
||||
package com.nova.brain.glass.viewmodel
|
||||
|
||||
import com.nova.brain.glass.MyApplication
|
||||
import com.nova.brain.glass.model.TaskItem
|
||||
import com.nova.brain.glass.model.data.TaskListData
|
||||
import com.nova.brain.glass.repository.Service
|
||||
import com.xuqm.base.di.manager.HttpManager
|
||||
import com.xuqm.base.viewmodel.BaseListViewModel
|
||||
import com.xuqm.base.viewmodel.callback.Response
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
class TaskListVM: BaseListViewModel<TaskItem>() {
|
||||
override fun loadData(
|
||||
page: Int,
|
||||
onResponse: Response<TaskItem>
|
||||
) {
|
||||
onResponse.onResponse(arrayListOf<TaskItem>().apply {
|
||||
for (i in 0..10) {
|
||||
add(TaskItem(i.toString()))
|
||||
}
|
||||
})
|
||||
class TaskListVM : BaseListViewModel<TaskItem>() {
|
||||
|
||||
var searchParams: TaskListData =
|
||||
TaskListData(taskType = "", keyword = "", dateRange = 0, dateType = 0)
|
||||
|
||||
override fun loadData(page: Int, onResponse: Response<TaskItem>) {
|
||||
add(
|
||||
HttpManager.getApi(MyApplication.appComponent1, Service::class.java)
|
||||
.glassesTaskSearch(searchParams)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ response ->
|
||||
val items = response.data?.list?.map {
|
||||
TaskItem(
|
||||
id = it.id,
|
||||
taskType = it.taskType,
|
||||
params = it.params,
|
||||
processStatus = it.processStatus,
|
||||
aiDescription = it.aiDescription
|
||||
)
|
||||
} ?: emptyList()
|
||||
onResponse.onResponse(ArrayList(items))
|
||||
}, {
|
||||
onResponse.onResponse(arrayListOf())
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
正在加载...
在新工单中引用
屏蔽一个用户