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) + } } }