From 80ebddfc13b3ffd0e41002d909801c6248659e9e Mon Sep 17 00:00:00 2001 From: yovinchen Date: Thu, 5 Dec 2024 15:51:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=86=E7=B1=BB=E5=88=AB=E9=A5=BC?= =?UTF-8?q?=E5=9B=BE=E6=B7=BB=E5=8A=A0=E5=88=B0=E6=88=90=E5=91=98=E8=AF=A6?= =?UTF-8?q?=E7=BB=86=E4=BF=A1=E6=81=AF=E5=B1=8F=E5=B9=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在DeliverDetailView模型中添加类别数据状态流 - 从成员视图访问时,在DeliverDetailScreen中显示饼图 - 计算并显示会员记录的类别分布 --- .../ui/screen/MemberDetailScreen.kt | 48 ++++++++++++++++--- .../viewmodel/MemberDetailViewModel.kt | 17 +++++-- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/yovinchen/bookkeeping/ui/screen/MemberDetailScreen.kt b/app/src/main/java/com/yovinchen/bookkeeping/ui/screen/MemberDetailScreen.kt index 4d145f9..9b055bd 100644 --- a/app/src/main/java/com/yovinchen/bookkeeping/ui/screen/MemberDetailScreen.kt +++ b/app/src/main/java/com/yovinchen/bookkeeping/ui/screen/MemberDetailScreen.kt @@ -33,6 +33,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.yovinchen.bookkeeping.data.Record import com.yovinchen.bookkeeping.model.AnalysisType import com.yovinchen.bookkeeping.model.TransactionType +import com.yovinchen.bookkeeping.ui.components.CategoryPieChart import com.yovinchen.bookkeeping.ui.components.RecordItem import com.yovinchen.bookkeeping.viewmodel.MemberDetailViewModel import java.text.NumberFormat @@ -53,7 +54,8 @@ fun MemberDetailScreen( ) { val records by viewModel.memberRecords.collectAsState(initial = emptyList()) val totalAmount by viewModel.totalAmount.collectAsState(initial = 0.0) - + val categoryData by viewModel.categoryData.collectAsState(initial = emptyList()) + LaunchedEffect(memberName, category, startMonth, endMonth, analysisType) { viewModel.loadMemberRecords( memberName = memberName, @@ -99,24 +101,58 @@ fun MemberDetailScreen( ) { Column( modifier = Modifier - .padding(16.dp), - horizontalAlignment = Alignment.CenterHorizontally + .fillMaxWidth() + .padding(16.dp) ) { Text( - text = if (records.isNotEmpty() && records.first().type == TransactionType.INCOME) "总收入" else "总支出", - style = MaterialTheme.typography.titleMedium + text = "总金额", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold ) Spacer(modifier = Modifier.height(8.dp)) Text( text = NumberFormat.getCurrencyInstance(Locale.CHINA) .format(totalAmount), style = MaterialTheme.typography.headlineMedium, - fontWeight = FontWeight.Bold + color = MaterialTheme.colorScheme.primary ) } } } + // 当从成员视图进入时显示饼图 + if (category.isEmpty()) { + item { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 4.dp) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Text( + text = "分类统计", + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Bold + ) + Spacer(modifier = Modifier.height(16.dp)) + CategoryPieChart( + categoryData = categoryData, + memberData = emptyList(), + currentViewMode = false, + onCategoryClick = { selectedCategory -> + // 暂时不处理点击事件 + } + ) + } + } + } + } + // 第二层:按日期分组的记录列表 groupedRecords.forEach { (date, dayRecords) -> item { diff --git a/app/src/main/java/com/yovinchen/bookkeeping/viewmodel/MemberDetailViewModel.kt b/app/src/main/java/com/yovinchen/bookkeeping/viewmodel/MemberDetailViewModel.kt index 5cb290d..724cfc7 100644 --- a/app/src/main/java/com/yovinchen/bookkeeping/viewmodel/MemberDetailViewModel.kt +++ b/app/src/main/java/com/yovinchen/bookkeeping/viewmodel/MemberDetailViewModel.kt @@ -8,6 +8,7 @@ import com.yovinchen.bookkeeping.model.BookkeepingRecord import com.yovinchen.bookkeeping.model.AnalysisType import com.yovinchen.bookkeeping.model.TransactionType import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch import java.time.YearMonth import java.time.ZoneId import java.util.Date @@ -22,6 +23,9 @@ class MemberDetailViewModel(application: Application) : AndroidViewModel(applica private val _totalAmount = MutableStateFlow(0.0) val totalAmount: StateFlow = _totalAmount.asStateFlow() + private val _categoryData = MutableStateFlow>>(emptyList()) + val categoryData: StateFlow>> = _categoryData.asStateFlow() + fun loadMemberRecords( memberName: String, category: String, @@ -62,11 +66,18 @@ class MemberDetailViewModel(application: Application) : AndroidViewModel(applica ) } - recordsFlow - .onEach { records -> + viewModelScope.launch { + recordsFlow.collect { records -> _memberRecords.value = records _totalAmount.value = records.sumOf { it.amount } + + // 计算分类数据 + val categoryAmounts = records.groupBy { it.category } + .mapValues { (_, records) -> records.sumOf { it.amount }.toFloat() } + .toList() + .sortedByDescending { it.second } + _categoryData.value = categoryAmounts } - .launchIn(viewModelScope) + } } }