package com.nova.brain.glass.viewmodel import android.os.Handler import android.os.Looper import androidx.lifecycle.MutableLiveData import com.nova.brain.glass.model.ChatItem import com.nova.brain.glass.model.ChatModel import com.nova.brain.glass.model.ChatModel1 import com.nova.brain.glass.model.data.ChatData import com.nova.brain.glass.repository.Service import com.xuqm.base.common.GsonImplHelp import com.xuqm.base.common.LogHelper import com.xuqm.base.di.manager.HttpManager import com.xuqm.base.viewmodel.BaseListViewModel import com.xuqm.base.viewmodel.callback.Response import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers class ChatVM : BaseListViewModel() { val result = MutableLiveData() val loading = MutableLiveData() val chatItems: MutableList = mutableListOf() private var currentTask: Disposable? = null private var itemIdCounter = 0 private var dataSourceReady = false private val mainHandler = Handler(Looper.getMainLooper()) override fun loadData(page: Int, onResponse: Response) { dataSourceReady = true if (page == 0) { onResponse.onResponse(ArrayList(chatItems)) } else { onResponse.onResponse(ArrayList()) } } fun demoPostSse(question: String) { currentTask?.dispose() currentTask = null val itemId = itemIdCounter++ chatItems.add(ChatItem(itemId, question, "")) if (dataSourceReady) invalidate() loading.postValue(true) currentTask = HttpManager.getApi(Service::class.java).chat(ChatData(question)) .subscribeOn(Schedulers.io()) .subscribe({ body -> var content = "" body.charStream().buffered().use { reader -> try { var line: String? while (reader.readLine().also { line = it } != null) { val l = line!! if (l.isNotEmpty()) { if (l.trimStart().startsWith("<")) { // HTML 响应(隧道断开),移除占位项并在主线程用相同问题重试 mainHandler.post { if (chatItems.isNotEmpty()) chatItems.removeAt(chatItems.size - 1) demoPostSse(question) } loading.postValue(false) return@use } val json = if (l.startsWith("data:")) l.removePrefix("data:").trim() else l val model = GsonImplHelp.get().toObject(json, ChatModel::class.java) if (model.type == null) { loading.postValue(false) val msg = model.msg ?: json val lastIndex = chatItems.size - 1 if (lastIndex >= 0) { chatItems[lastIndex].content = msg notifyItem(lastIndex) } result.postValue(msg) return@use } if (model.role != "assistant" || model.type != "string") continue val model1 = GsonImplHelp.get().toObject(json, ChatModel1::class.java) content += model1.data val lastIndex = chatItems.size - 1 if (lastIndex >= 0) { chatItems[lastIndex].content = content notifyItem(lastIndex) } result.postValue(content) } } } catch (e: Exception) { LogHelper.e(">>>>11", e) loading.postValue(false) val errMsg = "AI反馈异常: ${e.message}" val lastIndex = chatItems.size - 1 if (lastIndex >= 0) { chatItems[lastIndex].content = errMsg notifyItem(lastIndex) } result.postValue(errMsg) } } loading.postValue(false) }, { e -> LogHelper.e(">>>>22", e) loading.postValue(false) result.postValue("AI反馈异常: ${e.message}") }) currentTask?.also { add(it) } } }