替换模型,重新识别改为更新数据不关闭弹窗,设备联调优化
This commit is contained in:
Binary file not shown.
@@ -1,44 +1,44 @@
|
||||
{
|
||||
"class_names": [
|
||||
"小白菜",
|
||||
"圆白菜[卷心菜]",
|
||||
"大白菜(代表值)",
|
||||
"大葱",
|
||||
"洋葱(鲜)[葱头]",
|
||||
"番茄[西红柿]",
|
||||
"胡萝卜(红)[金笋,丁香萝卜]",
|
||||
"芹菜(茎)[旱芹,药芹]",
|
||||
"茄子(代表值)",
|
||||
"蒜薹(带帽)",
|
||||
"西兰花[绿菜花]",
|
||||
"辣椒(青,尖)",
|
||||
"韭菜",
|
||||
"马铃薯[土豆、洋芋]",
|
||||
"黄瓜(鲜)[胡瓜]"
|
||||
],
|
||||
"class_to_idx": {
|
||||
"小白菜": 0,
|
||||
"番茄[西红柿]": 1,
|
||||
"胡萝卜(红)[金笋,丁香萝卜]": 2,
|
||||
"芹菜(茎)[旱芹,药芹]": 3,
|
||||
"茄子(代表值)": 4,
|
||||
"蒜薹(带帽)": 5,
|
||||
"西兰花[绿菜花]": 6,
|
||||
"辣椒(青,尖)": 7,
|
||||
"韭菜": 8,
|
||||
"马铃薯[土豆、洋芋]": 9,
|
||||
"圆白菜[卷心菜]": 0,
|
||||
"大白菜(代表值)": 1,
|
||||
"大葱": 2,
|
||||
"洋葱(鲜)[葱头]": 3,
|
||||
"番茄[西红柿]": 4,
|
||||
"胡萝卜(红)[金笋,丁香萝卜]": 5,
|
||||
"芹菜(茎)[旱芹,药芹]": 6,
|
||||
"茄子(代表值)": 7,
|
||||
"西兰花[绿菜花]": 8,
|
||||
"辣椒(青,尖)": 9,
|
||||
"黄瓜(鲜)[胡瓜]": 10
|
||||
},
|
||||
"idx_to_class": {
|
||||
"0": "小白菜",
|
||||
"1": "番茄[西红柿]",
|
||||
"2": "胡萝卜(红)[金笋,丁香萝卜]",
|
||||
"3": "芹菜(茎)[旱芹,药芹]",
|
||||
"4": "茄子(代表值)",
|
||||
"5": "蒜薹(带帽)",
|
||||
"6": "西兰花[绿菜花]",
|
||||
"7": "辣椒(青,尖)",
|
||||
"8": "韭菜",
|
||||
"9": "马铃薯[土豆、洋芋]",
|
||||
"0": "圆白菜[卷心菜]",
|
||||
"1": "大白菜(代表值)",
|
||||
"2": "大葱",
|
||||
"3": "洋葱(鲜)[葱头]",
|
||||
"4": "番茄[西红柿]",
|
||||
"5": "胡萝卜(红)[金笋,丁香萝卜]",
|
||||
"6": "芹菜(茎)[旱芹,药芹]",
|
||||
"7": "茄子(代表值)",
|
||||
"8": "西兰花[绿菜花]",
|
||||
"9": "辣椒(青,尖)",
|
||||
"10": "黄瓜(鲜)[胡瓜]"
|
||||
},
|
||||
"embedding_dim": 512,
|
||||
"total_images": 550,
|
||||
"build_time": "2025-11-06T14:40:27.391796"
|
||||
"total_images": 770,
|
||||
"build_time": "2025-11-13T16:28:46.501957"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||
@@ -34,7 +34,7 @@ class MainActivity : ComponentActivity() {
|
||||
finish()
|
||||
})
|
||||
}
|
||||
SensorScaleUtils.startScale(autoScale = true){}
|
||||
SensorScaleUtils.startScale(autoScale = true)
|
||||
FoodModule.init(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.view.PreviewView
|
||||
@@ -28,6 +27,7 @@ import com.sw.inbound.utils.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.CameraUtils
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||
import com.sw.inbound.utils.ext.clickWithDebounce
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
@@ -126,12 +126,12 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
|
||||
binding.btnSave.setOnClickListener {
|
||||
if (clickIndex == -1) {
|
||||
Toast.makeText(this, "请选择物品名称", Toast.LENGTH_SHORT).show()
|
||||
toast("请选择物品名称")
|
||||
return@setOnClickListener
|
||||
}
|
||||
val count = collectList.count { it.bitmap != null }
|
||||
if (count == 0) {
|
||||
Toast.makeText(this, "请拍摄物品照片", Toast.LENGTH_SHORT).show()
|
||||
toast("请拍摄物品照片")
|
||||
return@setOnClickListener
|
||||
}
|
||||
vectorThread()
|
||||
@@ -208,9 +208,16 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun clearData() {
|
||||
collectList.forEach {
|
||||
try {
|
||||
if (it.bitmap?.isRecycled?.not() == true) {
|
||||
it.bitmap?.recycle()
|
||||
}
|
||||
it.bitmap = null
|
||||
it.isShowCamera = true
|
||||
it.isFinish = false
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
collectionAdapter.notifyDataSetChanged()
|
||||
|
||||
@@ -227,6 +234,7 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
toast("每次只允许保存6条数据")
|
||||
rerurn@ cameraCallback
|
||||
}
|
||||
try {
|
||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
||||
val cropBitmap = BitmapCropper.cropCenter(
|
||||
original = bitmap,
|
||||
@@ -244,6 +252,9 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun vectorThread() {
|
||||
@@ -263,9 +274,16 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
private fun image2VectorTask(bitmap: Bitmap, position: Int) {
|
||||
try {
|
||||
initBox()
|
||||
val imageVector = FoodModule.bitmap2FloatArray(bitmap)
|
||||
box?.put(Food(name = searchGoodsList[clickIndex].goodsName, foodIdx = 0, foodVector = imageVector))
|
||||
box?.put(
|
||||
Food(
|
||||
name = searchGoodsList[clickIndex].goodsName,
|
||||
foodIdx = 0,
|
||||
foodVector = imageVector
|
||||
)
|
||||
)
|
||||
collectList[position].let {
|
||||
it.imageVector = imageVector
|
||||
it.isFinish = true
|
||||
@@ -273,6 +291,9 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
runOnUiThread {
|
||||
collectionAdapter.notifyItemChanged(position)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
@@ -321,6 +342,7 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
searchAdapter.stateView = layout
|
||||
}
|
||||
}
|
||||
|
||||
fun searchGoods(
|
||||
searchName: String,
|
||||
pageNo: Int,
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.sw.inbound.dialog.DialogManager
|
||||
import com.sw.inbound.dialog.DropdownPopup
|
||||
import com.sw.inbound.dialog.GoodsRecognizeDialog
|
||||
import com.sw.inbound.dialog.GoodsSearchDialog
|
||||
import com.sw.inbound.dialog.Loading
|
||||
import com.sw.inbound.dialog.WarnDialog
|
||||
import com.sw.inbound.model.request.GoodsAddParam
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
@@ -35,6 +36,7 @@ import com.sw.inbound.utils.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.CameraUtils
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.hideKeyboard
|
||||
@@ -49,6 +51,8 @@ import java.io.File
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
|
||||
typealias RecognizeCallback = (List<SearchGoodsInfo.Record>)->Unit
|
||||
|
||||
@AndroidEntryPoint
|
||||
abstract class GoodsListActivity : ComponentActivity() {
|
||||
|
||||
@@ -143,8 +147,12 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
startTime = System.currentTimeMillis()
|
||||
binding.root.postDelayed({
|
||||
SensorScaleUtils.addWeightListener {
|
||||
try {
|
||||
weightCallback?.invoke(it)
|
||||
recognizeWeight(weight = it)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}, 3 * 1000)
|
||||
}
|
||||
@@ -176,12 +184,14 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
if (DialogManager.hasShowDialog()) {
|
||||
return
|
||||
}
|
||||
val checkResult = isFirstRecognize.not() && System.currentTimeMillis() - startTime <= DELAY_TIME
|
||||
Timber.tag(TAG).d("recognizeWeight,checkResult=$checkResult")
|
||||
if (checkResult) {
|
||||
Timber.tag(TAG).d("recognizeWeight,等待中:${(System.currentTimeMillis() - startTime)/1000}")
|
||||
return
|
||||
}
|
||||
// val checkResult = isFirstRecognize.not()
|
||||
// //&& System.currentTimeMillis() - startTime <= DELAY_TIME
|
||||
// Timber.tag(TAG).d("recognizeWeight,checkResult=$checkResult")
|
||||
// if (checkResult) {
|
||||
// //Timber.tag(TAG).d("recognizeWeight,等待中:${(System.currentTimeMillis() - startTime)/1000}")
|
||||
// Timber.tag(TAG).d("recognizeWeight, checkResult=true")
|
||||
// return
|
||||
// }
|
||||
Timber.tag(TAG).d("recognizeWeight,recognizeFood:isShowRecognizeDialog=$isShowRecognizeDialog")
|
||||
recognizeFood()
|
||||
}
|
||||
@@ -195,6 +205,12 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
}.start()
|
||||
}
|
||||
|
||||
fun delayRecognizeFood() {
|
||||
window.decorView.postDelayed({
|
||||
recognizeFood()
|
||||
},
|
||||
DELAY_TIME.toLong())
|
||||
}
|
||||
fun recognizeFood() {
|
||||
if (isShowRecognizeDialog.not()) {
|
||||
if(goodsRecognizeDialog == null) {
|
||||
@@ -215,6 +231,23 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private var recognizeCallback:RecognizeCallback?=null
|
||||
var isAgainRecognize = false
|
||||
|
||||
fun againRecognizeFood(callback: RecognizeCallback) {
|
||||
Loading.show(this)
|
||||
isAgainRecognize = true
|
||||
this.recognizeCallback = callback
|
||||
try {
|
||||
cameraUtils.takePhoto(takePhotoSuccessCallback)
|
||||
} catch (e: Exception) {
|
||||
Timber.tag(TAG).d("againRecognizeFood,takePhoto异常:${e.message}")
|
||||
e.printStackTrace()
|
||||
Loading.dismiss()
|
||||
recognizeCallback?.invoke(mutableListOf())
|
||||
}
|
||||
}
|
||||
|
||||
private var dropdownPopup: DropdownPopup? = null
|
||||
|
||||
private val dropdownList: MutableList<DictType> = mutableListOf()
|
||||
@@ -251,6 +284,12 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
//nameList = foodList,
|
||||
scoreList = foodList,
|
||||
) { goodsList ->
|
||||
if (isAgainRecognize) {
|
||||
Loading.dismiss()
|
||||
recognizeCallback?.invoke(goodsList)
|
||||
isAgainRecognize = false
|
||||
return@recognizeGoodsList
|
||||
}
|
||||
handleGoodsResult(
|
||||
goodsList = if (goodsList.size == foodList.size) goodsList else mutableListOf(),
|
||||
file = file,
|
||||
@@ -258,12 +297,6 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
)
|
||||
}
|
||||
}
|
||||
// searchMultipleGoods(foodNameList) { goodsList ->
|
||||
// handleGoodsResult(
|
||||
// if (goodsList.size == foodNameList.size) goodsList
|
||||
// else mutableListOf()
|
||||
// )
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ class ReceiptActivity : GoodsListActivity() {
|
||||
val list = detail.receiveGoodsInfoList
|
||||
list.forEach { goodsInfo ->
|
||||
goodsInfo.recUnitPriceTaxInBak = goodsInfo.recUnitPriceTaxIn
|
||||
goodsInfo.recUnitPriceTaxIn = 0.0
|
||||
goodsInfo.unitNameBak = goodsInfo.unitName
|
||||
goodsInfo.receivedNumBak = goodsInfo.receivedNum
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.databinding.ListItemReceiptGoodsBinding
|
||||
import com.sw.inbound.dialog.WarnDialog
|
||||
import com.sw.inbound.ext.toFormattedString
|
||||
import com.sw.inbound.ext.toSafeDouble
|
||||
import com.sw.inbound.model.response.GoodsInfo
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
@@ -62,13 +63,15 @@ class ReceiptGoodsAdapter(var list: MutableList<GoodsInfo>) :
|
||||
)
|
||||
tvGoodsName.text = item.goodName.ifNullOrBlank("-")
|
||||
tvProcurementUnit.text = item.unitName.ifNullOrBlank("-")
|
||||
tvProcurementCount.text = if (item.receiveCount == null || item.receiveCount == 0.toDouble()) "-"
|
||||
else item.receiveCount.removeTrailingZeros()
|
||||
val realCount = item.receiveCount?:0.toDouble()
|
||||
tvProcurementCount.text = if (realCount == 0.toDouble()) "-" else realCount.removeTrailingZeros()
|
||||
//tvProcurementPrice.text = item.recUnitPriceTaxInBak.toSafeDouble(2).ifNullOrZero("-")
|
||||
//tvProcurementAmount.text = item.recPriceExItem.toSafeDouble(2).ifNullOrZero("-")
|
||||
//tvReceiptCount.text = item.receivedNum.toSafeDouble(2).ifNullOrZero("-")
|
||||
tvGoodsWeight.text = if (item.goodsWeight == null || item.goodsWeight == 0.toBigDecimal()) "-"
|
||||
else item.goodsWeight?.toDouble().removeTrailingZeros()
|
||||
|
||||
tvGoodsWeight.text = doubleFormat(item.goodsWeight?.toDouble())
|
||||
|
||||
tvReceiptPrice.text = doubleFormat(item.recUnitPriceTaxIn)
|
||||
|
||||
if (item.unitHint.isNullOrBlank().not()) {
|
||||
unitDivider.visible()
|
||||
@@ -136,7 +139,7 @@ class ReceiptGoodsAdapter(var list: MutableList<GoodsInfo>) :
|
||||
}
|
||||
item.receivedNum = it
|
||||
item.recUnitPriceTaxIn = item.recPriceInItem!! / it
|
||||
//tvGoodsPrice.text = "${item.goodsUnitPrice?.roundedDecimalPlace(2)}"
|
||||
tvReceiptPrice.text = "${item.recUnitPriceTaxIn?.roundedDecimalPlace(2)}"
|
||||
}
|
||||
addEditListener(etReceiptAmount) {
|
||||
if (it == 0.toDouble()) {
|
||||
@@ -146,7 +149,7 @@ class ReceiptGoodsAdapter(var list: MutableList<GoodsInfo>) :
|
||||
}
|
||||
item.recPriceInItem = it
|
||||
item.recUnitPriceTaxIn = it / item.receivedNum!!
|
||||
//tvGoodsPrice.text = "${item.goodsUnitPrice?.roundedDecimalPlace(2)}"
|
||||
tvReceiptPrice.text = "${item.recUnitPriceTaxIn?.roundedDecimalPlace(2)}"
|
||||
}
|
||||
ivClear.run {
|
||||
visible()
|
||||
@@ -210,4 +213,9 @@ class ReceiptGoodsAdapter(var list: MutableList<GoodsInfo>) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun doubleFormat(num:Double?): String{
|
||||
val realNum = num?:0.toDouble()
|
||||
return if (realNum == 0.toDouble()) "-" else realNum.toFormattedString(2)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,9 @@ package com.sw.inbound.adapter
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.databinding.ListItemRecognizeBinding
|
||||
@@ -34,7 +36,12 @@ class RecognizeAdapter(var list: MutableList<SearchGoodsInfo.Record>) :
|
||||
bottomLeftRadius = 12.dp
|
||||
)
|
||||
}
|
||||
it.ivRecImage.load(item!!.relativeUrl)
|
||||
it.ivRecImage.run {
|
||||
load(item!!.relativeUrl) {
|
||||
transformations(RoundedCornersTransformation(radius = 12.dp.toFloat()))
|
||||
}
|
||||
scaleType = ImageView.ScaleType.CENTER_CROP
|
||||
}
|
||||
//it.root.run {
|
||||
// setShapeDrawable(
|
||||
// //strokeColor = if (item.isSelected) "#FF0033CC" else "#FFDCDCF0",
|
||||
|
||||
@@ -16,7 +16,7 @@ import com.sw.inbound.utils.ext.hideKeyboard
|
||||
abstract class BaseDialog(
|
||||
context: Context,
|
||||
var defWidth: Int = 1500.dp,
|
||||
var defHeight: Int = 800.dp
|
||||
var defHeight: Int = 900.dp
|
||||
) : Dialog(context, R.style.DialogTheme) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
@@ -78,8 +78,7 @@ class GoodsRecognizeDialog(
|
||||
}
|
||||
binding.ivClose.setOnClickListener {
|
||||
dismiss()
|
||||
activity?.isShowRecognizeDialog = true
|
||||
activity?.goodsRecognizeDialog = null
|
||||
activity?.delayRecognizeFood()
|
||||
activity?.startTime = System.currentTimeMillis()
|
||||
}
|
||||
binding.btnManuallyFind.setOnClickListener {
|
||||
@@ -87,9 +86,17 @@ class GoodsRecognizeDialog(
|
||||
//dismiss()
|
||||
}
|
||||
binding.btnAgainRecognize.setOnClickListener {
|
||||
dismiss()
|
||||
activity?.isShowRecognizeDialog = true
|
||||
activity?.recognizeFood()
|
||||
//dismiss()
|
||||
activity?.againRecognizeFood { goodsList ->
|
||||
list.clear()
|
||||
list.addAll(goodsList)
|
||||
if (recognizeAdapter.list.isEmpty()) {
|
||||
loadEmptyView()
|
||||
return@againRecognizeFood
|
||||
}
|
||||
binding.rvRecognize.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
recognizeAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,4 +109,14 @@ class GoodsRecognizeDialog(
|
||||
recognizeAdapter.stateView = it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
activity?.run {
|
||||
isShowRecognizeDialog = true
|
||||
goodsRecognizeDialog = null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,6 +53,7 @@ class LoadingDialog(
|
||||
binding.tvMessage.text = message
|
||||
setContentView(binding.root)
|
||||
setCancelable(true)
|
||||
setCanceledOnTouchOutside(true)
|
||||
window?.run {
|
||||
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
|
||||
setFlags(
|
||||
|
||||
@@ -62,9 +62,13 @@ object FoodModule {
|
||||
)
|
||||
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
|
||||
val floatArray = outputTensor.dataAsFloatArray
|
||||
if (bitmap.isRecycled.not()) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
// try {
|
||||
// if (bitmap.isRecycled.not()) {
|
||||
// bitmap.recycle()
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
return floatArray
|
||||
}
|
||||
|
||||
@@ -107,7 +111,7 @@ object FoodModule {
|
||||
fun getFoodScoreList(bitmap: Bitmap, queryCount: Int = 15): List<IdNameScore> {
|
||||
val floatArray = bitmap2FloatArray(bitmap)
|
||||
val nameScoreList = queryFoodNameScore(floatArray, queryCount)
|
||||
val maxScoreList = nameScoreList.groupBy { it.name }.map { (_, value) -> value.maxByOrNull { it.score }!! }.toMutableList()
|
||||
val maxScoreList = nameScoreList.groupBy { it.name }.map { (_, value) -> value.minByOrNull { it.score }!! }.toMutableList()
|
||||
val map = mutableMapOf<String, Int>()
|
||||
nameScoreList.forEach {
|
||||
val key = it.name
|
||||
|
||||
@@ -2,14 +2,13 @@ package com.sw.inbound.sdk
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.sw.inbound.utils.ThreadUtils
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import com.wabon.wbintelligenthardwaresdk.api.SensorScale
|
||||
import com.wabon.wbintelligenthardwaresdk.api.SensorScale.OnScaleResult
|
||||
import kotlinx.coroutines.delay
|
||||
import timber.log.Timber
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
typealias Callback = (Double) -> Unit
|
||||
typealias WeightCallback = (Int) -> Unit
|
||||
|
||||
/**
|
||||
* 称 传感器计算
|
||||
@@ -19,8 +18,6 @@ object SensorScaleUtils {
|
||||
const val serialPort = "/dev/ttyS7"
|
||||
const val baudRate = 115200
|
||||
private var mSensorScale: SensorScale? = null
|
||||
private var isOpened: Boolean = false
|
||||
private var callback: Callback? = {}
|
||||
|
||||
private fun init() {
|
||||
mSensorScale = SensorScale(object : OnScaleResult {
|
||||
@@ -28,23 +25,11 @@ object SensorScaleUtils {
|
||||
* 读取重量
|
||||
*/
|
||||
override fun readWeight(state: Int, value: Double) {
|
||||
//val stateStr = when (state) {
|
||||
// SensorScale.STATE_STABLE -> "稳定"
|
||||
// SensorScale.STATE_UNSTABLE -> "不稳定"
|
||||
// SensorScale.STATE_OVER_WEIGHT -> "量程溢出"
|
||||
// else -> "未知"
|
||||
//}
|
||||
// if (state != SensorScale.STATE_STABLE) {
|
||||
// return
|
||||
// }
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
weightCallback?.invoke((value * 1000).toInt())
|
||||
callbackList.forEach {
|
||||
it.invoke((value * 1000).roundToInt())
|
||||
}
|
||||
}
|
||||
//Timber.d("readWeight state = ${stateStr}, weight = $value")
|
||||
// 只使用稳定值
|
||||
// if (state == SensorScale.STATE_STABLE) {
|
||||
callback?.invoke(value)
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,37 +41,35 @@ object SensorScaleUtils {
|
||||
|
||||
override fun fail(errCode: Int) {
|
||||
Timber.e("fail code = $errCode")
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
ToastUtils.showToast("秤读取数据异常")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private var weightCallback: ((Int) -> Unit)? = null
|
||||
fun addWeightListener(callback: (Int) -> Unit) {
|
||||
weightCallback = callback
|
||||
private var callbackList: MutableList<WeightCallback> = mutableListOf()
|
||||
fun addWeightListener(callback: WeightCallback) {
|
||||
callbackList.add(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启称重
|
||||
* @param autoScale 是否开启自动读取
|
||||
*/
|
||||
fun startScale(autoScale: Boolean = true, callback: Callback?) {
|
||||
if (isOpened) {
|
||||
startContinuousRead(callback = callback)
|
||||
return
|
||||
}
|
||||
this.callback = callback
|
||||
fun startScale(autoScale: Boolean = true) {
|
||||
init()
|
||||
mSensorScale?.openScale(serialPort, baudRate) { open ->
|
||||
isOpened = open
|
||||
Timber.d("isOpened = $isOpened")
|
||||
if (open) {
|
||||
if (autoScale) {
|
||||
ThreadUtils.launchOnIo {
|
||||
delay(1000)
|
||||
// 打开后需要等待后才能调用,否则会 1001 SDK未初始化
|
||||
if (open && autoScale) {
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
mSensorScale?.readWeight()
|
||||
mSensorScale?.startContinuousRead()
|
||||
}
|
||||
}
|
||||
}, 1500)
|
||||
// ThreadUtils.launchOnIo {
|
||||
// delay(1000)
|
||||
// // 打开后需要等待后才能调用,否则会 1001 SDK未初始化
|
||||
// mSensorScale?.startContinuousRead()
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,24 +77,14 @@ object SensorScaleUtils {
|
||||
/**
|
||||
* 开启自动读取重量
|
||||
*/
|
||||
fun startContinuousRead(callback: Callback?) {
|
||||
this.callback = callback
|
||||
Timber.d("开启自动读取 = $isOpened")
|
||||
if (!isOpened) {
|
||||
return
|
||||
}
|
||||
fun startContinuousRead() {
|
||||
mSensorScale?.startContinuousRead()
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动读取重量
|
||||
*/
|
||||
fun readWeight(callback: Callback?) {
|
||||
this.callback = callback
|
||||
Timber.d("isOpened = $isOpened")
|
||||
if (!isOpened) {
|
||||
return
|
||||
}
|
||||
fun readWeight() {
|
||||
mSensorScale?.readWeight()
|
||||
}
|
||||
|
||||
@@ -119,7 +92,6 @@ object SensorScaleUtils {
|
||||
* 零位标定
|
||||
*/
|
||||
fun zero() {
|
||||
if (!isOpened) return
|
||||
mSensorScale?.zero {
|
||||
Timber.d("零位标定操作成功")
|
||||
}
|
||||
@@ -129,8 +101,6 @@ object SensorScaleUtils {
|
||||
* 去皮置零
|
||||
*/
|
||||
fun tare() {
|
||||
Timber.d("tare isOpened = $isOpened")
|
||||
if (!isOpened) return
|
||||
mSensorScale?.tare {
|
||||
Timber.d("去皮置零操作成功")
|
||||
ToastUtils.showToast("去皮置零操作成功")
|
||||
@@ -141,10 +111,6 @@ object SensorScaleUtils {
|
||||
* 停止自动读取重量
|
||||
*/
|
||||
fun stopContinuousRead() {
|
||||
Timber.d("isOpened = $isOpened")
|
||||
if (!isOpened) {
|
||||
return
|
||||
}
|
||||
mSensorScale?.stopContinuousRead()
|
||||
}
|
||||
|
||||
@@ -152,8 +118,7 @@ object SensorScaleUtils {
|
||||
* 关闭称重
|
||||
*/
|
||||
fun closeScale() {
|
||||
isOpened = false
|
||||
mSensorScale?.closeScale()
|
||||
mSensorScale == null
|
||||
mSensorScale = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
//package com.sw.inbound.sdk
|
||||
//
|
||||
//import android.os.Handler
|
||||
//import android.os.Looper
|
||||
//import com.sw.inbound.utils.ThreadUtils
|
||||
//import com.sw.inbound.utils.ToastUtils
|
||||
//import com.wabon.wbintelligenthardwaresdk.api.SensorScale
|
||||
//import com.wabon.wbintelligenthardwaresdk.api.SensorScale.OnScaleResult
|
||||
//import kotlinx.coroutines.delay
|
||||
//import timber.log.Timber
|
||||
//
|
||||
//typealias Callback = (Double) -> Unit
|
||||
//
|
||||
///**
|
||||
// * 称 传感器计算
|
||||
// */
|
||||
//object SensorScaleUtils2 {
|
||||
//
|
||||
// const val serialPort = "/dev/ttyS7"
|
||||
// const val baudRate = 115200
|
||||
// private var mSensorScale: SensorScale? = null
|
||||
// private var isOpened: Boolean = false
|
||||
// private var callback: Callback? = {}
|
||||
//
|
||||
// private fun init() {
|
||||
// mSensorScale = SensorScale(object : OnScaleResult {
|
||||
// /**
|
||||
// * 读取重量
|
||||
// */
|
||||
// override fun readWeight(state: Int, value: Double) {
|
||||
// //val stateStr = when (state) {
|
||||
// // SensorScale.STATE_STABLE -> "稳定"
|
||||
// // SensorScale.STATE_UNSTABLE -> "不稳定"
|
||||
// // SensorScale.STATE_OVER_WEIGHT -> "量程溢出"
|
||||
// // else -> "未知"
|
||||
// //}
|
||||
//// if (state != SensorScale.STATE_STABLE) {
|
||||
//// return
|
||||
//// }
|
||||
// Handler(Looper.getMainLooper()).post {
|
||||
// weightCallback?.invoke((value * 1000).toInt())
|
||||
// }
|
||||
// //Timber.d("readWeight state = ${stateStr}, weight = $value")
|
||||
// // 只使用稳定值
|
||||
//// if (state == SensorScale.STATE_STABLE) {
|
||||
// callback?.invoke(value)
|
||||
//// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 读取鉴别率
|
||||
// */
|
||||
// override fun readIdentify(rate: Int) {
|
||||
// Timber.e("readIdentify rate = $rate")
|
||||
// }
|
||||
//
|
||||
// override fun fail(errCode: Int) {
|
||||
// Timber.e("fail code = $errCode")
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// private var weightCallback: ((Int) -> Unit)? = null
|
||||
// fun addWeightListener(callback: (Int) -> Unit) {
|
||||
// weightCallback = callback
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 开启称重
|
||||
// * @param autoScale 是否开启自动读取
|
||||
// */
|
||||
// fun startScale(autoScale: Boolean = true, callback: Callback?) {
|
||||
// if (isOpened) {
|
||||
// startContinuousRead(callback = callback)
|
||||
// return
|
||||
// }
|
||||
// this.callback = callback
|
||||
// init()
|
||||
// mSensorScale?.openScale(serialPort, baudRate) { open ->
|
||||
// isOpened = open
|
||||
// Timber.d("isOpened = $isOpened")
|
||||
// if (open) {
|
||||
// if (autoScale) {
|
||||
// ThreadUtils.launchOnIo {
|
||||
// delay(1000)
|
||||
// // 打开后需要等待后才能调用,否则会 1001 SDK未初始化
|
||||
// mSensorScale?.startContinuousRead()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 开启自动读取重量
|
||||
// */
|
||||
// fun startContinuousRead(callback: Callback?) {
|
||||
// this.callback = callback
|
||||
// Timber.d("开启自动读取 = $isOpened")
|
||||
// if (!isOpened) {
|
||||
// return
|
||||
// }
|
||||
// mSensorScale?.startContinuousRead()
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 手动读取重量
|
||||
// */
|
||||
// fun readWeight(callback: Callback?) {
|
||||
// this.callback = callback
|
||||
// Timber.d("isOpened = $isOpened")
|
||||
// if (!isOpened) {
|
||||
// return
|
||||
// }
|
||||
// mSensorScale?.readWeight()
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 零位标定
|
||||
// */
|
||||
// fun zero() {
|
||||
// if (!isOpened) return
|
||||
// mSensorScale?.zero {
|
||||
// Timber.d("零位标定操作成功")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 去皮置零
|
||||
// */
|
||||
// fun tare() {
|
||||
// Timber.d("tare isOpened = $isOpened")
|
||||
// if (!isOpened) return
|
||||
// mSensorScale?.tare {
|
||||
// Timber.d("去皮置零操作成功")
|
||||
// ToastUtils.showToast("去皮置零操作成功")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 停止自动读取重量
|
||||
// */
|
||||
// fun stopContinuousRead() {
|
||||
// Timber.d("isOpened = $isOpened")
|
||||
// if (!isOpened) {
|
||||
// return
|
||||
// }
|
||||
// mSensorScale?.stopContinuousRead()
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 关闭称重
|
||||
// */
|
||||
// fun closeScale() {
|
||||
// isOpened = false
|
||||
// mSensorScale?.closeScale()
|
||||
// mSensorScale = null
|
||||
// }
|
||||
//}
|
||||
@@ -20,6 +20,7 @@ import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import kotlin.collections.List
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
abstract class BaseViewModel(
|
||||
private val repository: RemoteRepository
|
||||
@@ -208,7 +209,7 @@ abstract class BaseViewModel(
|
||||
val response = repository.recognizeGoodsList(paramList)
|
||||
val list = if (parseResponse(response)) response.data?:listOf() else listOf()
|
||||
scoreList?.forEachIndexed { index, item ->
|
||||
list[index].score = ((1 - item.score) * 10000).toInt()
|
||||
list[index].score = ((1 - item.score) * 10000).roundToInt()
|
||||
}
|
||||
callback(list)
|
||||
}
|
||||
|
||||
@@ -131,6 +131,18 @@
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvReceiptPrice"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="收货单价(元)"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user