123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- 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<ContainerItemDetail>) {
- 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)
- }
- }
- }
|