package com.example.pda.ui import androidx.compose.foundation.clickable import androidx.compose.runtime.* import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.Modifier import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Clear import androidx.compose.material.icons.filled.Delete import androidx.compose.material3.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.compose.material.icons.filled.Search import com.example.pda.R import com.example.pda.ui.viewmodel.InventoryViewModel import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.lifecycle.viewmodel.compose.viewModel import com.example.pda.model.ContainerItemDetail import kotlinx.coroutines.launch // 托盘详情界面 - 修复关键问题 @OptIn(ExperimentalMaterial3Api::class) @Composable fun ContainerItems( container: String, onBack: () -> Unit, navToOutOperation: (String) -> Unit ) { val viewModel: InventoryViewModel = viewModel() val uiState by viewModel.uiState.collectAsState() val containerDetails by viewModel.containerItemsDetails.collectAsState() val snackbarHostState = remember { SnackbarHostState() } val coroutineScope = rememberCoroutineScope() val containerState = remember(container) { mutableStateOf(container) } var showInput by remember { mutableStateOf(container.isBlank()) } val inputIp = remember { mutableStateOf("") } // 自动加载数据 LaunchedEffect(container) { if (container.isNotBlank()) { viewModel.getContainerDetail(container) } } // 状态处理 LaunchedEffect(uiState) { when (val currentState = uiState) { is InventoryViewModel.UiState.Success -> { coroutineScope.launch { snackbarHostState.showSnackbar(currentState.message) viewModel.resetState() } } is InventoryViewModel.UiState.Error -> { coroutineScope.launch { snackbarHostState.showSnackbar("错误:${currentState.message}") viewModel.resetState() } } else -> {} } } Scaffold( snackbarHost = { SnackbarHost(snackbarHostState) }, topBar = { TopAppBar( navigationIcon = { IconButton(onClick = onBack) { Icon(Icons.Default.ArrowBack, "返回") } }, title = { Row(verticalAlignment = Alignment.CenterVertically) { Icon( painter = painterResource(id = R.drawable.logo), contentDescription = "PDA Logo", modifier = Modifier.size(40.dp), tint = MaterialTheme.colorScheme.surfaceTint ) Spacer(Modifier.width(8.dp)) Text("信泰PDA—托盘详情") } }, actions = { // 出库操作按钮 IconButton( onClick = { if (containerDetails.isNotEmpty()) { navToOutOperation(containerState.value) } else { coroutineScope.launch { snackbarHostState.showSnackbar("没有可出库的批次") } } } ) { Icon( painter = painterResource(id = R.drawable.ic_out), contentDescription = "出库操作", tint = Color.White ) } }, colors = TopAppBarDefaults.topAppBarColors( containerColor = Color(0xFFBCD0C5), titleContentColor = MaterialTheme.colorScheme.onPrimary, actionIconContentColor = MaterialTheme.colorScheme.onPrimary ) ) } ) { innerPadding -> Column( modifier = Modifier .padding(innerPadding) .fillMaxSize() .padding(16.dp) ) { // 输入区域 if (showInput || containerState.value.isBlank()) { Row( modifier = Modifier .fillMaxWidth() .padding(bottom = 16.dp), verticalAlignment = Alignment.CenterVertically ) { OutlinedTextField( value = inputIp.value, onValueChange = { inputIp.value = it }, label = { Text("请输入托盘编码") }, modifier = Modifier.weight(1f), trailingIcon = { IconButton( onClick = { if (inputIp.value.isNotBlank()) { containerState.value = inputIp.value viewModel.getContainerDetail(containerState.value) showInput = false } } ) { Icon(Icons.Default.Search, "搜索") } } ) } } // 托盘编码显示与操作 Row( modifier = Modifier .fillMaxWidth() .padding(bottom = 16.dp), verticalAlignment = Alignment.CenterVertically ) { Text( text = "托盘编码:${containerState.value}", style = MaterialTheme.typography.titleLarge, modifier = Modifier.weight(1f) ) if (!showInput) { IconButton( onClick = { containerState.value = "" showInput = true }, ) { Icon(Icons.Default.Clear, "清除托盘编码") } } } // 显示批次数据 ContainerItemList(data = containerDetails) } } } // 批次列表显示 - 优化版 @Composable private fun ContainerItemList(data: List) { if (data.isEmpty()) { Box( modifier = Modifier .fillMaxSize() .padding(16.dp), contentAlignment = Alignment.Center ) { Text("没有找到批次数据", style = MaterialTheme.typography.titleMedium) } } else { LazyColumn( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(12.dp) ) { itemsIndexed(data) { index, item -> OutOperationItemCard( index = index, item = item ) } } } } // 批次项卡片 - 提取为独立组件 @Composable private fun OutOperationItemCard( index: Int, item: ContainerItemDetail ) { val remaining = item.goods_in_qty - item.goods_out_qty Card( modifier = Modifier.fillMaxWidth(), elevation = CardDefaults.cardElevation(4.dp) ) { Column( modifier = Modifier.padding(16.dp) ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Text("#${index + 1}", style = MaterialTheme.typography.labelMedium) Text("items_: ${item.id}", style = MaterialTheme.typography.labelMedium) } Spacer(Modifier.height(6.dp)) Divider() Spacer(Modifier.height(6.dp)) Text( "批次: ${item.batch_number}", style = MaterialTheme.typography.titleMedium ) Spacer(Modifier.height(6.dp)) Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { Column { Text("物料编码", style = MaterialTheme.typography.labelSmall) Text(item.goods_code, style = MaterialTheme.typography.bodyMedium) } Column { Text("物料名称", style = MaterialTheme.typography.labelSmall) Text(item.goods_desc, style = MaterialTheme.typography.bodyMedium) } } Spacer(Modifier.height(2.dp)) Divider(thickness = 1.5.dp) // 数量信息网格 Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceAround ) { QuantityInfoCard(title = "组盘", value = item.goods_in_qty.toString(), backgroundColor = Color(0xFFE3F2FD)) QuantityInfoCard(title = "出库", value = item.goods_out_qty.toString(), backgroundColor = Color(0xFFFFF8E1)) QuantityInfoCard(title = "剩余", value = remaining.toString(), backgroundColor = Color(0xFFE8F5E9)) } } } } // 数量信息卡片组件 @Composable private fun QuantityInfoCard(title: String, value: String, backgroundColor: Color) { Card( modifier = Modifier.size(60.dp), colors = CardDefaults.cardColors(containerColor = backgroundColor) ) { Column( modifier = Modifier.padding(8.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text(title, style = MaterialTheme.typography.labelMedium) Spacer(Modifier.height(2.dp)) Text(value, style = MaterialTheme.typography.titleMedium) } } }