山东大学创新实训项目个人博客——第七篇

本周完成内容:
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。这些也是下周的工作内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值