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 中注册/清空 */
|
/** goToDecisionCenter 命中时的回调,由各 Activity 在 onResume/onPause 中注册/清空 */
|
||||||
var onGoToDecisionCenter: ((action: RecognizeAction) -> Unit)? = null
|
var onGoToDecisionCenter: ((action: RecognizeAction) -> Unit)? = null
|
||||||
|
|
||||||
|
/** goToTaskCenter 命中时的回调,由各 Activity 在 onResume/onPause 中注册/清空 */
|
||||||
|
var onGoToTaskCenter: ((action: RecognizeAction) -> Unit)? = null
|
||||||
|
|
||||||
/** scene == "decision" 时直接用 ASR 文本发起对话,由 ChatActivity 注册 */
|
/** scene == "decision" 时直接用 ASR 文本发起对话,由 ChatActivity 注册 */
|
||||||
var onDirectChat: ((text: String) -> Unit)? = null
|
var onDirectChat: ((text: String) -> Unit)? = null
|
||||||
|
|
||||||
@ -193,10 +196,10 @@ object AsrHelper : OfflineCmdListener {
|
|||||||
text = text,
|
text = text,
|
||||||
scence = scene,
|
scence = scene,
|
||||||
onSuccess = { action ->
|
onSuccess = { action ->
|
||||||
if (action.name == "goToDecisionCenter") {
|
when (action.name) {
|
||||||
onGoToDecisionCenter?.invoke(action)
|
"goToDecisionCenter" -> onGoToDecisionCenter?.invoke(action)
|
||||||
} else {
|
"goToTaskCenter" -> onGoToTaskCenter?.invoke(action)
|
||||||
"需要跳转任务列表".showMessage()
|
else -> Log.d(TAG, "unhandled action: $action")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -44,5 +44,13 @@ data class RecognizeAction(
|
|||||||
)
|
)
|
||||||
|
|
||||||
data class RecognizeParams(
|
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
|
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
|
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.ChatData
|
||||||
import com.nova.brain.glass.model.data.RecognizeData
|
import com.nova.brain.glass.model.data.RecognizeData
|
||||||
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.data.TopicData
|
import com.nova.brain.glass.model.data.TopicData
|
||||||
import com.nova.brain.glass.model.data.TopicModel
|
import com.nova.brain.glass.model.data.TopicModel
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
@ -33,6 +34,6 @@ interface Service {
|
|||||||
fun tbtopic(@Body body: TopicData): Observable<TopicModel>
|
fun tbtopic(@Body body: TopicData): Observable<TopicModel>
|
||||||
|
|
||||||
@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<TopicModel>
|
fun glassesTaskSearch(@Body body: TaskListData): Observable<TaskSearchResponse>
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ class ChatActivity : BaseListFormLayoutNormalActivity<ChatItem, ChatVM, Activity
|
|||||||
OfflineCmdServiceHelper.addOnLineListener(listener)
|
OfflineCmdServiceHelper.addOnLineListener(listener)
|
||||||
AsrHelper.scene = "decision"
|
AsrHelper.scene = "decision"
|
||||||
AsrHelper.onGoToDecisionCenter = { action ->
|
AsrHelper.onGoToDecisionCenter = { action ->
|
||||||
viewModel.demoPostSse(action.params.question)
|
viewModel.demoPostSse(action.params.question!!)
|
||||||
}
|
}
|
||||||
AsrHelper.onDirectChat = { text ->
|
AsrHelper.onDirectChat = { text ->
|
||||||
viewModel.demoPostSse(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.OfflineCmdListener
|
||||||
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
import com.nova.brain.glass.helper.OfflineCmdServiceHelper
|
||||||
import com.nova.brain.glass.model.TaskItem
|
import com.nova.brain.glass.model.TaskItem
|
||||||
|
import com.nova.brain.glass.model.data.TaskListData
|
||||||
import com.nova.brain.glass.viewmodel.TaskListVM
|
import com.nova.brain.glass.viewmodel.TaskListVM
|
||||||
import com.xuqm.base.adapter.BasePagedAdapter
|
import com.xuqm.base.adapter.BasePagedAdapter
|
||||||
import com.xuqm.base.adapter.CommonPagedAdapter
|
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 {
|
private val offlineCmdListener = object : OfflineCmdListener {
|
||||||
override fun onOfflineCmd(cmd: String) {
|
override fun onOfflineCmd(cmd: String) {
|
||||||
runOnUiThread { dispatchVoiceCmd(cmd) }
|
runOnUiThread { dispatchVoiceCmd(cmd) }
|
||||||
@ -182,10 +196,10 @@ class TaskListActivity :
|
|||||||
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)
|
||||||
|
val title = "${displayPosition}. ${item.aiDescription}【${item.processStatus}】"
|
||||||
holder
|
holder
|
||||||
.setText(R.id.tv_title, "${displayPosition}.[$position]张三提交的出差预算申请审核任务,从上海到北京,3月23开始3月24结束,预算金额¥1800元。【已逾期】")
|
.setText(R.id.tv_title, title)
|
||||||
.setClickListener(R.id.tv_title
|
.setClickListener(R.id.tv_title) {
|
||||||
) {
|
|
||||||
openTask(position)
|
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.IntentRecognizeHelper
|
||||||
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.RecognizeParams
|
||||||
import com.nova.brain.glass.viewmodel.WelcomeVM
|
import com.nova.brain.glass.viewmodel.WelcomeVM
|
||||||
import com.xuqm.base.ui.BaseActivity
|
import com.xuqm.base.ui.BaseActivity
|
||||||
|
|
||||||
@ -59,13 +60,15 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
|||||||
IntentRecognizeHelper.recognize(
|
IntentRecognizeHelper.recognize(
|
||||||
text = "查看我的任务列表?",
|
text = "查看我的任务列表?",
|
||||||
onSuccess = { action ->
|
onSuccess = { action ->
|
||||||
if (action.name == "goToDecisionCenter") {
|
when (action.name) {
|
||||||
startActivity(
|
"goToDecisionCenter" -> startActivity(
|
||||||
Intent(this, ChatActivity::class.java)
|
Intent(this, ChatActivity::class.java)
|
||||||
.putExtra("question", action.params.question)
|
.putExtra("question", action.params.question)
|
||||||
)
|
)
|
||||||
} else {
|
"goToTaskCenter" -> startActivity(
|
||||||
Log.d("WelcomeActivity", "triggerRecognize onSuccess: $action")
|
intentForTaskList(action.params)
|
||||||
|
)
|
||||||
|
else -> Log.d("WelcomeActivity", "triggerRecognize onSuccess: $action")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onComplete = {
|
onComplete = {
|
||||||
@ -101,6 +104,20 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
|||||||
.putExtra("question", action.params.question)
|
.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() {
|
override fun onPause() {
|
||||||
@ -109,6 +126,7 @@ class WelcomeActivity : BaseActivity<ActivityWelcomeBinding>() {
|
|||||||
OfflineCmdServiceHelper.removeListenerWelcome()
|
OfflineCmdServiceHelper.removeListenerWelcome()
|
||||||
dotsHandler.removeCallbacks(dotsRunnable)
|
dotsHandler.removeCallbacks(dotsRunnable)
|
||||||
AsrHelper.onGoToDecisionCenter = null
|
AsrHelper.onGoToDecisionCenter = null
|
||||||
|
AsrHelper.onGoToTaskCenter = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
|||||||
@ -1,18 +1,40 @@
|
|||||||
package com.nova.brain.glass.viewmodel
|
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.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.BaseListViewModel
|
||||||
import com.xuqm.base.viewmodel.callback.Response
|
import com.xuqm.base.viewmodel.callback.Response
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
class TaskListVM: BaseListViewModel<TaskItem>() {
|
class TaskListVM : BaseListViewModel<TaskItem>() {
|
||||||
override fun loadData(
|
|
||||||
page: Int,
|
var searchParams: TaskListData =
|
||||||
onResponse: Response<TaskItem>
|
TaskListData(taskType = "", keyword = "", dateRange = 0, dateType = 0)
|
||||||
) {
|
|
||||||
onResponse.onResponse(arrayListOf<TaskItem>().apply {
|
override fun loadData(page: Int, onResponse: Response<TaskItem>) {
|
||||||
for (i in 0..10) {
|
add(
|
||||||
add(TaskItem(i.toString()))
|
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())
|
||||||
})
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
正在加载...
在新工单中引用
屏蔽一个用户