From 7f4c3ffb9fe1969ad55599715f37408e49328b95 Mon Sep 17 00:00:00 2001 From: iammm0 Date: Thu, 22 Jan 2026 17:58:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=89=A9=E5=B1=95=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E5=B1=82API=E5=92=8CWebSocket=E6=B6=88=E6=81=AF=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 扩展ApiService添加回忆录状态和任务状态接口 - 优化WebSocketClient连接管理 - 增强WebSocketMessage消息类型支持 - 更新MemoirModels数据模型 --- .../com/huaga/life_echo/network/ApiService.kt | 42 ++++++++++++- .../life_echo/network/WebSocketClient.kt | 15 +++-- .../life_echo/network/WebSocketMessage.kt | 58 +++++++++++++++++- .../life_echo/network/models/MemoirModels.kt | 59 +++++++++++++++---- 4 files changed, 155 insertions(+), 19 deletions(-) diff --git a/app-android/app/src/main/java/com/huaga/life_echo/network/ApiService.kt b/app-android/app/src/main/java/com/huaga/life_echo/network/ApiService.kt index 7bf177c..a2a5b0b 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/network/ApiService.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/network/ApiService.kt @@ -95,7 +95,6 @@ class ApiService( return try { val response = client.get("$BASE_URL/api/chapters") { contentType(ContentType.Application.Json) - parameter("user_id", userId) } Result.success(response.body()) } catch (e: Exception) { @@ -261,5 +260,46 @@ class ApiService( Result.success(Unit) } } + + // ==================== 回忆录状态相关API ==================== + + suspend fun getMemoirState(): Result { + return try { + val response = client.get("$BASE_URL/api/memoir-state") { + contentType(ContentType.Application.Json) + } + Result.success(response.body()) + } catch (e: Exception) { + Result.failure(Exception("获取回忆录状态失败: ${e.message}", e)) + } + } + + // ==================== 任务状态相关API ==================== + + suspend fun getTasksStatus(): Result { + return try { + val response = client.get("$BASE_URL/api/tasks/status") { + contentType(ContentType.Application.Json) + } + Result.success(response.body()) + } catch (e: Exception) { + Result.failure(Exception("获取任务状态失败: ${e.message}", e)) + } + } + + suspend fun clearTasks(): Result { + return try { + val response = client.delete("$BASE_URL/api/tasks/clear") { + contentType(ContentType.Application.Json) + } + if (response.status.isSuccess()) { + Result.success(Unit) + } else { + Result.failure(Exception("清除任务失败: ${response.status}")) + } + } catch (e: Exception) { + Result.failure(Exception("清除任务失败: ${e.message}", e)) + } + } } diff --git a/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketClient.kt b/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketClient.kt index 8dc9ef9..d0e1a4a 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketClient.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketClient.kt @@ -11,6 +11,10 @@ import io.ktor.http.* import kotlinx.coroutines.flow.* import kotlinx.coroutines.* import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.put +import kotlinx.serialization.json.putJsonObject class WebSocketClient { private val client = HttpClient(Android) { @@ -74,7 +78,7 @@ class WebSocketClient { sendMessage(WebSocketMessage( type = MessageType.connect, conversation_id = conversationId, - data = mapOf("status" to "connected") + data = buildJsonObject { put("status", JsonPrimitive("connected")) } )) } catch (e: Exception) { @@ -118,7 +122,7 @@ class WebSocketClient { sendMessage(WebSocketMessage( type = MessageType.audio_chunk, conversation_id = conversationId, - data = mapOf("audio_base64" to base64Audio) + data = buildJsonObject { put("audio_base64", JsonPrimitive(base64Audio)) } )) } @@ -126,14 +130,15 @@ class WebSocketClient { sendMessage(WebSocketMessage( type = MessageType.text, conversation_id = conversationId, - data = mapOf("text" to text) + data = buildJsonObject { put("text", JsonPrimitive(text)) } )) } suspend fun sendEndConversation(conversationId: String) { sendMessage(WebSocketMessage( type = MessageType.end_conversation, - conversation_id = conversationId + conversation_id = conversationId, + data = buildJsonObject { } )) } @@ -146,7 +151,7 @@ class WebSocketClient { sendMessage(WebSocketMessage( type = MessageType.cancel_generation, conversation_id = conversationId, - data = mapOf("action" to "cancel") + data = buildJsonObject { put("action", JsonPrimitive("cancel")) } )) } diff --git a/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketMessage.kt b/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketMessage.kt index 970423e..b961b56 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketMessage.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/network/WebSocketMessage.kt @@ -1,6 +1,9 @@ package com.huaga.life_echo.network import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonObject @Serializable enum class MessageType { @@ -23,7 +26,58 @@ enum class MessageType { data class WebSocketMessage( val type: MessageType, val conversation_id: String? = null, - val data: Map = emptyMap(), + val data: JsonObject = buildJsonObject { }, val timestamp: String? = null -) +) { + /** + * 获取data中的字符串值 + */ + fun getString(key: String): String? { + return data[key]?.let { + if (it is JsonPrimitive) { + try { + it.content + } catch (e: Exception) { + null + } + } else { + null + } + } + } + + /** + * 获取data中的整数值 + */ + fun getInt(key: String): Int? { + return data[key]?.let { + if (it is JsonPrimitive) { + try { + it.content.toIntOrNull() + } catch (e: Exception) { + null + } + } else { + null + } + } + } + + /** + * 获取data中的布尔值 + */ + fun getBoolean(key: String): Boolean? { + return data[key]?.let { + if (it is JsonPrimitive) { + try { + it.content.toBooleanStrictOrNull() + } catch (e: Exception) { + null + } + } else { + null + } + } + } +} diff --git a/app-android/app/src/main/java/com/huaga/life_echo/network/models/MemoirModels.kt b/app-android/app/src/main/java/com/huaga/life_echo/network/models/MemoirModels.kt index f731b8b..0cf1405 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/network/models/MemoirModels.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/network/models/MemoirModels.kt @@ -6,30 +6,31 @@ import kotlinx.serialization.Serializable * 回忆录相关的数据模型 */ -// 书籍信息DTO(扩展版) +// 书籍信息DTO(匹配服务器格式) @Serializable data class BookDto( val id: String, - val userId: String, val title: String, - val subtitle: String? = null, - val totalPages: Int, - val totalWords: Int, - val updatedAt: Long, - val lastUpdatedAt: Long? = null + val total_pages: Int? = null, + val total_words: Int? = null, + val cover_image_url: String? = null, + val has_update: Boolean = false, + val last_update_chapter_id: String? = null ) -// 章节信息DTO(扩展版) +// 章节信息DTO(匹配服务器格式) @Serializable data class ChapterDto( val id: String, val title: String, val content: String, - val orderIndex: Int, + val order_index: Int, val status: String, // "draft", "partial", "completed" val category: String, - val pageCount: Int? = null, - val updatedAt: Long? = null + val images: List = emptyList(), + val updated_at: String? = null, + val is_new: Boolean = false, + val source_segments: List = emptyList() ) // 章节内容详情DTO @@ -45,3 +46,39 @@ data class ChapterContentDto( val updatedAt: Long, val quotes: List = emptyList() // 引用内容列表 ) + +// 回忆录状态DTO +@Serializable +data class MemoirStateDto( + val current_stage: String, + val covered_stages: List = emptyList(), + val slots: Map> = emptyMap() +) + +@Serializable +data class SlotInfo( + val snippet: String? = null, + val filled: Boolean = false +) + +// 任务状态DTO +@Serializable +data class TasksStatusDto( + val total: Int, + val pending: Int, + val running: Int, + val success: Int, + val failure: Int, + val all_completed: Boolean, + val tasks: List = emptyList() +) + +@Serializable +data class TaskInfoDto( + val task_id: String, + val task_type: String = "memoir", + val status: String, // "pending", "running", "success", "failure" + val created_at: String? = null, + val updated_at: String? = null, + val result: Map? = null +)