From 2b1f5fb3d9d7622a399b92ea07ab672278b00aaf Mon Sep 17 00:00:00 2001 From: yibo Date: Wed, 10 Jun 2026 23:53:16 +0800 Subject: [PATCH] feat(crm): 人物档案页真实最近联系时间 --- lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/PersonProfileScreen.kt | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/PersonProfileScreen.kt b/lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/PersonProfileScreen.kt index cb12201..0525bb9 100644 --- a/lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/PersonProfileScreen.kt +++ b/lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/PersonProfileScreen.kt @@ -111,6 +111,14 @@ internal fun PersonProfileScreen( .collectAsState(initial = emptyList()) val mentionScanning by vm.mentionScanning.collectAsState() + // 真实最近联系时间:微信消息 / 被提到 / 本人录音,取三者最近值 + val lastContactTs = remember(messages, mentioned, audio) { + val msgTs = messages.maxOfOrNull { it.createTime } ?: 0L + val mentionTs = mentioned.maxOfOrNull { it.startTs } ?: 0L + val audioTs = audio.maxOfOrNull { it.startTs } ?: 0L + maxOf(msgTs, mentionTs, audioTs) + } + var bindVoice by remember { mutableStateOf(false) } var recordVoice by remember { mutableStateOf(false) } var editProfile by remember { mutableStateOf(false) } @@ -146,7 +154,7 @@ internal fun PersonProfileScreen( item(key = "hero") { person?.let { p -> ProfileHero( - p, speakers, + p, speakers, lastContactTs, onBind = { bindVoice = true }, onRecordVoice = { vm.resetVoiceEnroll(); recordVoice = true }, onEnrich = { vm.enrichImpression(personId) }, @@ -319,6 +327,7 @@ private fun EnrollVoiceDialog( private fun ProfileHero( p: Person, speakers: List, + lastContactTs: Long, onBind: () -> Unit, onRecordVoice: () -> Unit, onEnrich: () -> Unit, @@ -406,6 +415,43 @@ private fun ProfileHero( TextButton(onClick = onEnrich, contentPadding = pad) { Text(if (p.impression == null) "🧠 AI印象" else "🧠 重生成", style = MaterialTheme.typography.labelMedium) } } + // 最近联系时间行 + if (lastContactTs > 0L) { + val days = ((System.currentTimeMillis() - lastContactTs) / 86_400_000L).toInt() + val timeLabel = when { + days == 0 -> "今天" + days == 1 -> "昨天" + days < 30 -> "${days} 天前" + days < 365 -> "${days / 30} 个月前" + else -> "${days / 365} 年前" + } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(6.dp), + modifier = Modifier.padding(top = 2.dp), + ) { + Text( + "最近联系 $timeLabel", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + if (days > 30) { + val staleLabel = if (days < 365) "超过 ${days / 30} 个月未联系" else "超过 ${days / 365} 年未联系" + Surface( + shape = androidx.compose.foundation.shape.RoundedCornerShape(4.dp), + color = MaterialTheme.colorScheme.errorContainer, + ) { + Text( + "⚠ $staleLabel", + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.onErrorContainer, + modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp), + ) + } + } + } + } + // 「关于/简历」已挪到下方「简历」tab(hero 保持紧凑,给 tab 内容腾出整屏)。 Spacer(Modifier.height(6.dp)) } -- libgit2 0.21.4