diff --git a/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt b/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt index 5554b9a..74edf71 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/navigation/AppNavigation.kt @@ -27,6 +27,8 @@ sealed class Screen(val route: String) { object FAQ : Screen("faq") object Feedback : Screen("feedback") object About : Screen("about") + object Terms : Screen("terms") + object Privacy : Screen("privacy") } @OptIn(ExperimentalAnimationApi::class) @@ -149,6 +151,30 @@ fun AppNavigation( ) { AboutScreen(navController = navController) } + composable( + route = Screen.Terms.route, + enterTransition = { slideInHorizontally() }, + exitTransition = { slideOutHorizontally() }, + popEnterTransition = { slideInHorizontallyFromLeft() }, + popExitTransition = { slideOutHorizontallyToRight() } + ) { + LegalDocumentScreen( + documentType = com.huaga.life_echo.ui.screens.LegalDocumentType.TERMS, + onNavigateBack = { navController.popBackStack() } + ) + } + composable( + route = Screen.Privacy.route, + enterTransition = { slideInHorizontally() }, + exitTransition = { slideOutHorizontally() }, + popEnterTransition = { slideInHorizontallyFromLeft() }, + popExitTransition = { slideOutHorizontallyToRight() } + ) { + LegalDocumentScreen( + documentType = com.huaga.life_echo.ui.screens.LegalDocumentType.PRIVACY, + onNavigateBack = { navController.popBackStack() } + ) + } composable( route = Screen.Login.route, enterTransition = { fadeInTransition() }, @@ -169,6 +195,12 @@ fun AppNavigation( }, onNavigateToResetPassword = { navController.navigate(Screen.ResetPassword.route) + }, + onNavigateToTerms = { + navController.navigate(Screen.Terms.route) + }, + onNavigateToPrivacy = { + navController.navigate(Screen.Privacy.route) } ) } @@ -182,6 +214,12 @@ fun AppNavigation( RegisterScreen( onRegisterSuccess = { navController.popBackStack() + }, + onNavigateToTerms = { + navController.navigate(Screen.Terms.route) + }, + onNavigateToPrivacy = { + navController.navigate(Screen.Privacy.route) } ) } diff --git a/app-android/app/src/main/java/com/huaga/life_echo/ui/screens/LegalDocumentScreen.kt b/app-android/app/src/main/java/com/huaga/life_echo/ui/screens/LegalDocumentScreen.kt new file mode 100644 index 0000000..6c12ef7 --- /dev/null +++ b/app-android/app/src/main/java/com/huaga/life_echo/ui/screens/LegalDocumentScreen.kt @@ -0,0 +1,75 @@ +package com.huaga.life_echo.ui.screens + +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.compose.foundation.layout.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import com.huaga.life_echo.config.AppConfig + +/** + * 法律文档页面(用户协议或隐私政策) + * 使用WebView显示后端返回的HTML内容 + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LegalDocumentScreen( + documentType: LegalDocumentType, + onNavigateBack: () -> Unit +) { + val context = LocalContext.current + val url = "${AppConfig.BASE_URL}/api/legal/${documentType.endpoint}" + + Scaffold( + topBar = { + TopAppBar( + title = { Text(documentType.title) }, + navigationIcon = { + IconButton(onClick = onNavigateBack) { + Icon( + imageVector = Icons.Default.ArrowBack, + contentDescription = "返回" + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surface, + titleContentColor = MaterialTheme.colorScheme.onSurface + ) + ) + } + ) { paddingValues -> + AndroidView( + factory = { ctx -> + WebView(ctx).apply { + webViewClient = WebViewClient() + settings.javaScriptEnabled = true + settings.domStorageEnabled = true + settings.loadWithOverviewMode = true + settings.useWideViewPort = true + settings.builtInZoomControls = true + settings.displayZoomControls = false + loadUrl(url) + } + }, + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + ) + } +} + +/** + * 法律文档类型 + */ +enum class LegalDocumentType(val title: String, val endpoint: String) { + TERMS("用户协议", "terms"), + PRIVACY("隐私政策", "privacy") +}