本周完成内容:
1.导航界面的流式输出与历史对话查询功能;

2.适配新的会话历史查询api,增加agent_type参数,使得三个阶段的对话历史可以分开查询;

3.康复界面搭建和api适配。
前两项任务不再赘述。
康复界面设计如下,上部分使用一个镶嵌在抽屉组件里的日历组件来展示日程、每一天的日程详情,抽屉可以收起以展示更多对话;中间部分使用前几次博客中提到的ChatScreen组件展示对话;下部分使用前面搭建的InputBox组件来供用户输入消息和多模态文件:
//可折叠日历组件
AnimatedVisibility(
visible = uiState.showCalendar,
enter = expandVertically(),
exit = shrinkVertically()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(fraction = 0.4f)
.background(colorResource(id = R.color.primaryContainer))
) {
CalendarPanel(
schedules = allSchedules,
selectedDate = uiState.selectedDate,
onSelectDate = { viewModel.selectDate(it) },
onShowDetail = { viewModel.showScheduleDetail(it) }
)
}
}



其他功能与前几期博客实现的差不太多,这里主要看一下批量添加功能是如何实现的:
批量添加模式的有关参数:
val isBatchMode: Boolean = false, // 是否开启批量模式
val batchEveryNDays: Int = 1, // 每隔N天执行一次
val batchTotalTimes: Int = 7, // 总执行次数
val batchTimesPerDay: Int = 1, // 每天执行次数
val batchHourSlots: List<Int> = listOf(9), // 每个时段的小时列表
val batchMinuteSlots: List<Int> = listOf(0) // 每个时段的分钟列表
使用这些参数在前端通过数次调用api手动完成批量添加日程:
private fun submitBatchSchedules(state: RehabilitationUiState) {
val taskType = state.newScheduleTaskType
val taskContent = state.newScheduleContent.trim()
val startDate = runCatching { LocalDate.parse(state.newScheduleDate, DateTimeFormatter.ISO_LOCAL_DATE) }.getOrNull()
if (startDate == null) { _uiState.update { it.copy(errorMessage = "日期格式错误") }; return }
val everyN = state.batchEveryNDays
val totalTimes = state.batchTotalTimes
val timesPerDay = state.batchTimesPerDay
val slots = state.batchHourSlots
val totalRequests = totalTimes * timesPerDay
Log.d(TAG, "batch: totalRequests=$totalRequests, every${everyN}天, ${totalTimes}次, 每天${timesPerDay}次")
_uiState.update { it.copy(isAddingSchedule = true, errorMessage = null) }
var completed = 0
for (batchIdx in 0 until totalTimes) {
val date = startDate.plusDays(batchIdx.toLong() * everyN.toLong())
for (slotIdx in 0 until timesPerDay) {
val slot = if (slotIdx < slots.size) slots[slotIdx] else IntPair(8, 0)
val executeTime = date.format(DateTimeFormatter.ISO_LOCAL_DATE) + "T" + slot.toTimeStr()
val request = RehabScheduleAddRequest(taskType = taskType, taskContent = taskContent, executeTime = executeTime)
val call = NetworkUtil.request(
ApiService.api.rehabAddSchedule(request),
object : NetworkCallback<BaseResponse<RehabSchedule>> {
override fun onSuccess(data: BaseResponse<RehabSchedule>) {
completed++
if (data.code == "0" && data.data != null) {
val schedules = _uiState.value.schedules.toMutableList()
schedules.add(data.data)
_uiState.update { it.copy(schedules = schedules) }
}
if (completed >= totalRequests) finishBatchAdd()
}
override fun onFailure(error: String) {
completed++
if (completed >= totalRequests) finishBatchAdd()
}
}
)
pendingCalls.add(call)
}
}
}
从logcat的输出可以看出这种实现方案有效:

不过最佳的方案还是在后端就提供方法接口。
目前项目还存在导航推荐医院api概率超时、康复对话api稳定超时、康复对话生成康复计划逻辑不清晰等问题,需要前后端进行联调。此外还缺少一个查询日程的api。这些也是下周的工作内容。

2412

被折叠的 条评论
为什么被折叠?



