初始代码提交

This commit is contained in:
2026-01-14 10:36:27 +08:00
parent 600aa4dbb0
commit 196cacfe5a
268 changed files with 22545 additions and 2 deletions
@@ -0,0 +1,175 @@
package com.sw.inbound.ui
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.sw.inbound.GlobalKey
import com.sw.inbound.R
import com.sw.inbound.ui.page.HomeScreen
import com.sw.inbound.ui.page.PurchaseOrderScreen
import com.sw.inbound.ui.weight.GlobalLoading
import com.sw.inbound.utils.SPUtil
import com.sw.inbound.utils.ToastUtils
@Composable
fun AppScreen(
onBackRequest: () -> Unit
) {
val navController = rememberNavController()
val currentBackStackEntry by navController.currentBackStackEntryAsState()
var canBack by remember { mutableStateOf(false) }
// 拦截物理返回键
// BackHandler(
// onBack = {
// val currentRoute = currentBackStackEntry?.destination?.route
// Timber.d("BackHandler currentRouter = ${currentRoute}")
// if (currentRoute == Screen.Home.route && !canBack) {
// ToastUtils.showToast("再次点击退出")
// canBack = true
// } else if (currentRoute == Screen.Login.route) {
// onBackRequest()
// } else {
// navController.popBackStack()
// }
// }
// )
//
// BackHandler(canBack) {
// Timber.d("canBack = $canBack")
// if (canBack) {
// onBackRequest()
// }
// }
Scaffold(
modifier = Modifier
.fillMaxSize()
//.paint(painter = painterResource(R.mipmap.bg)),
,containerColor = Color.Transparent,
content = { padding ->
Box {
// Image(
// painter = painterResource(R.mipmap.bg),
// contentDescription = null,
// modifier = Modifier.fillMaxSize(),
// contentScale = ContentScale.Crop
// )
Image(
painter = painterResource(id = R.mipmap.bg),
contentDescription = "背景图片",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
NavHost(padding, navController, onBackRequest)
}
}
)
ToastUtils.ToastComposable()
GlobalLoading() // 全局Loading
}
/**
* 导航
*/
@Composable
private fun NavHost(
padding: PaddingValues,
navController: NavHostController,
onBackRequest: () -> Unit = {}
) {
val spUtil = SPUtil.getInstance()
val token = spUtil.get(GlobalKey.KEY_TOKEN, "")!!
NavHost(
modifier = Modifier
.fillMaxSize()
.padding(padding),
navController = navController,
//startDestination = if (token.isEmpty()) Screen.Login.route else Screen.Home.route
startDestination = Screen.Home.route
) {
// composable(Screen.Test.route) {
// TestScreen(modifier = Modifier, navController)
// }
// 首页
composable(Screen.Home.route) {
HomeScreen(modifier = Modifier, navController, onBackRequest = onBackRequest)
}
// 登录
// composable(Screen.Login.route) {
// LoginScreen(modifier = Modifier, navController)
// }
// 采购单入库
composable(
Screen.PurchaseOrder.route,
enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
exitTransition = { fadeOut(animationSpec = tween(0)) } // 无退出动画
) {
PurchaseOrderScreen(modifier = Modifier.fillMaxSize(), navController)
}
// // 自采单
// composable(
// Screen.SelfProcurement.route,
// enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
// exitTransition = { fadeOut(animationSpec = tween(0)) } // 无退出动画
// ) {
// SelfProcurementScreen(modifier = Modifier, navController)
// }
// // 收货
// composable(
// Screen.ReceiptProduct.route,
// enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
// exitTransition = { fadeOut(animationSpec = tween(0)) }, // 无退出动画
// arguments = listOf(
// navArgument(name = "id", builder = { type = NavType.IntType }),
// navArgument(name = "supplierId", builder = { type = NavType.IntType })
// )
// ) { backStackEntry ->
// val id = backStackEntry.arguments?.getString("id") ?: ""
// val supplierId = backStackEntry.arguments?.getString("supplierId") ?: ""
// ReceiptProductScreen(modifier = Modifier, navController, id, supplierId)
// }
}
}
sealed class Screen(val route: String) {
data object Home : Screen("home")
// data object Login : Screen("login")
// 采购单入库
data object PurchaseOrder : Screen("purchase_order")
// 自采单入库
// data object SelfProcurement : Screen("self_procurement")
// 收货
// data object ReceiptProduct : Screen("receipt_product?id={id}&supplierId={supplierId}") {
// fun createRoute(id: Int, supplierId: Int) =
// "receipt_product?id=${id}&supplierId=${supplierId}"
// }
// 添加物品
// data object AddProduct : Screen("addProduct")
// data object Test : Screen("Test")
}
@@ -0,0 +1,118 @@
package com.sw.inbound.ui.page
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.sw.inbound.R
import com.sw.inbound.activity.GoodsListActivity
import com.sw.inbound.activity.SelfProcurementActivity
import com.sw.inbound.ui.Screen
import com.sw.inbound.ui.weight.TopTitleBar
import com.sw.inbound.utils.ext.startActivity
import com.sw.inbound.viewmodel.UserViewModel
import timber.log.Timber
/**
* 首页
*/
@Composable
fun HomeScreen(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
viewModel: UserViewModel = hiltViewModel<UserViewModel>(),
onBackRequest: () -> Unit = {}
) {
val user by viewModel.user.collectAsState()
// 避免每次进入都获取字典类型
LaunchedEffect(Unit) {
Timber.d("LaunchedEffect(Unit)")
viewModel.getInitInfo()
}
BackHandler {
onBackRequest()
}
Column(modifier = Modifier.fillMaxSize()) {
TopTitleBar(user = user, onLogoutClick = {
// viewModel.logout()
// navController.navigate(Screen.Login.route) {
// popUpTo(Screen.Home.route) {
// inclusive = true
// }
// }
})
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.weight(1f)
.fillMaxWidth()
) {
Image(
modifier = Modifier
.width(595.dp)
.height(477.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) {
navController.navigate(Screen.PurchaseOrder.route)
//navController.context.startActivity<ReceiptActivity> {
// putExtra(GoodsListActivity.ID, "123123")
// putExtra(GoodsListActivity.SUPPLIER_ID, "123123123123")
// putExtra(GoodsListActivity.IS_RECEIPT_PAGE, true)
//}
},
painter = painterResource(R.mipmap.ic_order_purchase),
contentDescription = "采购单入库"
)
Spacer(modifier = Modifier.width(15.dp))
Image(
modifier = Modifier
.width(595.dp)
.height(477.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null
) {
// navController.navigate(
// Screen.SelfProcurement.route, navOptions = NavOptions.Builder()
// .setEnterAnim(0)
// .setExitAnim(0)
// .setPopEnterAnim(0)
// .setPopExitAnim(0)
// .build()
// )
navController.context.startActivity<SelfProcurementActivity> {
putExtra(GoodsListActivity.IS_RECEIPT_PAGE, false)
}
},
painter = painterResource(R.mipmap.ic_order_self_procurement),
contentDescription = "自采入库"
)
}
}
}
@@ -0,0 +1,202 @@
//package com.sw.inbound.ui.page
//
//import androidx.compose.foundation.Image
//import androidx.compose.foundation.border
//import androidx.compose.foundation.layout.Arrangement
//import androidx.compose.foundation.layout.Box
//import androidx.compose.foundation.layout.Column
//import androidx.compose.foundation.layout.Spacer
//import androidx.compose.foundation.layout.fillMaxSize
//import androidx.compose.foundation.layout.fillMaxWidth
//import androidx.compose.foundation.layout.height
//import androidx.compose.foundation.layout.padding
//import androidx.compose.foundation.layout.size
//import androidx.compose.foundation.layout.width
//import androidx.compose.foundation.shape.RoundedCornerShape
//import androidx.compose.foundation.text.KeyboardOptions
//import androidx.compose.material3.Text
//import androidx.compose.material3.TextField
//import androidx.compose.material3.TextFieldDefaults
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.LaunchedEffect
//import androidx.compose.runtime.getValue
//import androidx.compose.runtime.mutableStateOf
//import androidx.compose.runtime.remember
//import androidx.compose.runtime.setValue
//import androidx.compose.ui.Alignment
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.graphics.asImageBitmap
//import androidx.compose.ui.res.colorResource
//import androidx.compose.ui.text.input.ImeAction
//import androidx.compose.ui.text.input.KeyboardType
//import androidx.compose.ui.text.input.PasswordVisualTransformation
//import androidx.compose.ui.text.input.VisualTransformation
//import androidx.compose.ui.text.style.TextAlign
//import androidx.compose.ui.unit.dp
//import androidx.compose.ui.unit.sp
//import androidx.hilt.navigation.compose.hiltViewModel
//import androidx.navigation.NavController
//import androidx.navigation.compose.rememberNavController
//import com.sw.inbound.GlobalData
//import com.sw.inbound.GlobalKey
//import com.sw.inbound.R
//import com.sw.inbound.ext.bold
//import com.sw.inbound.ext.textAlign
//import com.sw.inbound.ext.withSize
//import com.sw.inbound.ui.Screen
//import com.sw.inbound.ui.theme.AppTypography
//import com.sw.inbound.ui.weight.CustomButton
//import com.sw.inbound.utils.QRCodeUtil
//import com.sw.inbound.utils.SPUtil
//import com.sw.inbound.viewmodel.UserViewModel
//import timber.log.Timber
//
///**
// * 登录界面
// */
//@Composable
//fun LoginScreen(
// modifier: Modifier = Modifier,
// controller: NavController = rememberNavController(),
// viewModel: UserViewModel = hiltViewModel<UserViewModel>()
//) {
// var username by remember { mutableStateOf<String>("") }
// var password by remember { mutableStateOf<String>("") }
//
//// val user by viewModel.user.collectAsState()
//
// LaunchedEffect(Unit) {
// Timber.d(" user =")
// username = SPUtil.getInstance().get(GlobalKey.KEY_USER_NAME, "").toString()
// viewModel.user.collect {
// Timber.d(" user collect = ${it}")
// if (it != null) {
// GlobalData.user = it
// controller.navigate(Screen.Home.route) {
// Timber.d("登录成功,跳转到主界面")
// controller.popBackStack()
// }
// }
// }
//// if (user != null){
//// controller.navigate(Screen.Home.route) {
//// controller.popBackStack()
//// }
//// }
// }
//
// val qrCodeBmp by lazy {
// QRCodeUtil.generateQRCode(
// content = GlobalData.deviceId,
// size = 150
// )
// }
//
// Box(contentAlignment = Alignment.BottomStart) {
// Column(
// modifier = Modifier.fillMaxSize(),
// verticalArrangement = Arrangement.Center,
// horizontalAlignment = Alignment.CenterHorizontally
// ) {
// Text(text = "出入库管理", style = AppTypography.black141428TextStyle.withSize(60.sp).bold())
// Spacer(modifier = Modifier.height(91.dp))
//
// UserInputView(value = username, placeholderValue = "请输入用户名", onValueChange = {
// username = it
// })
//
// Spacer(modifier = Modifier.height(30.dp))
//
// UserInputView(value = password, placeholderValue = "请输入密码", onValueChange = {
// password = it
// }, isPassword = true)
//
// Spacer(modifier = Modifier.height(90.dp))
// CustomButton(
// modifier = modifier
// .width(885.dp)
// .height(120.dp),
// text = "登录",
// onClick = {
// //if (username.isEmpty() || password.isEmpty()) {
// // ToastUtils.showToast("用户名或密码不能为空")
// // return@CustomButton
// //}
// viewModel.login(username, password)
// // TODO: 测试功能,临时打开新页面
// controller.navigate(Screen.Home.route)
//// controller.context.startActivity<ReceiptActivity> {
//// putExtra(GoodsListActivity.ID, "123123")
//// putExtra(GoodsListActivity.SUPPLIER_ID, "123123123123")
//// }
// },
// borderColor = colorResource(R.color.blue),
// textColor = colorResource(R.color.white),
// fontSize = 36.sp
// )
// }
// Image(
// bitmap = qrCodeBmp!!.asImageBitmap(),
// contentDescription = "",
// modifier = Modifier
// .padding(start = 10.dp, bottom = 10.dp)
// .size(80.dp, 80.dp)
// )
// }
//}
//
//
//@Composable
//private fun UserInputView(
// value: String,
// placeholderValue: String,
// onValueChange: (String) -> Unit,
// isPassword: Boolean = false,
// isShowPassword: Boolean = false
//) {
// val backgroundColor = Color.White.copy(alpha = 0.37f)
//
// TextField(
// value = value,
// onValueChange = onValueChange,
// modifier = Modifier
// .height(120.dp)
// .width(885.dp)
// .border(
// width = 2.dp,
// color = backgroundColor,
// shape = RoundedCornerShape(10.dp)
// ),
// colors = TextFieldDefaults.colors(
// focusedContainerColor = backgroundColor,
// unfocusedContainerColor = backgroundColor,
// disabledContainerColor = backgroundColor,
// focusedIndicatorColor = Color.Transparent,
// unfocusedIndicatorColor = Color.Transparent,
// disabledIndicatorColor = Color.Transparent
// ),
// // 密码输入相关设置
// visualTransformation = if (isPassword && !isShowPassword) {
// PasswordVisualTransformation()
// } else {
// VisualTransformation.None
// },
// keyboardOptions = KeyboardOptions(
// keyboardType = if (isPassword) KeyboardType.Password else KeyboardType.Text,
// imeAction = if (isPassword) ImeAction.Done else ImeAction.Next
// ),
// shape = RoundedCornerShape(10.dp),
// textStyle = AppTypography.gray96a0aaTextStyle.withSize(30.sp).textAlign(TextAlign.Center),
// placeholder = {
// Text(
// text = placeholderValue,
// modifier = Modifier.fillMaxWidth(),
// textAlign = TextAlign.Center, // 占位符水平居中
// style = AppTypography.gray96a0aaTextStyle.textAlign(TextAlign.Center)
// )
// },
// singleLine = true // 确保单行输入(避免换行导致高度变化)
// )
//
//}
@@ -0,0 +1,361 @@
package com.sw.inbound.ui.page
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.sw.inbound.R
import com.sw.inbound.activity.GoodsListActivity
import com.sw.inbound.activity.ReceiptActivity
import com.sw.inbound.activity.SelfProcurementActivity
import com.sw.inbound.ext.dashedBorder
import com.sw.inbound.ext.toFormattedString
import com.sw.inbound.model.response.SupplierInfo
import com.sw.inbound.ui.theme.AppTypography.blackTextStyle
import com.sw.inbound.ui.theme.AppTypography.grayTextStyle
import com.sw.inbound.ui.weight.BottomActionBar
import com.sw.inbound.ui.weight.TopTitleBar
import com.sw.inbound.utils.ext.startActivity
import com.sw.inbound.viewmodel.PurchaseOrderViewModel
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import timber.log.Timber
@Preview(
widthDp = 1920,
heightDp = 1080,
showBackground = true
)
/**
* 采购订单-供应商列表
*/
@Composable
fun PurchaseOrderScreen(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
viewModel: PurchaseOrderViewModel = hiltViewModel<PurchaseOrderViewModel>()
) {
val products by viewModel.supplierList.collectAsState()
val lazyListState = rememberLazyListState()
val canLoadMore by viewModel.canLoadMore.collectAsState()
val isMoreLoading by viewModel.isMoreLoading.collectAsState()
var pageNum by remember { mutableIntStateOf(1) }
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
Timber.d("ON_RESUME 触发")
pageNum = 0
viewModel.getOrderList()
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
}
// 检测是否滚动到底部
LaunchedEffect(lazyListState) {
snapshotFlow { lazyListState.layoutInfo }
.map { layoutInfo ->
val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
lastVisibleItem?.index == layoutInfo.totalItemsCount - 1
}
.distinctUntilChanged()
.collect { reachedEnd ->
Timber.d("加载更多 reachedEnd = $reachedEnd, isMoreLoading = $isMoreLoading, canLoadMore = $canLoadMore")
if (reachedEnd && !isMoreLoading && canLoadMore) {
pageNum++
viewModel.getOrderList(pageNum = pageNum)
}
}
}
Column {
TopTitleBar()
Box(
modifier = Modifier
.weight(1f)
.padding(horizontal = 10.dp)
) {
Image(
painter = painterResource(id = R.mipmap.bg_listview),
contentDescription = "背景",
modifier = Modifier
.fillMaxSize(),
contentScale = ContentScale.FillBounds
)
Box(
modifier = Modifier.padding(
start = 30.dp,
end = 30.dp,
top = 30.dp,
bottom = 90.dp
)
) {
if (products.isEmpty()) {
PurchaseEmptyItem()
} else {
LazyRow(
modifier = modifier
.padding(10.dp),
state = lazyListState,
contentPadding = PaddingValues(16.dp),
horizontalArrangement = Arrangement.spacedBy(30.dp)
) {
items(items = products, key = { it!!.id?:"" }) { product ->
PurchaseOrderItem(product!!) {
// navController.navigate(
// Screen.ReceiptProduct.createRoute(
// it.id,
// it.supplierId
// )
// )
navController.context.startActivity<ReceiptActivity> {
putExtra(GoodsListActivity.ID,product!!.id)
putExtra(GoodsListActivity.SUPPLIER_ID,product.supplierId)
putExtra(GoodsListActivity.IS_RECEIPT_PAGE,true)
putExtra(GoodsListActivity.IS_NEW_RECEIPT,false)
}
}
}
if (isMoreLoading) {
item {
Box(
modifier = Modifier
.fillParentMaxHeight()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
}
}
}
}
}
BottomActionBar(
modifier = Modifier, onLeftButtonClick = {
navController.popBackStack()
}, onRight2ButtonClick = {
//navController.navigate(Screen.SelfProcurement.route)
navController.context.startActivity<SelfProcurementActivity> {
putExtra(GoodsListActivity.IS_RECEIPT_PAGE, false)}
//navController.context.startActivity<ReceiptActivity> {
// //xtra(GoodsListActivity.ID,it!!.id)
// //xtra(GoodsListActivity.SUPPLIER_ID,it.supplierId)
// putExtra(GoodsListActivity.IS_RECEIPT_PAGE,true)
// putExtra(GoodsListActivity.IS_NEW_RECEIPT,true)
//}
})
}
}
/**
* 采购单缺省
*/
@Composable
fun PurchaseEmptyItem() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(painter = painterResource(R.mipmap.ic_empty), contentDescription = "暂无数据")
Spacer(modifier = Modifier.height(30.dp))
Text(
text = "暂无数据", style = TextStyle(
fontSize = 30.sp,
fontWeight = FontWeight.Bold,
color = colorResource(R.color.title)
)
)
}
}
/**
* 列表item
*/
@Composable
fun PurchaseOrderItem(product: SupplierInfo, onItemClick: (SupplierInfo) -> Unit) {
val (receiptStatusStyle, statusLabel) = when (product.receiveStatus) {
1 -> blackTextStyle to "已关闭"
2 -> blackTextStyle to "已完成"
3 -> blackTextStyle.copy(
color = colorResource(R.color.red)
) to "未收货"
4 -> blackTextStyle.copy(
color = colorResource(R.color.origin)
) to "部分收货"
else -> blackTextStyle to "已关闭"
}
val itemSpace = 29.dp
Box(
modifier = Modifier
.background(
color = Color.White.copy(alpha = 0.37f),
shape = RoundedCornerShape(10.dp) // 圆角背景
)
.clickable {
onItemClick(product)
}
) {
Column(
modifier = Modifier
.width(580.dp)
.padding(horizontal = 30.dp, vertical = 30.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(0.dp)
) {
Text(
text = product.supplierName ?: "-",
modifier = Modifier.padding(top = 25.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = TextStyle(
fontWeight = FontWeight.Bold,
fontSize = 30.sp,
color = colorResource(R.color.black)
)
)
Spacer(modifier = Modifier.height(itemSpace))
Text(
text = "单号 ${product.purCode ?: "-"}",
maxLines = 1,
style = grayTextStyle
)
Spacer(modifier = Modifier.height(itemSpace))
HorizontalDivider(
thickness = 1.dp,
color = colorResource(R.color.divider)
)
Spacer(modifier = Modifier.height(40.dp))
Text(
text = "物品(项)",
style = grayTextStyle
)
Spacer(modifier = Modifier.height(22.dp))
Text(
text = product.goodCount.toFormattedString(),
style = TextStyle(
color = colorResource(R.color.black),
fontSize = 90.sp,
fontWeight = FontWeight.Bold
)
)
Spacer(modifier = Modifier.height(22.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.dashedBorder(
strokeWidth = 2.dp,
color = Color(0xFFBDC5CE),
cornerRadiusDp = 10.dp
)
.padding(horizontal = 72.dp, vertical = 27.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "采购日期", style = grayTextStyle)
Spacer(modifier = Modifier.height(8.dp))
Text(text = product.purchaseDate ?: "-", style = blackTextStyle)
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = "到货日期", style = grayTextStyle)
Spacer(modifier = Modifier.height(8.dp))
Text(text = product.receiveDate ?: "-", style = blackTextStyle)
}
}
Spacer(modifier = Modifier.height(28.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Row {
Text("收货状态:", style = grayTextStyle)
Spacer(Modifier.width(8.dp))
Text(statusLabel, style = receiptStatusStyle)
}
Row {
Text("采购人:", style = grayTextStyle)
Spacer(Modifier.width(8.dp))
Text(product.receiveUser, style = blackTextStyle)
}
}
Spacer(modifier = Modifier.height(itemSpace))
Button(
modifier = Modifier
.fillMaxWidth()
.height(80.dp),
shape = RoundedCornerShape(10.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Color(0xFF009632).copy(alpha = 1f),
contentColor = colorResource(R.color.white)
), onClick = {
onItemClick(product)
}) {
Text(
if (product.receiveStatus == 4) "部分收货" else "收货",
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 26.sp)
)
}
}
}
}
@@ -0,0 +1,744 @@
//package com.sw.inbound.ui.page
//
//import androidx.compose.foundation.Image
//import androidx.compose.foundation.background
//import androidx.compose.foundation.border
//import androidx.compose.foundation.clickable
//import androidx.compose.foundation.layout.Arrangement
//import androidx.compose.foundation.layout.Box
//import androidx.compose.foundation.layout.Column
//import androidx.compose.foundation.layout.Row
//import androidx.compose.foundation.layout.Spacer
//import androidx.compose.foundation.layout.fillMaxHeight
//import androidx.compose.foundation.layout.fillMaxSize
//import androidx.compose.foundation.layout.fillMaxWidth
//import androidx.compose.foundation.layout.height
//import androidx.compose.foundation.layout.padding
//import androidx.compose.foundation.layout.width
//import androidx.compose.foundation.lazy.LazyColumn
//import androidx.compose.foundation.lazy.itemsIndexed
//import androidx.compose.foundation.shape.RoundedCornerShape
//import androidx.compose.material3.HorizontalDivider
//import androidx.compose.material3.LocalTextStyle
//import androidx.compose.material3.Tab
//import androidx.compose.material3.Text
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.DisposableEffect
//import androidx.compose.runtime.LaunchedEffect
//import androidx.compose.runtime.collectAsState
//import androidx.compose.runtime.getValue
//import androidx.compose.runtime.mutableIntStateOf
//import androidx.compose.runtime.remember
//import androidx.compose.runtime.setValue
//import androidx.compose.ui.Alignment
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.layout.ContentScale
//import androidx.compose.ui.res.colorResource
//import androidx.compose.ui.res.painterResource
//import androidx.compose.ui.text.font.FontWeight
//import androidx.compose.ui.text.style.TextAlign
//import androidx.compose.ui.text.style.TextOverflow
//import androidx.compose.ui.unit.dp
//import androidx.compose.ui.unit.sp
//import androidx.hilt.navigation.compose.hiltViewModel
//import androidx.lifecycle.compose.LocalLifecycleOwner
//import androidx.navigation.NavController
//import androidx.navigation.compose.rememberNavController
//import com.sw.inbound.GlobalData
//import com.sw.inbound.R
//import com.sw.inbound.ext.bold
//import com.sw.inbound.ext.toSafeFloat
//import com.sw.inbound.ext.withColor
//import com.sw.inbound.ext.withSize
//import com.sw.inbound.model.request.UploadInfo
//import com.sw.inbound.model.response.DictType
//import com.sw.inbound.model.response.GoodsInfo
//import com.sw.inbound.sdk.SensorScaleUtils
//import com.sw.inbound.ui.theme.AppTypography
//import com.sw.inbound.ui.theme.AppTypography.black141428TextStyle
//import com.sw.inbound.ui.theme.AppTypography.gray96a0aaTextStyle
//import com.sw.inbound.ui.theme.Black_141428
//import com.sw.inbound.ui.theme.Red_FF3232
//import com.sw.inbound.ui.weight.BottomActionBar
//import com.sw.inbound.ui.weight.CustomDropdownTextField
//import com.sw.inbound.ui.weight.CustomSpinner
//import com.sw.inbound.ui.weight.CustomTextField
//import com.sw.inbound.ui.weight.IdentityView
//import com.sw.inbound.ui.weight.InputType
//import com.sw.inbound.ui.weight.PageType
//import com.sw.inbound.ui.weight.ReceiptUnadjustedListView
//import com.sw.inbound.ui.weight.RowInputLayout
//import com.sw.inbound.ui.weight.TopTitleBar
//import com.sw.inbound.ui.weight.dialog.ReceiptTipDialog
//import com.sw.inbound.utils.InteractionUtils
//import com.sw.inbound.utils.ToastUtils
//import com.sw.inbound.viewmodel.ReceiptViewModel
//import timber.log.Timber
//import androidx.compose.foundation.text.KeyboardOptions
//import androidx.compose.ui.text.input.KeyboardType
//
///**
// * 收货界面
// */
//@Composable
//fun ReceiptProductScreen(
// modifier: Modifier = Modifier,
// controller: NavController = rememberNavController(),
// id: String,
// supplierId: String,
// viewModel: ReceiptViewModel = hiltViewModel<ReceiptViewModel>()
//) {
// val adjustState by viewModel.adjustState.collectAsState()
// val showDialog by viewModel.showReceiptDialog.collectAsState()
// val orders by viewModel.orders.collectAsState()
// val receiptResult by viewModel.receiptResult.collectAsState()
//
// LaunchedEffect(receiptResult) {
// if (receiptResult) {
//// ToastUtils.showToast("收货成功")
// controller.popBackStack()
// }
// }
//
// val lifecycleOwner = LocalLifecycleOwner.current
// DisposableEffect(lifecycleOwner) {
// Timber.d("开始传感器采集")
// viewModel.startSensorScale()
// onDispose {
// Timber.d("停止传感器采集")
// viewModel.stopSensorScale()
// }
// }
//
// Column(modifier = modifier) {
// TopTitleBar()
// Box(
// modifier = modifier
// .weight(1f)
// .padding(horizontal = 10.dp)
// ) {
// Image(
// painter = painterResource(id = R.mipmap.bg_listview),
// contentDescription = "背景",
// modifier = Modifier
// .fillMaxSize(),
// contentScale = ContentScale.FillBounds
// )
// Row(
// modifier = Modifier.padding(
// start = 30.dp,
// end = 30.dp,
// top = 30.dp,
// bottom = 30.dp
// )
// ) {
// // 左侧列表
// ReceiptLeftView(
// modifier
// .weight(1f)
// .padding(start = 30.dp, top = 30.dp, bottom = 30.dp), viewModel, id
// )
//
// // 未调整,显示右侧界面
// if (!adjustState) {
//// Spacer(modifier = Modifier.width(30.dp))
// // 右侧编辑
// ReceiptRightView(
// modifier
// .width(580.dp)
// .padding(30.dp), viewModel
// )
// }
// }
// }
// BottomActionBar(
// modifier = Modifier,
// right2ButtonText = "确认收货",
// onLeftButtonClick = {
// controller.popBackStack()
// },
// onRight2ButtonClick = {
// viewModel.updateReceiptDialog(true)
// })
// }
//
// if (showDialog) {
// ReceiptTipDialog(
// isWarn = viewModel.hasWrongCount(),
// goodsList = orders.filter { it.receivedNum != it.receiveCount },
// onCancelClick = {
// Timber.d("返回")
// viewModel.updateReceiptDialog(false)
// },
// onConfirmClick = { isFull ->
// Timber.d(if (isFull) "确认收货" else "部分收货")
// viewModel.updateReceiptDialog(false)
// val uploadInfo = UploadInfo(id = id)
// if (isFull) {
// uploadInfo.receiveGoodsInfos = orders
// viewModel.confirmReceipt(uploadInfo)
// } else {
// uploadInfo.receiveGoodsInfoList = orders
// uploadInfo.supplierId = supplierId
// viewModel.partialReceipt(uploadInfo)
// }
// })
// }
//}
//
///**
// * 左侧列表
// */
//@Composable
//fun ReceiptLeftView(
// modifier: Modifier,
// viewModel: ReceiptViewModel,
// id: String
//) {
// val warehouseTypeList = GlobalData.warehouseTypeList
// val currentPurchaseInfo by viewModel.currentPurchaseInfo.collectAsState()
//
// LaunchedEffect(id) {
// viewModel.getReceiveDetail(id)
// }
//
// currentPurchaseInfo?.let {
// Column(modifier) {
// Row(
// modifier = Modifier.fillMaxWidth(),
// horizontalArrangement = Arrangement.SpaceBetween
// ) {
// Column {
// Text(
// "供应商:${currentPurchaseInfo?.supplierName ?: "-"}",
// style = black141428TextStyle.bold()
// )
// Spacer(modifier = Modifier.height(18.dp))
// Row {
// Text(
// "采购单号:${currentPurchaseInfo?.purCode ?: "-"}",
// style = gray96a0aaTextStyle.copy(fontSize = 20.sp)
// )
// Spacer(modifier = Modifier.width(30.dp))
// Text(
// "收货单号:${currentPurchaseInfo?.receiveCode ?: "-"}",
// style = gray96a0aaTextStyle.copy(fontSize = 20.sp)
// )
// }
// }
// CustomSpinner(
// items = warehouseTypeList,
// selectedItem = currentPurchaseInfo!!.warehouseName,
// onItemSelected = { value ->
// val currentPurchaseInfo1 =
// currentPurchaseInfo!!.copy(warehouseName = value.value)
// viewModel.updateCurrentPurchaseInfo(currentPurchaseInfo1)
// viewModel.updateAllPurchaseStore(warehouse = value)
// })
// }
// Spacer(modifier = Modifier.height(30.dp))
//
// TabScreen(viewModel)
// }
// }
//}
//
///**
// * 已确认、未确认切换按钮
// */
//@Composable
//fun TabScreen(viewModel: ReceiptViewModel) {
// var selectedTabIndex by remember { mutableIntStateOf(0) }
//
// val purchaseUnadjustedList by viewModel.unadjustedOrders.collectAsState()
// val purchaseAdjustList by viewModel.adjustedOrders.collectAsState()
//
// val tabs =
// listOf("未确认(${purchaseUnadjustedList.size})", "已确认(${purchaseAdjustList.size})")
//
// LaunchedEffect(purchaseUnadjustedList) {
// viewModel.updateReceiptList(purchaseUnadjustedList)
// }
//
// Column(
// modifier = Modifier
// .background(
// color = Color.White.copy(alpha = 0.37f),
// shape = RoundedCornerShape(10.dp) // 圆角背景
// )
// .fillMaxSize()
// ) {
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .padding(vertical = 30.dp), // 左上角对齐
// horizontalArrangement = Arrangement.Start,
//
// ) {
// tabs.forEachIndexed { index, title ->
// val selected = selectedTabIndex == index
// Tab(
// selected = selected,
// onClick = { selectedTabIndex = index },
// modifier = Modifier
// .width(150.dp)
//// .wrapContentWidth()
// .padding(start = if (index == 1) 30.dp else 0.dp),
// selectedContentColor = Color(0xFF0032C8),
// unselectedContentColor = Color(0xFF14141E)
// ) {
// Text(
// text = title,
// style = if (selected) AppTypography.BlueTextStyle else AppTypography.black141428TextStyle.bold(),
// textAlign = TextAlign.Center,
// modifier = Modifier.padding(vertical = 12.dp)
// )
// }
// }
// }
//
// HorizontalDivider(
// modifier = Modifier
// .fillMaxWidth()
// .padding(horizontal = 30.dp),
// thickness = 1.dp,
// color = colorResource(R.color.divider)
// )
//
// when (selectedTabIndex) {
// // 未调整列表
// 0 -> {
// UnadjustedView(purchaseUnadjustedList, viewModel)
// viewModel.updateAdjustState(false)
// }
// // 已调整列表
// 1 -> {
// AdjustedView(viewModel)
// viewModel.updateAdjustState(true)
// }
// }
// }
//}
//
///**
// * 未确认界面
// */
//@Composable
//fun UnadjustedView(purchaseOrderList: List<GoodsInfo>, viewModel: ReceiptViewModel) {
// val checkedItem by viewModel.selectedItem.collectAsState()
// // 未调整view
// ReceiptUnadjustedListView(
// modifier = Modifier.padding(horizontal = 30.dp),
// productList = purchaseOrderList,
// checkedItem = checkedItem,
// onItemCheckedClick = { index, it ->
// viewModel.updateSelectedItemWithSwitch(it)
// })
//}
//
//@Composable
//fun AdjustedView(viewModel: ReceiptViewModel) {
// // 已调整view
// val purchaseAdjustList by viewModel.adjustedOrders.collectAsState()
//
//
// LazyColumn(
// verticalArrangement = Arrangement.spacedBy(0.dp)
// ) {
// itemsIndexed(
// items = purchaseAdjustList,
//// key = { index, it -> it.id ?: index }) { index, it ->
// key = { index, it -> index }) { index, it ->
//
// AdjustedViewItem(it, viewModel)
// }
// }
//}
//
///**
// * 已确认界面
// */
//@Composable
//private fun AdjustedViewItem(purchaseOrder: GoodsInfo, viewModel: ReceiptViewModel) {
// val warehouseTypeList = GlobalData.warehouseTypeList
// val isWarnItem = purchaseOrder.receivedNum != purchaseOrder.receiveCount
// var modifier: Modifier // = Modifier.padding(horizontal = 30.dp)
// if (isWarnItem) {
// modifier = Modifier
// .padding(horizontal = 30.dp)
// .background(Color(0xffFAF1F9))
// .border(width = 1.dp, color = Color.Red)
// } else {
// modifier = Modifier.padding(horizontal = 30.dp)
// }
//
// Column(modifier = modifier) {
// Spacer(modifier = Modifier.height(30.dp))
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .padding(horizontal = 30.dp),
// horizontalArrangement = Arrangement.SpaceBetween
// ) {
// Text(
// purchaseOrder.goodNameStr,
// style = if (isWarnItem) AppTypography.blackTextStyle.withColor(Color.Red) else AppTypography.blackTextStyle
// )
// Row {
// Text("采购量:", style = gray96a0aaTextStyle)
// Text(
// "${purchaseOrder.receiveCountListStr}${purchaseOrder.unitNameStr}",
// style = black141428TextStyle
// )
// }
// }
// Spacer(modifier = Modifier.height(30.dp))
// Row(
// verticalAlignment = Alignment.CenterVertically,
// modifier = Modifier
// .fillMaxWidth()
// .padding(horizontal = 30.dp)
// ) {
// AdjustedRowInputLayout(
// label = "单价", value = purchaseOrder.newRecUnitPriceTaxInListStr,
// onValueChange = {
// viewModel.updatePurchaseItem(
// purchaseOrder = purchaseOrder.copy(
// newRecUnitPriceTaxIn = it.toSafeFloat()
// )
// )
// }, inputType = InputType.Decimal
// )
// Spacer(modifier = Modifier.width(12.dp))
// Text(text = "元", style = AppTypography.gray96a0aaTextStyle)
// Spacer(modifier = Modifier.width(50.dp))
// Text(text = "x", style = AppTypography.black141428TextStyle.bold())
// Spacer(modifier = Modifier.width(50.dp))
// AdjustedRowInputLayout(
// label = "实收",
// value = purchaseOrder.receivedNumTemp,
// onValueChange = {
// viewModel.updatePurchaseItem(
// purchaseOrder = purchaseOrder.copy(
// receivedNumTemp = it,
// receivedNum = it.toSafeFloat()
// )
// )
// },
// inputType = InputType.Decimal,
// inputTextColor = if (isWarnItem) Red_FF3232 else Black_141428
// )
// Spacer(modifier = Modifier.width(12.dp))
// Text(text = purchaseOrder.unitNameStr, style = AppTypography.gray96a0aaTextStyle)
// Spacer(modifier = Modifier.width(50.dp))
// Text(text = "=", style = AppTypography.black141428TextStyle.bold())
// Spacer(modifier = Modifier.width(50.dp))
// AdjustedRowInputLayout(
// label = "金额", value = purchaseOrder.recPriceExItemStr,
// onValueChange = {
// viewModel.updatePurchaseItem(
// purchaseOrder = purchaseOrder.copy(
// recPriceExItem = it.toSafeFloat()
// )
// )
// }, inputType = InputType.Decimal
// )
// Spacer(modifier = Modifier.width(12.dp))
// Text(text = "元", style = AppTypography.gray96a0aaTextStyle)
//
// Spacer(modifier = Modifier.weight(1f))
//
// AdjustedRowInputLayout(
// label = "仓库",
// value = purchaseOrder.warehouseNameStr,
// dropdownItems = warehouseTypeList,
// onValueChange = { value ->
// purchaseOrder.let {
// viewModel.updatePurchaseItem(
// purchaseOrder.copy(
// warehouseName = value,
// warehouseId = warehouseTypeList.find { it.value == value }?.id ?: 0
// )
// )
// }
// })
// }
// Spacer(modifier = Modifier.height(30.dp))
// HorizontalDivider(thickness = 1.dp, color = colorResource(R.color.divider))
// }
//}
//
///**
// * 已确认 横向输入组件 左标题+右输入框
// */
//@Composable
//private fun AdjustedRowInputLayout(
// label: String,
// value: String,
// onValueChange: (String) -> Unit,
// dropdownItems: List<DictType> = emptyList(),
// textAlign: TextAlign = TextAlign.Center,
// spinnerTextAlign: TextAlign = TextAlign.Start,
// trailingLabel: String? = null,
// inputType: InputType = InputType.Text,
// inputTextColor: Color = Black_141428
//) {
// Row(
// modifier = Modifier
// .height(60.dp)
//// .fillMaxWidth()
//// .padding(horizontal = 30.dp)
// ,
// horizontalArrangement = Arrangement.SpaceBetween,
// verticalAlignment = Alignment.CenterVertically
// ) {
// Text(label, style = AppTypography.gray96a0aaTextStyle)
// Spacer(modifier = Modifier.width(12.dp))
// if (dropdownItems.isEmpty()) {
// CustomTextField(
// modifier = Modifier.width(180.dp),
// value = value,
// onValueChange = onValueChange,
// textAlign = textAlign,
// trailingLabel = trailingLabel, inputType = inputType,
// textStyle = LocalTextStyle.current.copy(
// color = inputTextColor,
// fontSize = 24.sp,
// fontWeight = FontWeight.Bold,
// textAlign = textAlign
// )
// )
// } else {
// CustomDropdownTextField(
// modifier = Modifier.width(300.dp),
// value = value,
// dropdownItems = dropdownItems,
// onValueChange = onValueChange,
// textAlign = spinnerTextAlign,
// )
// }
// }
//}
//
///**
// * 未调整,显示右侧界面
// */
//@Composable
//fun ReceiptRightView(modifier: Modifier = Modifier, viewModel: ReceiptViewModel) {
// val selectedItem by viewModel.selectedItem.collectAsState()
// Column(
// modifier = modifier
// .fillMaxSize()
// .background(
// color = Color.White.copy(alpha = 0.37f),
// shape = RoundedCornerShape(10.dp) // 圆角背景
// )
// .padding(horizontal = 30.dp),
// horizontalAlignment = Alignment.CenterHorizontally
// ) {
// if (selectedItem == null) {
// Spacer(modifier = Modifier.height(30.dp))
// IdentityView(
// showSearchView = false,
// onOptionSelected = {},
// baseViewModel = viewModel,
// pageType = PageType.RECEIPT_PRODUCT
// )
// } else {
// ReceiptProductEditView(viewModel)
// }
// }
//}
//
///**
// * 收货界面右侧编辑
// */
//@Composable
//private fun ReceiptProductEditView(
// viewModel: ReceiptViewModel,
// onConfirmClick: () -> Unit = {},
// onCancelClick: () -> Unit = {}
//) {
// val selectedItem by viewModel.selectedItem.collectAsState()
// val warehouseTypeList = GlobalData.warehouseTypeList
//
// selectedItem?.let {
// Column(
// modifier = Modifier
// .fillMaxWidth()
// .fillMaxHeight()
// .padding(top = 20.dp, bottom = 20.dp),
// verticalArrangement = Arrangement.spacedBy(20.dp)
// ) {
// Spacer(modifier = Modifier.height(10.dp))
// Text(
// modifier = Modifier.fillMaxWidth(),
// textAlign = TextAlign.Center,
// text = selectedItem?.goodName ?: "-",
// style = AppTypography.black141428TextStyle.bold().withSize(30.sp),
// maxLines = 1,
// overflow = TextOverflow.Ellipsis,
// )
// Spacer(modifier = Modifier.height(20.dp))
//
// HorizontalDivider(
// modifier = Modifier
// .fillMaxWidth()
// .padding(),
// thickness = 1.dp,
// color = colorResource(R.color.divider)
// )
//
// RowInputLayout(
// label = "仓库",
// value = selectedItem!!.warehouseNameStr,
// dropdownItems = warehouseTypeList,
// onValueChange = { value ->
// selectedItem?.let {
// viewModel.updateSelectedItem(
// selectedItem!!.copy(
// warehouseName = value,
// warehouseId =
// warehouseTypeList.find { it.value == value }?.id ?: 0
//// storeList.indexOf(value)
// )
// )
// }
// })
// HorizontalDivider(
// modifier = Modifier
// .fillMaxWidth()
// .padding(),
// thickness = 1.dp,
// color = colorResource(R.color.divider)
// )
//
// RowInputLayout(
// label = "收货数量",
// value = selectedItem!!.receivedNumTemp,
// onValueChange = { value ->
// viewModel.updateCountInputState(true)
//
// selectedItem?.let {
// viewModel.updateSelectedItem(
// selectedItem!!.copy(
// receivedNumTemp = value,
// receivedNum = value.toSafeFloat()
// )
// )
// }
// },
// trailingLabel = selectedItem?.unitName,
// inputType = InputType.Decimal,
// isInitUpdate = true,
// keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
// )
//
// RowInputLayout(
// label = "收货单价",
// value = selectedItem!!.newRecUnitPriceTaxInTemp,
// trailingLabel = "元",
// isInitUpdate = true,
// onValueChange = { value ->
// viewModel.updatePriceInputState(true)
// viewModel.updateAmountInputState(false)
// selectedItem?.let {
// viewModel.updateSelectedItem(
// selectedItem!!.copy(
// recPriceExItemTemp = "",
// recPriceExItem = 0f,
// newRecUnitPriceTaxInTemp = value,
// newRecUnitPriceTaxIn = value.toSafeFloat()
// )
// )
// }
// }, inputType = InputType.Decimal,
// keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
// )
// RowInputLayout(
// label = "收货金额",
// value = selectedItem!!.recPriceExItemTemp,
// trailingLabel = "元",
// isInitUpdate = true,
// onValueChange = { value ->
// viewModel.updateAmountInputState(true)
// viewModel.updatePriceInputState(false)
// selectedItem?.let {
// viewModel.updateSelectedItem(
// selectedItem!!.copy(
// newRecUnitPriceTaxInTemp = "",
// newRecUnitPriceTaxIn = 0f,
//
// recPriceExItemTemp = value,
// recPriceExItem = value.toSafeFloat()
// )
// )
// }
// }, inputType = InputType.Decimal,
// keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
// )
//
// Row(
// modifier = Modifier
// .fillMaxWidth()
// .padding(horizontal = 30.dp),
// horizontalArrangement = Arrangement.SpaceBetween,
// verticalAlignment = Alignment.CenterVertically
// ) {
// Text(text = "物品重量", style = AppTypography.black141428TextStyle)
// CustomTextField(
// modifier = Modifier
// .width(290.dp)
// .height(60.dp),
// value = selectedItem!!.goodsWeightStr, onValueChange = {},
// enabled = false,
// isInitUpdate = true,
// textAlign = TextAlign.End,
// trailingLabel = selectedItem!!.goodsWeightUnitStr,
// inputType = InputType.Decimal,
// onClick = InteractionUtils.rememberDoubleClickDetector {
// Timber.d("物品重量 双击")
// SensorScaleUtils.tare()
// }
// )
// }
//
// HorizontalDivider(
// modifier = Modifier
// .fillMaxWidth()
// .padding(),
// thickness = 1.dp,
// color = colorResource(R.color.divider)
// )
// Spacer(modifier = Modifier.height(20.dp))
// Row(
// horizontalArrangement = Arrangement.SpaceAround,
// modifier = Modifier
// .fillMaxWidth()
// .height(80.dp)
// ) {
// Image(modifier = Modifier.clickable {
// viewModel.updateSelectedItem(null)
// }, painter = painterResource(R.mipmap.ic_btn_back), contentDescription = "返回")
// Image(modifier = Modifier.clickable {
// val errorInfo = selectedItem!!.hasNullField()
// if (errorInfo != null) {
// ToastUtils.showToast(errorInfo)
// return@clickable
// }
// val expectAmount =
// selectedItem!!.receivedNum!!.times(selectedItem!!.newRecUnitPriceTaxIn!!)
// .toSafeFloat()
// Timber.d("金额判断:期望金额 = $expectAmount, 实际金额 = ${selectedItem!!.recPriceExItem}")
//// if (expectAmount != selectedItem!!.recPriceExItem) {
//// ToastUtils.showToast("数量和金额不符,请检查后再试")
//// return@clickable
//// }
// viewModel.updatePurchaseItem(purchaseOrder = selectedItem!!.copy(isAdjusted = true))
// viewModel.updateSelectedItem(null)
// }, painter = painterResource(R.mipmap.ic_btn_confirm), contentDescription = "确定")
// }
// }
// }
//}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
//package com.sw.inbound.ui.page
//
//
//import android.annotation.SuppressLint
//import androidx.compose.runtime.Composable
//import androidx.compose.ui.Modifier
//import androidx.navigation.NavHostController
//
//
//@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
//@Composable
//fun TestScreen(modifier: Modifier.Companion, navController: NavHostController) {
//
//}
//
@@ -0,0 +1,64 @@
package com.sw.inbound.ui.theme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.sw.inbound.R
object AppTypography {
val gray96a0aaTextStyle: TextStyle
@Composable get() = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFF96A0AA)
)
val gray999999TextStyle: TextStyle
@Composable get() = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFF999999)
)
val black141428TextStyle: TextStyle
@Composable get() = TextStyle(
fontSize = 24.sp,
fontWeight = FontWeight.Medium,
color = Black_141428
)
val grayTextStyle: TextStyle
@Composable
get() = TextStyle(
color = colorResource(R.color.gray),
fontSize = 24.sp,
fontWeight = FontWeight.Medium
)
val blackTextStyle: TextStyle
@Composable
get() = TextStyle(
color = colorResource(R.color.black),
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
val blackMediumTextStyle: TextStyle
@Composable
get() = TextStyle(
color = colorResource(R.color.black),
fontSize = 24.sp,
fontWeight = FontWeight.Medium
)
val BlueTextStyle: TextStyle
@Composable
get() = TextStyle(
color = colorResource(R.color.blue),
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
}
@@ -0,0 +1,22 @@
package com.sw.inbound.ui.theme
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
val Black_141428 = Color(0xFF141428)
val Gray_A0A0B4 = Color(0XffA0A0B4)
val Gray_DCDCF0 = Color(0xFFDCDCF0)
val Gray_96A0AA = Color(0xFF96A0AA)
val GrayDivider = Color(0XFFDCDCF0)
val Green_009632 = Color(0xFF009632)
val Blue_0032C8 = Color(0xFF0032C8)
val Red_FF3232 = Color(0xFFFF3232)
@@ -0,0 +1,57 @@
package com.sw.inbound.ui.theme
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80
)
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
tertiary = Pink40
/* Other default colors to override
background = Color(0xFFFFFBFE),
surface = Color(0xFFFFFBFE),
onPrimary = Color.White,
onSecondary = Color.White,
onTertiary = Color.White,
onBackground = Color(0xFF1C1B1F),
onSurface = Color(0xFF1C1B1F),
*/
)
@Composable
fun InboundTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content,
)
}
@@ -0,0 +1,34 @@
package com.sw.inbound.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)
@@ -0,0 +1,105 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.sw.inbound.R
/**
* 底部按钮
*/
@Composable
fun BottomActionBar(
leftText: String = "返回",
right1ButtonText: String = "清空物品",
right2ButtonText: String = "新增收货",
showRight1Button: Boolean = false,
onLeftButtonClick: () -> Unit,
onRight1ButtonClick: () -> Unit = {},
onRight2ButtonClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 30.dp, end = 30.dp, bottom = 20.dp)
.height(100.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
// 左侧图标+文字
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.width(220.dp)
.height(100.dp)
.background(
color = colorResource(R.color.blue),
shape = RoundedCornerShape(10.dp)
)
.clickable {
onLeftButtonClick()
}
) {
Image(
painter = painterResource(R.mipmap.ic_back_white),
contentDescription = "返回",
modifier = Modifier.size(40.dp)
)
Spacer(modifier = Modifier.width(21.dp))
Text(
text = leftText,
style = TextStyle(
color = colorResource(R.color.white),
fontWeight = FontWeight.Bold,
fontSize = 36.sp
)
)
}
Row {
if (showRight1Button) {
CustomOutlinedButton(
modifier = modifier
.width(300.dp)
.height(100.dp),
text = right1ButtonText,
fontSize = 36.sp,
onClick = onRight1ButtonClick
)
Spacer(modifier = Modifier.width(20.dp))
}
CustomButton(
modifier = modifier
.width(300.dp)
.height(100.dp),
text = right2ButtonText,
onClick = onRight2ButtonClick,
borderColor = colorResource(R.color.blue),
textColor = colorResource(R.color.white),
fontSize = 36.sp
)
}
}
}
@@ -0,0 +1,193 @@
package com.sw.inbound.ui.weight
import android.net.Uri
import android.widget.Toast
import androidx.camera.view.CameraController
import androidx.camera.view.LifecycleCameraController
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
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.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.LocalLifecycleOwner
import coil.compose.AsyncImage
import com.sw.inbound.GlobalData
import com.sw.inbound.R
import com.sw.inbound.ext.dashedBorder
import com.sw.inbound.ui.theme.AppTypography
import com.sw.inbound.utils.FileUtils
import com.sw.inbound.utils.ToastUtils
import com.sw.inbound.utils.rememberPhotoCapture
import timber.log.Timber
/**
* 相机预览 -默认不预览,支持拍照
*/
@Composable
fun CameraCaptureLayout(
modifier: Modifier = Modifier
) {
val context = LocalContext.current
var showCamera by remember { mutableStateOf(false) }
val lifecycleOwner = LocalLifecycleOwner.current
var photoUri by remember { mutableStateOf<Uri?>(null) }
// CameraX 控制器
val cameraController = remember {
LifecycleCameraController(context).apply {
setEnabledUseCases(
CameraController.IMAGE_CAPTURE or
CameraController.VIDEO_CAPTURE
)
}
}
// 创建拍照工具实例
val (photoCaptureHelper, takePhoto) = rememberPhotoCapture(
cameraController = cameraController,
onSuccess = { savedUri ->
// 处理拍照成功的逻辑
photoUri = savedUri
Timber.d("photoUri = $photoUri")
Toast.makeText(context, "图片已保存", Toast.LENGTH_SHORT).show()
showCamera = false
GlobalData.imageUri = photoUri
},
onError = { error ->
// 处理拍照失败的逻辑
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
GlobalData.imageUri = null
}
)
Column(
modifier = modifier
.width(428.dp)
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(24.dp)
) {
if (showCamera) {
// 摄像头预览
CameraPreview(
modifier = Modifier
.width(428.dp)
.height(321.dp), controller = cameraController
)
} else {
if (photoUri == null) {
// 图片预览区域
Column(
modifier = Modifier
.fillMaxWidth()
.height(321.dp)
.dashedBorder(strokeWidth = 2.dp, cornerRadiusDp = 15.dp)
.clickable {
showCamera = true
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Image(
painter = painterResource(R.mipmap.ic_camera),
contentDescription = "默认图片",
modifier = Modifier
.width(96.dp)
.height(76.dp)
)
Spacer(modifier = Modifier.height(24.dp))
Text(
"图片采集",
style = AppTypography.grayTextStyle.copy(color = Color(0xFFB4B4C8))
)
}
} else {
Column(
modifier = Modifier
.fillMaxWidth()
.height(321.dp)
.dashedBorder(strokeWidth = 2.dp, cornerRadiusDp = 15.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
AsyncImage(
model = photoUri,
contentDescription = "照片",
modifier = Modifier.fillMaxSize()
)
}
}
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
CustomOutlinedButton(
modifier = Modifier
.weight(1f)
.height(80.dp),
text = "取消",
fontSize = 30.sp,
borderColor = colorResource(R.color.green),
textColor = colorResource(R.color.green),
onClick = {
Timber.d("点击取消")
showCamera = true
photoUri?.let {
FileUtils.deleteFileWithUri(context, photoUri!!)
}
photoUri = null
}
)
Spacer(modifier = Modifier.width(20.dp))
CustomButton(
modifier = Modifier
.weight(1f)
.height(80.dp),
text = "采集",
onClick = {
Timber.d("点击采集")
if (!showCamera) {
ToastUtils.showToast("请先开启图片预览")
return@CustomButton
}
takePhoto()
},
borderColor = colorResource(R.color.green),
textColor = colorResource(R.color.white),
fontSize = 30.sp,
showButtonIcon = true
)
}
}
// 生命周期管理
DisposableEffect(lifecycleOwner) {
Timber.d("cameraController")
cameraController.bindToLifecycle(lifecycleOwner)
onDispose { }
}
}
@@ -0,0 +1,52 @@
package com.sw.inbound.ui.weight
import android.net.Uri
import androidx.camera.view.LifecycleCameraController
import androidx.camera.view.PreviewView
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import coil.compose.AsyncImage
import com.sw.inbound.R
/**
* 相机预览
*/
@Composable
fun CameraPreview(
controller: LifecycleCameraController,
modifier: Modifier = Modifier,
photoUri: Uri? = null
) {
Box(modifier = modifier) {
AndroidView(
factory = { ctx ->
PreviewView(ctx).apply {
this.controller = controller
scaleType = PreviewView.ScaleType.FILL_CENTER // 控制预览缩放
}
},
modifier = Modifier.fillMaxSize()
)
if (photoUri != null) {
AsyncImage(
modifier = Modifier.fillMaxSize(),
model = photoUri,
contentDescription = "照片",
)
}
Image(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
painter = painterResource(R.mipmap.ic_scan),
contentDescription = "扫描"
)
}
}
@@ -0,0 +1,108 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.sw.inbound.R
/**
* 空心按钮
*/
@Composable
fun CustomOutlinedButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
textColor: Color = colorResource(R.color.blue),
borderColor: Color = Color.Blue,
cornerRadius: Dp = 8.dp,
borderWidth: Dp = 1.dp,
fontWeight: FontWeight = FontWeight.Bold,
fontSize: TextUnit = 24.sp
) {
OutlinedButton(
onClick = onClick,
modifier = modifier,
shape = RoundedCornerShape(cornerRadius),
border = BorderStroke(borderWidth, color = borderColor),
colors = ButtonDefaults.buttonColors(
containerColor = Color.Transparent,
contentColor = textColor
)
) {
Text(
text = text,
style = TextStyle(
fontWeight = fontWeight,
fontSize = fontSize,
color = textColor
)
)
}
}
/**
* 实心按钮
*/
@Composable
fun CustomButton(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
textColor: Color = colorResource(R.color.white),
borderColor: Color = colorResource(R.color.green),
cornerRadius: Dp = 8.dp,
borderWidth: Dp = 1.dp,
fontWeight: FontWeight = FontWeight.Bold,
fontSize: TextUnit = 24.sp,
showButtonIcon: Boolean = false
) {
Button(
onClick = onClick,
modifier = modifier,
shape = RoundedCornerShape(cornerRadius),
border = BorderStroke(borderWidth, color = borderColor),
colors = ButtonDefaults.buttonColors(
containerColor = borderColor,
contentColor = textColor
)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
if (showButtonIcon) {
Image(
painter = painterResource(R.mipmap.ic_camera_small),
contentDescription = "采集"
)
Spacer(modifier = Modifier.width(13.dp))
}
Text(
text = text,
style = TextStyle(
fontWeight = fontWeight,
fontSize = fontSize,
color = textColor
)
)
}
}
}
@@ -0,0 +1,113 @@
//package com.sw.inbound.ui.weight
//
//import androidx.compose.foundation.background
//import androidx.compose.foundation.border
//import androidx.compose.foundation.layout.fillMaxWidth
//import androidx.compose.foundation.shape.RoundedCornerShape
//import androidx.compose.material3.DropdownMenuItem
//import androidx.compose.material3.ExperimentalMaterial3Api
//import androidx.compose.material3.ExposedDropdownMenuBox
//import androidx.compose.material3.ExposedDropdownMenuDefaults
//import androidx.compose.material3.LocalTextStyle
//import androidx.compose.material3.MenuAnchorType.Companion.PrimaryNotEditable
//import androidx.compose.material3.Text
//import androidx.compose.material3.TextField
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.getValue
//import androidx.compose.runtime.mutableStateOf
//import androidx.compose.runtime.remember
//import androidx.compose.runtime.setValue
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.res.colorResource
//import androidx.compose.ui.text.TextStyle
//import androidx.compose.ui.text.font.FontWeight
//import androidx.compose.ui.text.style.TextAlign
//import androidx.compose.ui.unit.dp
//import androidx.compose.ui.unit.sp
//import com.sw.inbound.R
//import com.sw.inbound.model.response.DictType
//import com.sw.inbound.ui.theme.AppTypography
//import com.sw.inbound.ui.theme.Black_141428
//
///**
// * 表单中的下拉菜单
// */
//@OptIn(ExperimentalMaterial3Api::class)
//@Composable
//fun CustomDropdownTextField(
// value: String,
// onValueChange: (String) -> Unit,
// dropdownItems: List<DictType>,
// modifier: Modifier = Modifier,
// placeholderValue: String = "请选择",
// textAlign: TextAlign = TextAlign.Start,
// textStyle: TextStyle? = null,
// enabled: Boolean = true,
//) {
// var expanded by remember { mutableStateOf(false) }
// var newTextStyle = textStyle
// ?: LocalTextStyle.current.copy(
// color = Black_141428,
// fontSize = 24.sp,
// fontWeight = FontWeight.Bold,
// textAlign = textAlign
// )
//
// ExposedDropdownMenuBox(
// modifier = modifier,
// expanded = expanded || !enabled,
// onExpandedChange = { expanded = it },
// ) {
// TextField(
// value = value,
// onValueChange = onValueChange,
// readOnly = true,
// textStyle = newTextStyle,
//
// shape = RoundedCornerShape(10.dp),
// trailingIcon = {
// ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
// },
// colors = ExposedDropdownMenuDefaults.textFieldColors(
// focusedContainerColor = Color.Transparent,
// unfocusedContainerColor = Color.Transparent,
// disabledContainerColor = Color.Transparent,
// focusedIndicatorColor = Color.Transparent,
// unfocusedIndicatorColor = Color.Transparent
// ),
// placeholder = {
// Text(
// modifier = modifier.fillMaxWidth(),
// text = placeholderValue, style = AppTypography.gray96a0aaTextStyle.copy(
// textAlign = textAlign
// )
// )
// },
// modifier = Modifier
// .fillMaxWidth()
// .background(Color.Transparent)
// .border(
// width = 2.dp,
// color = colorResource(R.color.border_line),
// shape = RoundedCornerShape(10.dp)
// )
// .menuAnchor(PrimaryNotEditable, true)
// )
//
// ExposedDropdownMenu(
// expanded = expanded,
// onDismissRequest = { expanded = false }
// ) {
// dropdownItems.forEach { item ->
// DropdownMenuItem(
// text = { Text(text = item.value?:"", style = AppTypography.black141428TextStyle) },
// onClick = {
// onValueChange(item.value?:"")
// expanded = false
// }
// )
// }
// }
// }
//}
@@ -0,0 +1,99 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.sw.inbound.R
import com.sw.inbound.ui.theme.AppTypography
import timber.log.Timber
/**
* 搜索框
*/
@Composable
fun CustomSearchView(onValueChange: (String) -> Unit = {}, onSearchClick: (String) -> Unit) {
var searchText by remember { mutableStateOf("") }
val borderColor = Color(0xFFDCDCF0)
val focusManager = LocalFocusManager.current
// 搜索框
Box(
modifier = Modifier
.fillMaxWidth()
.height(60.dp)
.border(
width = 2.dp,
color = borderColor,
shape = RoundedCornerShape(10.dp) // 圆角边框
)
.background(Color.Transparent) // 透明背景
) {
TextField(
value = searchText,
onValueChange = {
searchText = it
onValueChange
},
modifier = Modifier
.fillMaxWidth()
.padding(end = 25.dp), // 为图标留出空间
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
disabledContainerColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
),
placeholder = {
Text("输入物品名称", style = AppTypography.gray96a0aaTextStyle)
},
singleLine = true,
textStyle = AppTypography.black141428TextStyle,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Search
),
keyboardActions = KeyboardActions(onSearch = {
focusManager.clearFocus()
onSearchClick(searchText)
}),
trailingIcon = {
Image(
painter = painterResource(R.mipmap.ic_search),
contentDescription = "搜索",
modifier = Modifier
.width(32.dp)
.height(32.dp)
.clickable {
Timber.d("搜索点击")
focusManager.clearFocus()
onSearchClick(searchText)
}
)
},
)
}
}
@@ -0,0 +1,29 @@
package com.sw.inbound.ui.weight
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import com.sw.inbound.ui.theme.AppTypography
/**
* 自定义单行文本
*/
@Composable
fun CustomSingleRightText(
modifier: Modifier,
text: String,
style: TextStyle = AppTypography.blackTextStyle,
textAlign: TextAlign = TextAlign.End
) {
Text(
modifier = modifier,
text = text,
textAlign = textAlign,
style = style,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -0,0 +1,106 @@
//package com.sw.inbound.ui.weight
//
//import androidx.compose.foundation.background
//import androidx.compose.foundation.shape.RoundedCornerShape
//import androidx.compose.material3.DropdownMenuItem
//import androidx.compose.material3.ExperimentalMaterial3Api
//import androidx.compose.material3.ExposedDropdownMenuBox
//import androidx.compose.material3.ExposedDropdownMenuDefaults
//import androidx.compose.material3.MenuAnchorType.Companion.PrimaryNotEditable
//import androidx.compose.material3.Text
//import androidx.compose.material3.TextField
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.getValue
//import androidx.compose.runtime.mutableStateOf
//import androidx.compose.runtime.remember
//import androidx.compose.runtime.setValue
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.res.colorResource
//import androidx.compose.ui.text.TextStyle
//import androidx.compose.ui.text.font.FontWeight
//import androidx.compose.ui.unit.dp
//import androidx.compose.ui.unit.sp
//import com.sw.inbound.R
//import com.sw.inbound.model.response.DictType
//
///**
// * 自定义顶部仓库下拉
// */
//@OptIn(ExperimentalMaterial3Api::class)
//@Composable
//fun CustomSpinner(
// items: List<DictType>,
// selectedItem: String,
// onItemSelected: (DictType) -> Unit,
// modifier: Modifier = Modifier,
//) {
//// var expanded by remember { mutableStateOf(false) }
// var expanded by remember { mutableStateOf(true) }
//
// ExposedDropdownMenuBox(
// expanded = expanded,
// onExpandedChange = { expanded = !expanded },
// modifier = modifier.background(
// color = Color(0x80FFFFFF),
// shape = RoundedCornerShape(10.dp) // 圆角背景
// )
// ) {
// TextField(
// value = selectedItem,
// onValueChange = {},
// readOnly = true,
// textStyle = TextStyle(
// color = Color.White,
// fontSize = 24.sp,
// fontWeight = FontWeight.Bold
// ),
// shape = RoundedCornerShape(10.dp),
// trailingIcon = {
// ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
// },
// colors = ExposedDropdownMenuDefaults.textFieldColors(
// focusedContainerColor = colorResource(R.color.blue),
// unfocusedContainerColor = colorResource(R.color.blue),
// disabledContainerColor = colorResource(R.color.blue),
// focusedTextColor = Color.White,
// unfocusedTextColor = Color.White,
// cursorColor = Color.White,
// focusedIndicatorColor = Color.Transparent,
// unfocusedIndicatorColor = Color.Transparent,
// focusedLabelColor = Color.White.copy(alpha = 0.8f),
// unfocusedLabelColor = Color.White.copy(alpha = 0.8f),
// focusedTrailingIconColor = Color.White,
// unfocusedTrailingIconColor = Color.White
// ),
// modifier = Modifier.menuAnchor(PrimaryNotEditable, true)
// )
//
// ExposedDropdownMenu(
// expanded = expanded,
// onDismissRequest = { expanded = false },
// modifier = Modifier
// .background(colorResource(R.color.blue))
// .exposedDropdownSize(matchTextFieldWidth = true)
// ) {
// items.forEach { item ->
// DropdownMenuItem(
// text = {
// Text(
// text = item.value?:"",
// style = TextStyle(
// color = Color.White,
// fontSize = 24.sp,
// fontWeight = FontWeight.Bold
// ),
// )
// },
// onClick = {
// onItemSelected(item)
// expanded = false
// }
// )
// }
// }
// }
//}
@@ -0,0 +1,226 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.sw.inbound.ext.isValidFloat
import com.sw.inbound.ext.isValidNumber
import com.sw.inbound.ui.theme.AppTypography
import com.sw.inbound.ui.theme.Black_141428
import com.sw.inbound.ui.theme.Gray_DCDCF0
import timber.log.Timber
//@Preview(showBackground = true)
//@Composable
//fun testTextField() {
// Column(verticalArrangement = Arrangement.spacedBy(10.dp), modifier = Modifier.padding(20.dp)) {
// CustomTextField(value = "123", onValueChange = {}, textAlign = TextAlign.Start)
// CustomTextField(value = "", onValueChange = {}, textAlign = TextAlign.Start)
// CustomTextField(value = "", onValueChange = {}, textAlign = TextAlign.End)
// CustomTextField(
// value = "123",
// onValueChange = {},
// textAlign = TextAlign.End,
// trailingLabel = "克"
// )
// CustomTextField(
// enabled = false,
// modifier = Modifier
// .height(60.dp),
// value = "123",
// onValueChange = {},
// textAlign = TextAlign.End,
// leadingIcon =
// {
// Button(
// onClick = {},
// modifier = Modifier
// .padding(0.dp)
// .fillMaxHeight(),
// shape = RoundedCornerShape(10.dp),
// border = BorderStroke(2.dp, color = Color.White),
// colors = ButtonDefaults.buttonColors(
// containerColor = Color.White,
// contentColor = Black_141428
// ),
// ) { Text(text = "累计", style = AppTypography.black141428TextStyle) }
// }
// )
// }
//
//}
enum class InputType {
Text, // 字符串
Number, // 数字
Decimal, // 浮点
Percent, // 百分比
}
/**
* 自定义输入框
*/
@Composable
fun CustomTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier.height(60.dp),
placeholderValue: String = "请录入", // 占位文本
trailingLabel: String? = null, // 右侧文字
textAlign: TextAlign = TextAlign.Start,
textStyle: TextStyle? = null,
leadingIcon: @Composable (() -> Unit)? = null, // 左侧布局
enabled: Boolean = true,
inputType: InputType = InputType.Text, // 输入类型
hasNext: Boolean = true, // 键盘显示下一个
isInitUpdate: Boolean = false, // 是否需要根据原始数据变动
keyboardOptions: KeyboardOptions? = null,
keyboardActions: KeyboardActions? = null,
onClick: () -> Unit = {}, // 点击
) {
val containerColor = if (enabled) Color.Transparent else Gray_DCDCF0
var inputValue by remember(if (isInitUpdate) value else null) {
mutableStateOf(value)
}
val focusManager = LocalFocusManager.current
fun onEditingComplete(isFocus: Boolean) {
Timber.d("onEditingComplete inputValue = $inputValue, isFocus = $isFocus")
onValueChange(inputValue)
}
var newTextStyle = textStyle
?: LocalTextStyle.current.copy(
color = Black_141428,
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
textAlign = textAlign
)
Box(modifier = modifier) {
TextField(
enabled = enabled,
value = inputValue,
textStyle = newTextStyle,
onValueChange = { newValue ->
Timber.d("onValueChange newValue = $newValue")
when (inputType) {
InputType.Number -> {
if (newValue.isEmpty() || newValue.isValidNumber()) {
inputValue = newValue
onEditingComplete(true)
}
}
InputType.Decimal -> {
if (newValue.isEmpty() || newValue.isValidFloat()) {
inputValue = newValue
onEditingComplete(true)
}
}
InputType.Percent -> {
val range: ClosedFloatingPointRange<Float> = 0f..100f
if (newValue.isEmpty() || (newValue.isValidFloat(1) && newValue.toFloat() in range)) {
inputValue = newValue
onEditingComplete(true)
}
}
else -> {
inputValue = newValue
onEditingComplete(true)
}
}
},
modifier = Modifier
.fillMaxWidth()
.background(Color.Transparent)
.border(
width = 2.dp,
color = Gray_DCDCF0,
shape = RoundedCornerShape(10.dp)
)
.clickable(onClick = onClick)
// .focusable()
.onFocusChanged(onFocusChanged = { focusState ->
{
onEditingComplete(focusState.isFocused)
}
}),
colors = TextFieldDefaults.colors(
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
disabledContainerColor = containerColor,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
),
shape = RoundedCornerShape(10.dp),
placeholder = {
Text(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.wrapContentHeight(Alignment.CenterVertically),
text = placeholderValue,
textAlign = textAlign,
style = AppTypography.gray96a0aaTextStyle
)
},
leadingIcon = leadingIcon,
trailingIcon = trailingLabel?.let { label ->
{
Box(modifier = Modifier.padding(start = 10.dp, end = 20.dp)) {
Text(
text = trailingLabel,
modifier = Modifier
.fillMaxHeight()
.wrapContentHeight(Alignment.CenterVertically),
style = AppTypography.gray96a0aaTextStyle
)
}
}
},
keyboardOptions = keyboardOptions
?: KeyboardOptions.Default.copy(imeAction = if (hasNext) ImeAction.Next else ImeAction.Done),
keyboardActions = keyboardActions ?: KeyboardActions(onNext = {
focusManager.moveFocus(focusDirection = FocusDirection.Next)
onEditingComplete(false)
}, onDone = {
focusManager.clearFocus()
onEditingComplete(false)
})
)
}
}
@@ -0,0 +1,126 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.sw.inbound.R
@Preview
@Composable
fun BackButton() {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 30.dp, end = 30.dp, bottom = 20.dp)
.height(100.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
// 左侧图标+文字
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.width(220.dp)
.height(100.dp)
.background(
color = colorResource(R.color.blue),
shape = RoundedCornerShape(10.dp)
)
.clickable {
}
) {
Image(
painter = painterResource(R.mipmap.ic_back_white),
contentDescription = "返回",
modifier = Modifier.size(40.dp)
)
Spacer(modifier = Modifier.width(21.dp))
Text(
text = "返回",
style = TextStyle(
color = colorResource(R.color.white),
fontWeight = FontWeight.Bold,
fontSize = 36.sp
)
)
}
// Row {
// if (false) {
// CustomOutlinedButton(
// modifier = Modifier
// .width(300.dp)
// .height(100.dp),
// text = "ok",
// fontSize = 36.sp,
// onClick = {}
// )
// Spacer(modifier = Modifier.width(20.dp))
// }
// CustomButton(
// modifier = Modifier
// .width(300.dp)
// .height(100.dp),
// text = "Button",
// onClick = {},
// borderColor = colorResource(R.color.blue),
// textColor = colorResource(R.color.white),
// fontSize = 36.sp
// )
// }
}
}
@Composable
fun BackButton2() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.width(220.dp)
.height(100.dp)
.background(
color = colorResource(R.color.blue),
shape = RoundedCornerShape(10.dp)
)
.clickable {
}
) {
Image(
painter = painterResource(R.mipmap.ic_home2),
contentDescription = "返回",
modifier = Modifier.size(40.dp)
)
Spacer(modifier = Modifier.width(21.dp))
Text(
text = "返回",
style = TextStyle(
color = colorResource(R.color.white),
fontWeight = FontWeight.Bold,
fontSize = 36.sp
)
)
}
}
@@ -0,0 +1,46 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.sw.inbound.ext.withColor
import com.sw.inbound.network.LoadingState
import com.sw.inbound.ui.theme.AppTypography
/**
* 全局加载进度
*/
@Composable
fun GlobalLoading() {
if (LoadingState.isLoading) {
Dialog(
onDismissRequest = {},
properties = DialogProperties(
dismissOnBackPress = false,
dismissOnClickOutside = false
)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
CircularProgressIndicator(modifier = Modifier)
Spacer(modifier = Modifier.height(20.dp))
Text(
text = "请稍等...",
style = AppTypography.grayTextStyle.withColor(color = Color.White)
)
}
}
}
}
@@ -0,0 +1,216 @@
//package com.sw.inbound.ui.weight
//
//import android.widget.Toast
//import androidx.camera.view.CameraController
//import androidx.camera.view.LifecycleCameraController
//import androidx.compose.foundation.layout.Column
//import androidx.compose.foundation.layout.Spacer
//import androidx.compose.foundation.layout.fillMaxSize
//import androidx.compose.foundation.layout.height
//import androidx.compose.foundation.layout.width
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.DisposableEffect
//import androidx.compose.runtime.LaunchedEffect
//import androidx.compose.runtime.collectAsState
//import androidx.compose.runtime.getValue
//import androidx.compose.runtime.mutableDoubleStateOf
//import androidx.compose.runtime.mutableIntStateOf
//import androidx.compose.runtime.mutableStateOf
//import androidx.compose.runtime.remember
//import androidx.compose.runtime.setValue
//import androidx.compose.ui.Alignment
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.platform.LocalContext
//import androidx.compose.ui.unit.dp
//import androidx.core.content.ContextCompat
//import androidx.lifecycle.compose.LocalLifecycleOwner
//import com.sw.inbound.ext.medium
//import com.sw.inbound.model.request.PurchaseWarehouseParam
//import com.sw.inbound.model.response.SearchGoodsInfo
//import com.sw.inbound.ui.theme.AppTypography
//import com.sw.inbound.utils.InteractionUtils.Debouncer
//import com.sw.inbound.utils.rememberPhotoCapture
//import com.sw.inbound.viewmodel.BaseViewModel
//import com.sw.inbound.viewmodel.ReceiptViewModel
//import com.sw.inbound.viewmodel.SelfProcurementViewModel
//import timber.log.Timber
//
//enum class PageType {
// /**
// * 自采
// */
// SELF_PROCUREMENT,
//
// /**
// * 收货
// */
// RECEIPT_PRODUCT
//}
//
///**
// * 菜品识别组件
// */
//@Composable
//fun IdentityView(
// showSearchView: Boolean = false,
// onOptionSelected: (SearchGoodsInfo.Record) -> Unit = {},
// checkedItem: PurchaseWarehouseParam? = null,
// baseViewModel: BaseViewModel,
// pageType: PageType
//) {
// val context = LocalContext.current
// val lifecycleOwner = LocalLifecycleOwner.current
// val weightInfo by baseViewModel.weightInfo.collectAsState()
// val identityList by baseViewModel.identityListItems.collectAsState()
// val receiptList by baseViewModel.receiptList.collectAsState()
// val searchList by baseViewModel.searchListItems.collectAsState()
//// var lastWeight by remember { mutableStateOf<Double?>(null) }
// var lastWeight by remember { mutableDoubleStateOf(0.0) }
// val lastPhotoUri by baseViewModel.lastPhotoUri.collectAsState()
// var pageNum by remember { mutableIntStateOf(1) }
// val isMoreLoading by baseViewModel.isMoreLoading.collectAsState()
// val canLoadMore by baseViewModel.canLoadMore.collectAsState()
// var list = if (identityList.isNotEmpty()) {
// identityList
// } else {
// searchList
// }
// val debouncer = remember { Debouncer(2000) }
// var isCameraReady by remember { mutableStateOf(false) }
//
// // CameraX 控制器
// val cameraController = remember {
// LifecycleCameraController(context).apply {
// // 必须设置有效的用例
// setEnabledUseCases(
// CameraController.IMAGE_CAPTURE or
// CameraController.VIDEO_CAPTURE
// )
// }
// }
//
// // 需要搜索的信息
// var searchInfo by remember { mutableStateOf("") }
// // 创建拍照工具实例
// val (photoCaptureHelper, takePhoto) = rememberPhotoCapture(
// cameraController = cameraController,
// onSuccess = { savedUri ->
// // 处理拍照成功的逻辑
// baseViewModel.updateLastPhotoUri(savedUri)
// Timber.d("photoUri = $savedUri")
// if (pageType == PageType.SELF_PROCUREMENT) {
// (baseViewModel as SelfProcurementViewModel).updateSelectedItem(null)
// } else if (pageType == PageType.RECEIPT_PRODUCT) {
// (baseViewModel as ReceiptViewModel).updateSelectedItem(null)
// }
// baseViewModel.getIdentityList(savedUri)
// },
// onError = { error ->
// // 处理拍照失败的逻辑
// Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
// baseViewModel.updateLastPhotoUri(null)
// }
// )
//
// // 绑定生命周期
// DisposableEffect(lifecycleOwner) {
// cameraController.bindToLifecycle(lifecycleOwner)
// onDispose {
// cameraController.unbind()
// isCameraReady = false
// }
// }
//
// LaunchedEffect(weightInfo) {
// Timber.d("LaunchedEffect weightInfo1 = $weightInfo, lastWeight = $lastWeight")
// if (weightInfo - lastWeight > 1.0) {
// Timber.d("LaunchedEffect pageType = $pageType, receiptList = ${receiptList.size}")
// var canIdentity = false
// if (pageType == PageType.RECEIPT_PRODUCT) {
// val selectItem = (baseViewModel as ReceiptViewModel).selectedItem.value
// canIdentity =
// receiptList.isNotEmpty() && (selectItem == null || selectItem.goodId.isNullOrBlank())
// } else if (pageType == PageType.SELF_PROCUREMENT) {
// val selectItem = (baseViewModel as SelfProcurementViewModel).selectedItem.value
// canIdentity = selectItem == null || selectItem.goodsId.isNullOrBlank()
// }
// Timber.d("LaunchedEffect canIdentity = $canIdentity")
// if (canIdentity) {
// debouncer.debounce {
// Timber.d("LaunchedEffect isCameraReady = $isCameraReady")
// if (isCameraReady) {
// takePhoto()
// }
// }
// }
// }
// lastWeight = weightInfo
// }
//
// // 监听相机初始化
// LaunchedEffect(Unit) {
// try {
// cameraController.initializationFuture.addListener({
// isCameraReady = true
// Timber.d("Camera initialized successfully")
// }, ContextCompat.getMainExecutor(context))
// } catch (e: Exception) {
// Timber.d("Camera initialized error = ${e.message}")
// }
// }
//
// Column(
// modifier = Modifier
// .fillMaxSize(),
// horizontalAlignment = Alignment.CenterHorizontally
// ) {
// CameraPreview(
// modifier = Modifier
// .width(397.dp)
// .height(298.dp),
// controller = cameraController,
// photoUri = lastPhotoUri
// )
// if (showSearchView) {
// Spacer(modifier = Modifier.height(30.dp))
// CustomSearchView(onSearchClick = {
// if (pageType == PageType.SELF_PROCUREMENT) {
// (baseViewModel as SelfProcurementViewModel).updateSelectedItem(null)
// }
// searchInfo = it
// baseViewModel.searchGoodsInfoList(it)
// })
// }
// Spacer(modifier = Modifier.height(30.dp))
// if (showSearchView) {
// SingleSelectButtonGroup(
// modifier = Modifier
// .height(64.dp)
// .width(192.dp), options = list,
// onOptionSelected = onOptionSelected,
// onLoadMore = {
// Timber.d("加载更多 canLoadMore = $canLoadMore")
// if (!canLoadMore) {
// return@SingleSelectButtonGroup
// }
// pageNum++
// baseViewModel.searchGoodsInfoList(goodsName = searchInfo, pageNo = pageNum)
// },
// checkedItem = list.find { it.goodsId == checkedItem?.goodsId },
// isMoreLoading = isMoreLoading,
// canLoadMore = canLoadMore
// )
// } else {
// SingleSelectButtonGroup(
// modifier = Modifier
// .height(70.dp)
// .width(215.dp),
// options = list,
// horizontalSpacing = 30.dp,
// verticalSpacing = 20.dp,
// onOptionSelected = onOptionSelected,
// unSelectedTextStyle = AppTypography.blackTextStyle.medium()
// )
// }
// }
//}
@@ -0,0 +1,157 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.sw.inbound.R
import com.sw.inbound.ext.bold
import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.ui.theme.AppTypography
import com.sw.inbound.ui.theme.Gray_DCDCF0
/**
* 收货-未调整列表
*/
@Composable
fun ReceiptUnadjustedListView(
modifier: Modifier = Modifier,
productList: List<GoodsInfo>,
checkedItem: GoodsInfo? = null,
onItemCheckedClick: (Int, GoodsInfo) -> Unit = { _, _ -> },
showClose: Boolean = false,
onCloseClick: (GoodsInfo) -> Unit = {},
) {
var selectIndex by remember { mutableIntStateOf(-1) }
Column(
modifier = modifier
// .padding(horizontal = 30.dp)
) {
// 左侧列表标题
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 60.dp)
.height(84.dp),
verticalAlignment = Alignment.CenterVertically
) {
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "名称",
style = AppTypography.gray96a0aaTextStyle.bold(),
textAlign = TextAlign.Start
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.width(120.dp),
text = "单价(元)",
style = AppTypography.gray96a0aaTextStyle.bold()
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(200.dp),
text = "数量",
style = AppTypography.gray96a0aaTextStyle.bold()
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(120.dp),
text = "金额(元)",
style = AppTypography.gray96a0aaTextStyle.bold()
)
if (showClose) {
Spacer(modifier = Modifier.width(78.dp))
}
}
// Spacer(modifier = Modifier.height(31.dp))
HorizontalDivider(thickness = 1.dp, color = colorResource(R.color.divider))
// Spacer(modifier = Modifier.height(31.dp))
// 左侧列表
LazyColumn() {
itemsIndexed(
items = productList,
// key = { index, it -> it.id ?: index }) { index, it ->
key = { index, it -> index }) { index, it ->
val checkedBg =
if (/*selectIndex == index ||*/ checkedItem?.id == it.id) Gray_DCDCF0 else Color.Transparent
Row(
modifier = Modifier
.background(color = checkedBg)
.height(80.dp)
.padding(horizontal = 60.dp)
.clickable {
selectIndex = index
onItemCheckedClick(index, it)
}, verticalAlignment = Alignment.CenterVertically
) {
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = it.goodNameStr,
textAlign = TextAlign.Start
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.width(120.dp),
text = it.recUnitPriceTaxInListStr,
style = AppTypography.blackTextStyle
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(200.dp),
text = "${it.dualCountStr}${it.unitNameStr}",
style = AppTypography.blackTextStyle
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(120.dp),
text = it.recPriceExItemListStr,
style = AppTypography.blackTextStyle
)
if (showClose) {
Spacer(modifier = Modifier.width(30.dp))
Image(
modifier = Modifier
.size(48.dp)
.clickable {
onCloseClick(it)
},
painter = painterResource(R.mipmap.ic_delete),
contentDescription = "删除"
)
}
}
// Spacer(modifier = Modifier.height(33.dp))
// if (productList.indexOf(it) != productList.lastIndex)
HorizontalDivider(
thickness = 1.dp,
color = colorResource(R.color.divider)
)
// Spacer(modifier = Modifier.height(33.dp))
}
}
}
}
@@ -0,0 +1,83 @@
//package com.sw.inbound.ui.weight
//
//import androidx.compose.foundation.Image
//import androidx.compose.foundation.clickable
//import androidx.compose.foundation.layout.Arrangement
//import androidx.compose.foundation.layout.Row
//import androidx.compose.foundation.layout.Spacer
//import androidx.compose.foundation.layout.fillMaxWidth
//import androidx.compose.foundation.layout.height
//import androidx.compose.foundation.layout.padding
//import androidx.compose.foundation.layout.width
//import androidx.compose.foundation.text.KeyboardActions
//import androidx.compose.foundation.text.KeyboardOptions
//import androidx.compose.material3.Text
//import androidx.compose.runtime.Composable
//import androidx.compose.ui.Alignment
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.res.painterResource
//import androidx.compose.ui.text.style.TextAlign
//import androidx.compose.ui.unit.dp
//import com.sw.inbound.R
//import com.sw.inbound.model.response.DictType
//import com.sw.inbound.ui.theme.AppTypography
//
///**
// * 横向输入框 包含左侧文件+右侧输入框
// */
//@Composable
//fun RowInputLayout(
// label: String, // 左侧文字
// value: String,
// onValueChange: (String) -> Unit,
// dropdownItems: List<DictType>? = null, // 下拉列表
// hasNext: Boolean = true, // 键盘显示下一步
// inputType: InputType = InputType.Text,
// trailingLabel: String? = null, // 尾部文字
// keyboardOptions: KeyboardOptions? = null,
// keyboardActions: KeyboardActions? = null,
// isInitUpdate: Boolean = false, // 是否根据原始数据更新
// showRightButton: Boolean = false,
// onRightButtonClick: () -> Unit = {},
//) {
// val textWidth = if (showRightButton) 218.dp else 290.dp
// Row(
// modifier = Modifier
// .height(60.dp)
// .fillMaxWidth()
// .padding(horizontal = 30.dp),
// horizontalArrangement = Arrangement.SpaceBetween,
// verticalAlignment = Alignment.CenterVertically
// ) {
// Text(label, style = AppTypography.black141428TextStyle)
//// Spacer(modifier = Modifier.width(67.dp))
// Spacer(modifier = Modifier.weight(1f))
// if (dropdownItems == null) {
// CustomTextField(
// modifier = Modifier.width(textWidth),
// value = value, onValueChange = onValueChange,
// textAlign = TextAlign.End,
// trailingLabel = trailingLabel,
// hasNext = hasNext,
// inputType = inputType,
// keyboardOptions = keyboardOptions,
// keyboardActions = keyboardActions,
// isInitUpdate = isInitUpdate
// )
// } else {
// CustomDropdownTextField(
// modifier = Modifier.width(textWidth),
// value = value,
// dropdownItems = dropdownItems,
// onValueChange = onValueChange,
// textAlign = TextAlign.End
// )
// }
// if (showRightButton) {
// Spacer(modifier = Modifier.width(12.dp))
// Image(modifier = Modifier.clickable {
// onRightButtonClick()
// }, painter = painterResource(R.drawable.ic_add), contentDescription = "添加")
// }
// }
//}
@@ -0,0 +1,145 @@
package com.sw.inbound.ui.weight
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.sw.inbound.R
import com.sw.inbound.ext.bold
import com.sw.inbound.model.request.PurchaseWarehouseParam
import com.sw.inbound.ui.theme.AppTypography
/**
* 自采购 左侧列表
*/
@Composable
fun SelfProcurementListItem(
modifier: Modifier = Modifier,
productList: List<PurchaseWarehouseParam>,
checkedItem: PurchaseWarehouseParam? = null,
onItemCheckedClick: (PurchaseWarehouseParam) -> Unit = {},
showClose: Boolean = false,
onCloseClick: (Int, PurchaseWarehouseParam) -> Unit,
) {
Column(
modifier = modifier
// .padding(horizontal = 30.dp)
) {
// 左侧列表标题
Row(
modifier = Modifier
.fillMaxWidth()
.padding(30.dp)
) {
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "名称",
style = AppTypography.gray96a0aaTextStyle.bold(),
textAlign = TextAlign.Start
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.width(100.dp),
text = "单价(元)",
style = AppTypography.gray96a0aaTextStyle.bold()
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(100.dp),
text = "数量",
style = AppTypography.gray96a0aaTextStyle.bold()
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(110.dp),
text = "金额(元)",
style = AppTypography.gray96a0aaTextStyle.bold()
)
if (showClose) {
Spacer(modifier = Modifier.width(78.dp))
}
}
// Spacer(modifier = Modifier.height(31.dp))
HorizontalDivider(thickness = 1.dp, color = colorResource(R.color.divider))
// Spacer(modifier = Modifier.height(31.dp))
// 左侧列表
LazyColumn() {
itemsIndexed(items = productList)
// items(
// items = productList,
// // 取消key,列表中可以插入同一物品
//// key = { it.goodsId }
// )
{ index, it ->
Row(
modifier = Modifier
.background(color = Color.Transparent)
.padding(30.dp)
.clickable {
onItemCheckedClick(it)
}, verticalAlignment = Alignment.CenterVertically
) {
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = it.goodsNameStr,
textAlign = TextAlign.Start
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.width(100.dp),
text = it.goodsUnitPriceStr,
style = AppTypography.blackTextStyle
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(100.dp),
text = "${it.goodsCountStr}${it.unitNameStr}",
style = AppTypography.blackTextStyle
)
Spacer(modifier = Modifier.width(20.dp))
CustomSingleRightText(
modifier = Modifier.width(110.dp),
text = it.goodsPriceStr,
style = AppTypography.blackTextStyle
)
if (showClose) {
Spacer(modifier = Modifier.width(30.dp))
Image(
modifier = Modifier
.size(48.dp)
.clickable {
onCloseClick(index, it)
},
painter = painterResource(R.mipmap.ic_delete),
contentDescription = "删除"
)
}
}
// Spacer(modifier = Modifier.height(33.dp))
// if (productList.indexOf(it) != productList.lastIndex)
HorizontalDivider(
thickness = 1.dp,
color = colorResource(R.color.divider)
)
// Spacer(modifier = Modifier.height(33.dp))
}
}
}
}
@@ -0,0 +1,147 @@
//package com.sw.inbound.ui.weight
//
//import androidx.compose.foundation.background
//import androidx.compose.foundation.border
//import androidx.compose.foundation.clickable
//import androidx.compose.foundation.layout.Arrangement
//import androidx.compose.foundation.layout.Box
//import androidx.compose.foundation.layout.fillMaxWidth
//import androidx.compose.foundation.layout.padding
//import androidx.compose.foundation.layout.wrapContentWidth
//import androidx.compose.foundation.lazy.grid.GridCells
//import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
//import androidx.compose.foundation.lazy.grid.itemsIndexed
//import androidx.compose.foundation.lazy.grid.rememberLazyGridState
//import androidx.compose.foundation.shape.RoundedCornerShape
//import androidx.compose.material3.Text
//import androidx.compose.runtime.Composable
//import androidx.compose.runtime.LaunchedEffect
//import androidx.compose.runtime.getValue
//import androidx.compose.runtime.mutableIntStateOf
//import androidx.compose.runtime.mutableStateOf
//import androidx.compose.runtime.remember
//import androidx.compose.runtime.setValue
//import androidx.compose.runtime.snapshotFlow
//import androidx.compose.ui.Alignment
//import androidx.compose.ui.Modifier
//import androidx.compose.ui.draw.clip
//import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.platform.LocalContext
//import androidx.compose.ui.text.TextStyle
//import androidx.compose.ui.text.style.TextAlign
//import androidx.compose.ui.text.style.TextOverflow
//import androidx.compose.ui.tooling.preview.Preview
//import androidx.compose.ui.unit.Dp
//import androidx.compose.ui.unit.dp
//import com.sw.inbound.model.response.SearchGoodsInfo
//import com.sw.inbound.ui.theme.AppTypography
//import kotlinx.coroutines.flow.distinctUntilChanged
//import kotlinx.coroutines.flow.map
//import timber.log.Timber
//
//
//@Preview(showBackground = true)
//@Composable
//fun testSingleGroup() {
// val list = mutableListOf<SearchGoodsInfo.Record>()
// list.add(SearchGoodsInfo.Record(goodsName = "胶东大白菜胶东大白菜胶东大白菜胶东大白菜"))
// for (i in 1..20) {
// list.add(SearchGoodsInfo.Record(goodsName = "胶东大白菜$i"))
// }
//
//// val list = arrayListOf<String>(
//// "胶东大白菜",
//// "玉田尖白菜1",
//// "玉田尖白菜2",
//// "玉田尖白菜3",
//// "玉田尖白菜4"
//// )
//// SingleSelectButtonGroup(list)
//}
//
///**
// * 搜索结果列表,可选中
// */
//@Composable
//fun SingleSelectButtonGroup(
// options: List<SearchGoodsInfo.Record>,
// modifier: Modifier = Modifier,
// onOptionSelected: (SearchGoodsInfo.Record) -> Unit,
// horizontalSpacing: Dp = 13.dp,
// verticalSpacing: Dp = 13.dp,
// unSelectedTextStyle: TextStyle = AppTypography.gray96a0aaTextStyle,
// onLoadMore: (Int) -> Unit = {},
// isMoreLoading: Boolean = false,
// canLoadMore: Boolean = true,
// checkedItem: SearchGoodsInfo.Record? = null
//) {
// val context = LocalContext.current
// var selectedItem by remember { mutableStateOf(options.firstOrNull() ?: "") }
//
// val lazyGridState = rememberLazyGridState()
// var pageNum by remember { mutableIntStateOf(1) }
//
// // 检测是否滚动到底部
// LaunchedEffect(lazyGridState) {
// snapshotFlow { lazyGridState.layoutInfo }
// .map { layoutInfo ->
// val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
// lastVisibleItem?.index == layoutInfo.totalItemsCount - 1
// }
// .distinctUntilChanged()
// .collect { reachedEnd ->
// Timber.d("加载更多 reachedEnd = $reachedEnd, isMoreLoading = $isMoreLoading, canLoadMore = $canLoadMore")
// if (reachedEnd && !isMoreLoading && canLoadMore) {
// pageNum++
// onLoadMore(pageNum)
// }
// }
// }
//
// // 定义颜色
// val selectedColor = Color(0xFFD9E3F9)
// val unselectedColor = Color(0xFFDCDCF0)
//
// LazyVerticalGrid(
// state = lazyGridState,
// columns = GridCells.Fixed(2), // 每行2列
// modifier = Modifier
// .fillMaxWidth(),
// horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
// verticalArrangement = Arrangement.spacedBy(verticalSpacing)
// ) {
// itemsIndexed(items = options, key = { index, it -> index }) { index, item ->
// val isChecked = item.goodsId == checkedItem?.goodsId
// Box(
// modifier = modifier
// .border(
// width = 2.dp,
// shape = RoundedCornerShape(10.dp),
// color = if (isChecked) selectedColor else unselectedColor,
// )
// .clip(RoundedCornerShape(10.dp))
// .background(if (isChecked) selectedColor else Color.Transparent)
// .clickable {
//// selectedItem = item
// onOptionSelected(item)
// },
// contentAlignment = Alignment.Center
//// .padding(vertical = 20.dp)
// ) {
// Text(
// text = item.goodsNameStr,
// style = if (isChecked) AppTypography.BlueTextStyle else unSelectedTextStyle,
// modifier = Modifier
//// .width(192.dp)
//// .height(64.dp)
// .wrapContentWidth()
// .padding(horizontal = 10.dp), // 水平内边距
// textAlign = TextAlign.Center,
// maxLines = 1,
// overflow = TextOverflow.Ellipsis,
// softWrap = false
// )
// }
// }
// }
//}
@@ -0,0 +1,133 @@
package com.sw.inbound.ui.weight
import android.content.Intent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.sw.inbound.MyApp
import com.sw.inbound.R
import com.sw.inbound.activity.FoodCollectionActivity
import com.sw.inbound.ext.medium
import com.sw.inbound.model.response.User
import com.sw.inbound.ui.theme.AppTypography
import com.sw.inbound.utils.DateTimeUtils
import com.sw.inbound.utils.ext.startActivity
import kotlinx.coroutines.delay
@OptIn(ExperimentalFoundationApi::class)
@Preview(
widthDp = 1920,
heightDp = 1080,
showBackground = true
)
/**
* 标题
*/
@Composable
fun TopTitleBar(
modifier: Modifier = Modifier,
// title: String = "采购单入库",
title: String = "出入库管理",
user: User? = null,
onLogoutClick: () -> Unit = {}
) {
var currentTime by remember { mutableStateOf(DateTimeUtils.getChineseDateString()) }
// 每秒更新一次时间
LaunchedEffect(Unit) {
while (true) {
delay(1000) // 1秒间隔
currentTime = DateTimeUtils.getChineseDateString()
}
}
Row(
modifier = modifier
.fillMaxWidth()
.padding(start = 60.dp, end = 60.dp, top = 22.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = title,
style = TextStyle(
fontWeight = FontWeight.Bold,
color = colorResource(R.color.title),
fontSize = 36.sp
),
modifier = Modifier.wrapContentSize()
.clickable(onClick = {
MyApp.instance?.run {
startActivity(
Intent(this, FoodCollectionActivity::class.java).apply{
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
)
}
})
)
Spacer(modifier = Modifier.weight(1f))
if (user != null) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.height(60.dp)
.clickable {
onLogoutClick()
}) {
Text(text = user.name ?: "用户", style = AppTypography.blackTextStyle.medium())
Spacer(modifier = Modifier.width(21.dp))
Image(
modifier = Modifier.size(60.dp),
painter = painterResource(R.mipmap.ic_logout),
contentDescription = "退出"
)
}
} else {
Text(
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
onLogoutClick()
}
),
text = currentTime,
style = TextStyle(
fontWeight = FontWeight.Medium,
color = colorResource(R.color.black),
fontSize = 24.sp
)
)
}
}
}
@@ -0,0 +1,101 @@
package com.sw.inbound.ui.weight.dialog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.sw.inbound.R
import com.sw.inbound.ui.weight.CustomButton
import com.sw.inbound.ui.weight.CustomOutlinedButton
import com.sw.inbound.utils.ToastUtils
/**
* 添加物品弹窗
*/
@Composable
fun AddProductDialog(
modifier: Modifier = Modifier,
onCancelClick: () -> Unit,
onConfirmClick: () -> Unit,
onDismiss: () -> Unit,
content: @Composable () -> Unit
) {
Dialog(
onDismissRequest = onDismiss,
properties = DialogProperties(
usePlatformDefaultWidth = false, // 不使用平台默认宽度
decorFitsSystemWindows = false // 允许内容延伸到系统窗口后面
)
) {
Surface(
modifier = Modifier
.padding(start = 60.dp, end = 60.dp, bottom = 40.dp) // 设置弹窗距离边框60dp
.wrapContentSize(),
shape = RoundedCornerShape(30.dp),
color = Color.White,
shadowElevation = 0.dp
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(start = 152.dp, end = 152.dp, top = 56.dp, bottom = 30.dp),
) {
// 主要内容区域
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
content()
}
Spacer(modifier = Modifier.height(30.dp))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
CustomOutlinedButton(
modifier = modifier
.width(300.dp)
.height(100.dp),
text = "取消",
fontSize = 36.sp,
onClick = onCancelClick
)
Spacer(modifier = Modifier.width(20.dp))
CustomButton(
modifier = modifier
.width(300.dp)
.height(100.dp),
text = "确定",
onClick = onConfirmClick,
borderColor = colorResource(R.color.blue),
textColor = colorResource(R.color.white),
fontSize = 36.sp
)
}
}
ToastUtils.ToastComposable()
}
}
}
@@ -0,0 +1,103 @@
package com.sw.inbound.ui.weight.dialog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.sw.inbound.R
import com.sw.inbound.ui.weight.CustomButton
import com.sw.inbound.ui.weight.CustomOutlinedButton
import com.sw.inbound.utils.ToastUtils
/**
* 添加物品弹窗
*/
@Composable
fun AddPurchaseUnitDialog(
modifier: Modifier = Modifier,
onCancelClick: () -> Unit,
onConfirmClick: () -> Unit,
onDismiss: () -> Unit,
content: @Composable () -> Unit
) {
Dialog(
onDismissRequest = onDismiss,
properties = DialogProperties(
usePlatformDefaultWidth = false, // 不使用平台默认宽度
decorFitsSystemWindows = false // 允许内容延伸到系统窗口后面
)
) {
Surface(
modifier = Modifier
.width(1190.dp)
.height(840.dp)
.wrapContentSize(),
shape = RoundedCornerShape(30.dp),
color = Color.White,
shadowElevation = 0.dp
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
) {
// 主要内容区域
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 164.dp)
.weight(1f)
) {
content()
}
Spacer(modifier = Modifier.height(30.dp))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
CustomOutlinedButton(
modifier = modifier
.width(300.dp)
.height(100.dp),
text = "取消",
fontSize = 36.sp,
onClick = onCancelClick
)
Spacer(modifier = Modifier.width(20.dp))
CustomButton(
modifier = modifier
.width(300.dp)
.height(100.dp),
text = "确定",
onClick = onConfirmClick,
borderColor = colorResource(R.color.blue),
textColor = colorResource(R.color.white),
fontSize = 36.sp
)
}
}
ToastUtils.ToastComposable()
}
}
}
@@ -0,0 +1,228 @@
package com.sw.inbound.ui.weight.dialog
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.sw.inbound.R
import com.sw.inbound.ext.bold
import com.sw.inbound.ext.withColor
import com.sw.inbound.ext.withSize
import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.ui.theme.AppTypography
import com.sw.inbound.ui.theme.GrayDivider
import com.sw.inbound.ui.weight.CustomButton
import com.sw.inbound.ui.weight.CustomOutlinedButton
import com.sw.inbound.ui.weight.CustomSingleRightText
import com.sw.inbound.utils.ToastUtils
/**
* 收货确认弹窗
*/
@Composable
fun ReceiptTipDialog(
modifier: Modifier = Modifier,
isWarn: Boolean = false,
goodsList: List<GoodsInfo>,
onCancelClick: () -> Unit,
onConfirmClick: (Boolean) -> Unit,
onDismiss: () -> Unit = {},
) {
Dialog(
onDismissRequest = onDismiss,
properties = DialogProperties(
usePlatformDefaultWidth = false, // 不使用平台默认宽度
decorFitsSystemWindows = false // 允许内容延伸到系统窗口后面
)
) {
Surface(
modifier = Modifier
.width(1190.dp)
.height(840.dp)
.wrapContentSize(),
shape = RoundedCornerShape(30.dp),
color = Color.White,
shadowElevation = 0.dp
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(30.dp),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Image(
painter = if (isWarn) painterResource(R.mipmap.ic_tip_warn) else painterResource(
R.mipmap.ic_tip_success
), contentDescription = "提示"
)
Spacer(modifier = Modifier.height(60.dp))
Text(
text = if (isWarn) "收货数量与采购量存在差异" else "核对无误,确认收货",
style = AppTypography.black141428TextStyle.bold().withSize(48.sp)
)
if (isWarn) {
Spacer(modifier = Modifier.height(60.dp))
Column(
modifier = Modifier
.height(257.dp)
.width(810.dp)
.border(width = 1.dp, color = GrayDivider)
) {
Row(
modifier = Modifier
.padding(start = 80.dp, top = 20.dp, end = 80.dp)
.height(50.dp),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "名称",
style = AppTypography.gray999999TextStyle,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "采购量",
style = AppTypography.gray999999TextStyle,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "实收",
style = AppTypography.gray999999TextStyle,
textAlign = TextAlign.Center
)
}
LazyColumn {
itemsIndexed(items = goodsList) { index, goods ->
Row(
modifier = Modifier
.padding(horizontal = 80.dp)
.height(50.dp),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = goods.goodNameStr,
style = AppTypography.blackMediumTextStyle,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "${goods.receiveCountListStr}${goods.unitNameStr}",
style = AppTypography.blackMediumTextStyle.withColor(
color = Color(0xFF0032C8)
),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.width(10.dp))
CustomSingleRightText(
modifier = Modifier.weight(1f),
text = "${goods.receivedNumCount}${goods.unitNameStr}",
style = AppTypography.blackMediumTextStyle.withColor(
Color.Red
),
textAlign = TextAlign.Center
)
}
}
}
}
Spacer(modifier = Modifier.height(29.dp))
Text(
text = "请确认实际收货数量,或选择部分收货处理",
style = AppTypography.black141428TextStyle.withColor(
color = Color(0xFF999999)
)
)
}
}
HorizontalDivider(thickness = 1.dp, color = colorResource(R.color.divider))
Spacer(modifier = Modifier.height(30.dp))
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
CustomOutlinedButton(
modifier = modifier
.width(180.dp)
.height(90.dp),
text = "返回",
fontSize = 36.sp,
onClick = onCancelClick
)
Spacer(modifier = Modifier.width(12.dp))
if (isWarn) {
CustomButton(
modifier = modifier
.width(260.dp)
.height(90.dp),
text = "部分收货",
onClick = {
onConfirmClick(false)
},
borderColor = colorResource(R.color.green),
textColor = colorResource(R.color.white),
fontSize = 36.sp
)
Spacer(modifier = Modifier.width(12.dp))
}
CustomButton(
modifier = modifier
.width(260.dp)
.height(90.dp),
text = "确定收货",
onClick = {
onConfirmClick(true)
},
borderColor = colorResource(R.color.blue),
textColor = colorResource(R.color.white),
fontSize = 36.sp
)
}
}
ToastUtils.ToastComposable()
}
}
}