feat: 新增套餐余额页面与个人资料入口
- 新增PlanBalanceScreen套餐余额屏幕 - 更新ProfileScreen个人资料页面入口 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,173 @@
|
|||||||
|
package com.huaga.life_echo.ui.screens
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import com.huaga.life_echo.ui.components.common.LoadingIndicator
|
||||||
|
import com.huaga.life_echo.ui.components.payment.QuotaIndicator
|
||||||
|
import com.huaga.life_echo.ui.icons.AppIcons
|
||||||
|
import com.huaga.life_echo.ui.theme.LightPurple
|
||||||
|
import com.huaga.life_echo.ui.theme.MediumPurple
|
||||||
|
import com.huaga.life_echo.ui.theme.SlatePurple
|
||||||
|
import com.huaga.life_echo.ui.viewmodel.PaymentViewModel
|
||||||
|
import com.huaga.life_echo.ui.viewmodel.ViewModelFactory
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 套餐余额页:展示当前套餐账户剩余额度(对话轮数、章节等)
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun PlanBalanceScreen(
|
||||||
|
navController: androidx.navigation.NavHostController? = null,
|
||||||
|
viewModel: PaymentViewModel = viewModel(
|
||||||
|
factory = ViewModelFactory(LocalContext.current)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
val quota by viewModel.quota.collectAsState()
|
||||||
|
val currentPlan by viewModel.currentPlan.collectAsState()
|
||||||
|
val isLoading by viewModel.isLoading.collectAsState()
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
viewModel.checkQuota()
|
||||||
|
viewModel.loadCurrentPlan()
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
|
title = { Text("套餐余额") },
|
||||||
|
navigationIcon = {
|
||||||
|
IconButton(onClick = { navController?.popBackStack() }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = AppIcons.ArrowBack,
|
||||||
|
contentDescription = "返回",
|
||||||
|
tint = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
viewModel.checkQuota()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = AppIcons.Refresh,
|
||||||
|
contentDescription = "刷新",
|
||||||
|
tint = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
|
containerColor = MediumPurple,
|
||||||
|
titleContentColor = Color.White,
|
||||||
|
navigationIconContentColor = Color.White,
|
||||||
|
actionIconContentColor = Color.White
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
if (isLoading && quota == null) {
|
||||||
|
LoadingIndicator(modifier = Modifier.padding(paddingValues))
|
||||||
|
} else {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.background(MaterialTheme.colorScheme.background),
|
||||||
|
contentPadding = PaddingValues(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
currentPlan?.let { plan ->
|
||||||
|
item {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = LightPurple.copy(alpha = 0.3f)),
|
||||||
|
shape = MaterialTheme.shapes.medium
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "当前套餐",
|
||||||
|
fontSize = 14.sp,
|
||||||
|
color = SlatePurple
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = plan.displayName,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = MediumPurple
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Text(
|
||||||
|
text = "账户额度",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
quota?.let { q ->
|
||||||
|
item {
|
||||||
|
QuotaIndicator(quota = q)
|
||||||
|
}
|
||||||
|
} ?: item {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant),
|
||||||
|
shape = MaterialTheme.shapes.medium
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(24.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "暂无额度信息,请稍后刷新",
|
||||||
|
fontSize = 14.sp,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -184,6 +184,12 @@ fun ProfileScreen(
|
|||||||
onPress = { navController?.navigate(Screen.PlanDetails.route) }
|
onPress = { navController?.navigate(Screen.PlanDetails.route) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
SettingItem(
|
||||||
|
icon = AppIcons.Info,
|
||||||
|
label = "套餐余额",
|
||||||
|
description = "查看当前套餐剩余额度",
|
||||||
|
onPress = { navController?.navigate(Screen.PlanBalance.route) }
|
||||||
|
)
|
||||||
SettingItem(
|
SettingItem(
|
||||||
icon = AppIcons.Upgrade,
|
icon = AppIcons.Upgrade,
|
||||||
label = "升级套餐",
|
label = "升级套餐",
|
||||||
|
|||||||
Reference in New Issue
Block a user