From a88321b7b6938efcfbc4ec5b79b589695a020fd1 Mon Sep 17 00:00:00 2001 From: zxj <275873859@qq.com> Date: Fri, 11 Jul 2025 11:14:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=87=80=E5=80=BC=E7=8E=87?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sw/inbound/ext/StringExt.kt | 15 ++++-- .../sw/inbound/model/request/GoodsAddParam.kt | 6 +-- .../inbound/ui/page/SelfProcurementScreen.kt | 8 +++- .../sw/inbound/ui/weight/CustomTextField.kt | 11 ++++- .../java/com/sw/inbound/ExampleUnitTest.kt | 47 ++++++++++++++++++- 5 files changed, 75 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/sw/inbound/ext/StringExt.kt b/app/src/main/java/com/sw/inbound/ext/StringExt.kt index cb72636..34f77e5 100644 --- a/app/src/main/java/com/sw/inbound/ext/StringExt.kt +++ b/app/src/main/java/com/sw/inbound/ext/StringExt.kt @@ -72,8 +72,10 @@ fun String.toSafeDouble(): Double { } } -fun String.isValidFloat(): Boolean { +fun String.isValidFloat(maxFractionDigits: Int = 2): Boolean { + if (isEmpty()) return false if (startsWith(".")) return false + // 处理前导零的情况 if (length > 1 && startsWith("0")) { // 允许 "0" 和 "0.x" 但不允许 "00", "01", "00.1" 等 @@ -81,9 +83,14 @@ fun String.isValidFloat(): Boolean { return false } } - val decimalRegex = Regex("^\\d+\\.?\\d{0,2}$") - return this.matches(decimalRegex) -// return input.matches(Regex("-?\\d+(\\.\\d+)?")) + + // 构建动态正则表达式 + val decimalRegex = when { + maxFractionDigits <= 0 -> Regex("^\\d+$") // 不允许小数 + else -> Regex("^\\d+\\.?\\d{0,${maxFractionDigits}}$") + } + + return matches(decimalRegex) } fun String.toSafeFloat(maxDecimalDigits: Int = 2): Float { diff --git a/app/src/main/java/com/sw/inbound/model/request/GoodsAddParam.kt b/app/src/main/java/com/sw/inbound/model/request/GoodsAddParam.kt index 27ee74e..69a8caf 100644 --- a/app/src/main/java/com/sw/inbound/model/request/GoodsAddParam.kt +++ b/app/src/main/java/com/sw/inbound/model/request/GoodsAddParam.kt @@ -85,10 +85,10 @@ data class GoodsAddParam( val netRateStr: String get() { - if (netRate == null || netRate == 0f) { - return "" + return if (netRate == null || netRate == 0f) { + "" } else { - return netRate!!.toFormattedString() + netRate!!.toFormattedString(1) } } diff --git a/app/src/main/java/com/sw/inbound/ui/page/SelfProcurementScreen.kt b/app/src/main/java/com/sw/inbound/ui/page/SelfProcurementScreen.kt index 2b26bc3..7f4af8f 100644 --- a/app/src/main/java/com/sw/inbound/ui/page/SelfProcurementScreen.kt +++ b/app/src/main/java/com/sw/inbound/ui/page/SelfProcurementScreen.kt @@ -383,10 +383,11 @@ private fun DialogRightEditView(viewModel: SelfProcurementViewModel) { .width(474.dp), label = "净材率", value = goodsAddParam.netRateStr, - inputType = InputType.Decimal, + inputType = InputType.Percent, onValueChange = { viewModel.updateGoodsAddParam(goodsAddParam.copy(netRate = it.toSafeFloat())) - }) + }, trailingLabel = "%" + ) ColumnInputText( modifier = Modifier.width(474.dp), value = goodsAddParam.unitIdStr, @@ -498,6 +499,9 @@ fun ColumnInputText( } } +/** + * 添加物品弹窗 + */ @Composable fun AddProductDialog( modifier: Modifier = Modifier, diff --git a/app/src/main/java/com/sw/inbound/ui/weight/CustomTextField.kt b/app/src/main/java/com/sw/inbound/ui/weight/CustomTextField.kt index 2a0beeb..ffb12b4 100644 --- a/app/src/main/java/com/sw/inbound/ui/weight/CustomTextField.kt +++ b/app/src/main/java/com/sw/inbound/ui/weight/CustomTextField.kt @@ -83,7 +83,8 @@ import timber.log.Timber enum class InputType { Text, // 字符串 Number, // 数字 - Decimal // 浮点 + Decimal, // 浮点 + Percent, // 百分比 } /** @@ -147,6 +148,14 @@ fun CustomTextField( } } + InputType.Percent -> { + val range: ClosedFloatingPointRange = 0f..100f + if (newValue.isEmpty() || (newValue.isValidFloat(1) && newValue.toFloat() in range)) { + inputValue = newValue + onEditingComplete(true) + } + } + else -> { inputValue = newValue onEditingComplete(true) diff --git a/app/src/test/java/com/sw/inbound/ExampleUnitTest.kt b/app/src/test/java/com/sw/inbound/ExampleUnitTest.kt index 48e5e1f..e425cc4 100644 --- a/app/src/test/java/com/sw/inbound/ExampleUnitTest.kt +++ b/app/src/test/java/com/sw/inbound/ExampleUnitTest.kt @@ -1,6 +1,5 @@ package com.sw.inbound -import org.junit.Assert.assertEquals import org.junit.Test /** @@ -9,8 +8,52 @@ import org.junit.Test * See [testing documentation](http://d.android.com/tools/testing). */ class ExampleUnitTest { + @Test fun addition_isCorrect() { - assertEquals(4, 2 + 2) +// println(4, 2 + 2) + } + + fun log(tag: String, msg: Boolean) { + println("$tag, result = $msg") + } + + @Test + fun testFloat() { + log("0.00", "0.00".isValidFloat()) + log("0.01", "0.01".isValidFloat()) + log("00", "00".isValidFloat()) + log("01", "01".isValidFloat()) + log("10", "10".isValidFloat()) + log("10.00", "10.00".isValidFloat()) + log("10.01", "10.01".isValidFloat()) + log("10.011", "10.011".isValidFloat()) + log("0.0-1", "0.0".isValidFloat(1)) + log("10.011-1", "10.011".isValidFloat(1)) + log("10.01-1", "10.01".isValidFloat(1)) + log("10.0-1", "10.0".isValidFloat(1)) + log("10.0-0", "10.0".isValidFloat(0)) + log("10.01-0", "10.01".isValidFloat(0)) + } + + fun String.isValidFloat(maxFractionDigits: Int = 2): Boolean { + if (isEmpty()) return false + if (startsWith(".")) return false + + // 处理前导零的情况 + if (length > 1 && startsWith("0")) { + // 允许 "0" 和 "0.x" 但不允许 "00", "01", "00.1" 等 + if (!startsWith("0.")) { + return false + } + } + + // 构建动态正则表达式 + val decimalRegex = when { + maxFractionDigits <= 0 -> Regex("^\\d+$") // 不允许小数 + else -> Regex("^\\d+\\.?\\d{0,${maxFractionDigits}}$") + } + + return matches(decimalRegex) } } \ No newline at end of file