From 9077605da60be8a654a38b8f6ad110566120d797 Mon Sep 17 00:00:00 2001 From: WaterRain <109326062+CATMIAOZHI@users.noreply.github.com> Date: Tue, 7 Jul 2026 21:46:59 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Ollama=E8=AF=A6=E6=83=85=E9=A1=B5?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A8=A1=E5=9E=8B=E8=B0=83=E7=94=A8=E6=AC=A1?= =?UTF-8?q?=E6=95=B0=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 OllamaUsageCard 的 5h 和每周用量窗口进度条下方, 新增模型级调用次数列表(按次数降序,品牌粉标色)。 数据来自已有的 extras[session.models]/[weekly.models], 新增 parseModelRequests() 解析 + ModelRequestList Composable。 仅改详情页,首页 Dashboard 未动。 --- .../ui/servicedetail/ServiceDetailScreen.kt | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt b/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt index 3b3537f..0ad12a2 100644 --- a/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt +++ b/app/src/main/java/com/rainy/token/ui/servicedetail/ServiceDetailScreen.kt @@ -391,7 +391,7 @@ private fun UsageWindowRow(label: String, pct: Int?, resetInSec: Long?) { } /** - * Ollama Pro 专属:5h + 每周用量窗口卡。 + * Ollama Pro 专属:5h + 每周用量窗口卡 + 模型级调用次数。 */ @Composable private fun OllamaUsageCard(state: State) { @@ -404,6 +404,9 @@ private fun OllamaUsageCard(state: State) { val extras = balance?.extras ?: return val plan = extras["plan"] ?: "—" + val sessionModels = parseModelRequests(extras["session.models"]) + val weeklyModels = parseModelRequests(extras["weekly.models"]) + Card( modifier = Modifier.fillMaxWidth(), shape = RoundedCornerShape(20.dp), @@ -431,6 +434,10 @@ private fun OllamaUsageCard(state: State) { pct = extras["session.pct"]?.toFloatOrNull()?.toInt(), resetInSec = extras["session.resetAt"]?.toLongOrNull()?.let { (it - System.currentTimeMillis()) / 1000 }?.takeIf { it > 0 } ) + if (sessionModels.isNotEmpty()) { + Spacer(modifier = Modifier.height(10.dp)) + ModelRequestList(models = sessionModels) + } Spacer(modifier = Modifier.height(14.dp)) HorizontalDivider(color = MaterialTheme.colorScheme.outlineVariant) Spacer(modifier = Modifier.height(14.dp)) @@ -439,6 +446,60 @@ private fun OllamaUsageCard(state: State) { pct = extras["weekly.pct"]?.toFloatOrNull()?.toInt(), resetInSec = extras["weekly.resetAt"]?.toLongOrNull()?.let { (it - System.currentTimeMillis()) / 1000 }?.takeIf { it > 0 } ) + if (weeklyModels.isNotEmpty()) { + Spacer(modifier = Modifier.height(10.dp)) + ModelRequestList(models = weeklyModels) + } + } + } +} + +/** + * 解析 extras 中的模型调用次数字符串。 + * 格式: "model1,count1;model2,count2" + */ +private fun parseModelRequests(raw: String?): List> { + if (raw.isNullOrBlank()) return emptyList() + return raw.split(";").mapNotNull { entry -> + val parts = entry.split(",") + if (parts.size == 2) { + val model = parts[0].trim() + val count = parts[1].trim().toIntOrNull() + if (model.isNotBlank() && count != null) model to count else null + } else null + } +} + +/** + * 模型级调用次数列表。 + * 每行显示模型名 + 调用次数,按次数降序排列。 + */ +@Composable +private fun ModelRequestList(models: List>) { + Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { + Text( + text = "模型调用次数", + style = MaterialTheme.typography.labelSmall, + color = inkMuted() + ) + models.sortedByDescending { it.second }.forEach { (model, count) -> + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = model, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.weight(1f) + ) + Text( + text = count.toString(), + style = MaterialTheme.typography.bodySmall, + fontWeight = FontWeight.SemiBold, + color = StrawberryPink + ) + } } } }