联调优化

This commit is contained in:
马增飞
2025-11-14 18:13:28 +08:00
parent 6e3e873764
commit 76fa364792
18 changed files with 317 additions and 251 deletions
+3
View File
@@ -153,6 +153,9 @@ dependencies {
} else {
releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion")
}
implementation("org.greenrobot:eventbus:3.3.1")
}
apply(plugin = "io.objectbox")
+33 -33
View File
@@ -1,42 +1,42 @@
{
"class_names": [
"圆白菜[卷心菜]",
"大白菜(代表值)",
"大葱",
"洋葱(鲜)[葱头]",
"番茄[西红柿]",
"胡萝卜(红)[金笋,丁香萝卜]",
"芹菜(茎)[旱芹,药芹]",
"茄子(代表值)",
"西兰花[绿菜花]",
"辣椒(青,尖)",
"黄瓜(鲜)[胡瓜]"
"圆白菜[卷心菜,包菜]WP2025111000063",
"大白菜WP2025111000064",
"大葱WP2025111000060",
"洋葱(鲜)[葱头]WP2025111000061",
"番茄WP2025110700016",
"胡萝卜WP2025110600008",
"芹菜WP2025111000065",
"茄子(紫皮,长)WP2025110700024",
"西兰花[绿菜花]WP2025110700029",
"辣椒(青辣椒,螺丝椒)WP2025110700017",
"黄瓜(鲜)[胡瓜]WP2025110700031"
],
"class_to_idx": {
"圆白菜[卷心菜]": 0,
"大白菜(代表值)": 1,
"大葱": 2,
"洋葱(鲜)[葱头]": 3,
"番茄[西红柿]": 4,
"胡萝卜(红)[金笋,丁香萝卜]": 5,
"芹菜(茎)[旱芹,药芹]": 6,
"茄子(代表值)": 7,
"西兰花[绿菜花]": 8,
"辣椒(青,尖)": 9,
"黄瓜(鲜)[胡瓜]": 10
"圆白菜[卷心菜,包菜]WP2025111000063": 0,
"大白菜WP2025111000064": 1,
"大葱WP2025111000060": 2,
"洋葱(鲜)[葱头]WP2025111000061": 3,
"番茄WP2025110700016": 4,
"胡萝卜WP2025110600008": 5,
"芹菜WP2025111000065": 6,
"茄子(紫皮,长)WP2025110700024": 7,
"西兰花[绿菜花]WP2025110700029": 8,
"辣椒(青辣椒,螺丝椒)WP2025110700017": 9,
"黄瓜(鲜)[胡瓜]WP2025110700031": 10
},
"idx_to_class": {
"0": "圆白菜[卷心菜]",
"1": "大白菜(代表值)",
"2": "大葱",
"3": "洋葱(鲜)[葱头]",
"4": "番茄[西红柿]",
"5": "胡萝卜(红)[金笋,丁香萝卜]",
"6": "芹菜(茎)[旱芹,药芹]",
"7": "茄子(代表值)",
"8": "西兰花[绿菜花]",
"9": "辣椒(青,尖)",
"10": "黄瓜(鲜)[胡瓜]"
"0": "圆白菜[卷心菜,包菜]WP2025111000063",
"1": "大白菜WP2025111000064",
"2": "大葱WP2025111000060",
"3": "洋葱(鲜)[葱头]WP2025111000061",
"4": "番茄WP2025110700016",
"5": "胡萝卜WP2025110600008",
"6": "芹菜WP2025111000065",
"7": "茄子(紫皮,长)WP2025110700024",
"8": "西兰花[绿菜花]WP2025110700029",
"9": "辣椒(青辣椒,螺丝椒)WP2025110700017",
"10": "黄瓜(鲜)[胡瓜]WP2025110700031"
},
"embedding_dim": 512,
"total_images": 770,
@@ -276,7 +276,13 @@ class FoodCollectionActivity : ComponentActivity() {
private fun image2VectorTask(bitmap: Bitmap, position: Int) {
try {
initBox()
val imageVector = FoodModule.bitmap2FloatArray(bitmap)
val imageVector = try {
FoodModule.bitmap2FloatArray(bitmap)
} catch (e: Exception) {
e.printStackTrace()
//toast("保存失败")
return
}
box?.put(
Food(
name = searchGoodsList[clickIndex].goodsName,
@@ -10,6 +10,7 @@ import androidx.activity.viewModels
import androidx.camera.view.PreviewView
import androidx.core.graphics.toColorInt
import androidx.core.view.updateLayoutParams
import androidx.lifecycle.viewModelScope
import com.shuwei.intelligent.shelves.utils.ext.appendText
import com.shuwei.intelligent.shelves.utils.ext.buildSpannableString
import com.sw.inbound.GlobalData
@@ -45,13 +46,15 @@ import com.sw.inbound.utils.ext.toJsonString
import com.sw.inbound.utils.ext.toast
import com.sw.inbound.viewmodel.ReceiptViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import java.io.File
import kotlin.math.abs
import kotlin.math.min
typealias RecognizeCallback = (List<SearchGoodsInfo.Record>)->Unit
typealias RecognizeCallback = (List<SearchGoodsInfo.Record>) -> Unit
@AndroidEntryPoint
abstract class GoodsListActivity : ComponentActivity() {
@@ -147,14 +150,16 @@ abstract class GoodsListActivity : ComponentActivity() {
startTime = System.currentTimeMillis()
binding.root.postDelayed({
SensorScaleUtils.addWeightListener {
try {
weightCallback?.invoke(it)
recognizeWeight(weight = it)
} catch (e: Exception) {
e.printStackTrace()
runOnUiThread {
try {
weightCallback?.invoke(it)
recognizeWeight(weight = it)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}, 3 * 1000)
}, 1 * 1000)
}
private var weightCallback: ((weight: Int) -> Unit)? = null
@@ -171,13 +176,13 @@ abstract class GoodsListActivity : ComponentActivity() {
// return
//}
if (weight < 200) {
if (abs(weight) < 10) {
if (DialogManager.getDialogList().size == 1 &&
DialogManager.contains("GoodsRecognizeDialog") &&
goodsRecognizeDialog?.isShowing == true) {
goodsRecognizeDialog?.dismiss()
}
}
// if (abs(weight) < 10) {
// if (DialogManager.getDialogList().size == 1 &&
// DialogManager.contains("GoodsRecognizeDialog") &&
// goodsRecognizeDialog?.isShowing == true) {
// goodsRecognizeDialog?.dismiss()
// }
// }
return
}
this.lastWeight = weight
@@ -192,7 +197,8 @@ abstract class GoodsListActivity : ComponentActivity() {
// Timber.tag(TAG).d("recognizeWeight, checkResult=true")
// return
// }
Timber.tag(TAG).d("recognizeWeight,recognizeFoodisShowRecognizeDialog=$isShowRecognizeDialog")
Timber.tag(TAG)
.d("recognizeWeight,recognizeFoodisShowRecognizeDialog=$isShowRecognizeDialog")
recognizeFood()
}
@@ -201,19 +207,29 @@ abstract class GoodsListActivity : ComponentActivity() {
private val takePhotoSuccessCallback: (Uri) -> Unit = { uri ->
Thread {
searchFood(uri)
try {
searchFood(uri)
} catch (e: Exception) {
e.printStackTrace()
}
}.start()
}
fun delayRecognizeFood() {
window.decorView.postDelayed({
if (abs(lastWeight) < 10) {
return
}
window.decorView.postDelayed(
{
recognizeFood()
},
DELAY_TIME.toLong())
DELAY_TIME.toLong()
)
}
fun recognizeFood() {
if (isShowRecognizeDialog.not()) {
if(goodsRecognizeDialog == null) {
if (goodsRecognizeDialog == null) {
isShowRecognizeDialog = true
}
return
@@ -231,7 +247,7 @@ abstract class GoodsListActivity : ComponentActivity() {
}
}
private var recognizeCallback:RecognizeCallback?=null
private var recognizeCallback: RecognizeCallback? = null
var isAgainRecognize = false
fun againRecognizeFood(callback: RecognizeCallback) {
@@ -267,33 +283,47 @@ abstract class GoodsListActivity : ComponentActivity() {
targetWidth = 1000, targetHeight = 1300,
offsetX = 30, offsetY = 100
)
val file = BitmapSaver.saveToAppFilesDir(
newBmp,
this,
"IMG_CROP_${System.currentTimeMillis()}.jpg"
)
Timber.d("${this.javaClass.simpleName}-searchFood-裁剪bitmap保存文件路径:${file?.absolutePath}")
//val foodList = FoodModule.queryFood(newBmp)
if (bitmap.isRecycled.not()) {
bitmap.recycle()
}
// val file = BitmapSaver.saveToAppFilesDir(
// newBmp,
// this,
// "IMG_CROP_${System.currentTimeMillis()}.jpg"
// )
// Timber.d("${this.javaClass.simpleName}-searchFood-裁剪bitmap保存文件路径:${file?.absolutePath}")
//var foodList = FoodModule.queryFood(newBmp)
//物品编号
//foodList = foodList.map { "WP"+it.split("WP")[1] }
//物品名称
//foodList = foodList.map { it.split("WP")[0] }
val foodList = FoodModule.getFoodScoreList(newBmp)
runOnUiThread {
if (foodList.isEmpty()) {
handleGoodsResult()
return@runOnUiThread
}
viewModel.recognizeGoodsList(
//nameList = foodList,
scoreList = foodList,
) { goodsList ->
if (newBmp.isRecycled.not()) {
newBmp.recycle()
}
if (foodList.isEmpty()) {
recognizeFoodError()
return@let
}
foodList.forEach {
it.name = it.name.split("WP")[0]
}
viewModel.recognizeGoodsList(
//nameList = foodList,
scoreList = foodList,
) { goodsList ->
runOnUiThread {
if (isAgainRecognize) {
Loading.dismiss()
recognizeCallback?.invoke(goodsList)
isAgainRecognize = false
return@recognizeGoodsList
return@runOnUiThread
}
handleGoodsResult(
goodsList = if (goodsList.size == foodList.size) goodsList else mutableListOf(),
file = file,
name = foodList.joinToString(",")
// file = null,
// name = foodList.joinToString(",")
)
}
}
@@ -302,8 +332,8 @@ abstract class GoodsListActivity : ComponentActivity() {
private fun handleGoodsResult(
goodsList: List<SearchGoodsInfo.Record> = mutableListOf(),
file: File?=null,
name: String?=null,
file: File? = null,
name: String? = null,
) {
runOnUiThread {
if (goodsRecognizeDialog?.isShowing == true) {
@@ -383,7 +413,8 @@ abstract class GoodsListActivity : ComponentActivity() {
val finalWeight = item.goodsWeight?.toDouble().plus2(goods.goodsWeight?.toDouble())
val finalNum = item.receivedNum.plus2(goods.receivedNum)
val finalAmount = item.recPriceInItem.plus2(goods.recPriceInItem)
val finalPrice = if (finalAmount == 0.toDouble() || finalNum == 0.toDouble()) 0.toDouble() else finalAmount / finalNum
val finalPrice =
if (finalAmount == 0.toDouble() || finalNum == 0.toDouble()) 0.toDouble() else finalAmount / finalNum
item.run {
receivedNum = finalNum
recUnitPriceTaxIn = finalPrice.roundedDecimalPlace(2)
@@ -453,7 +484,10 @@ abstract class GoodsListActivity : ComponentActivity() {
val count = goodsList.count { it.isLocalGoods }
// 处理返回事件
if (count > 0) {
WarnDialog(context = this@GoodsListActivity, content = "存在未收货的物品,请确认是否放弃收货,若放弃则数据不会保存?") {
WarnDialog(
context = this@GoodsListActivity,
content = "存在未收货的物品,请确认是否放弃收货,若放弃则数据不会保存?"
) {
//onBackPressedDispatcher.onBackPressed()
finish()
}.show()
@@ -531,18 +565,18 @@ abstract class GoodsListActivity : ComponentActivity() {
}
}
fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
viewModel.uploadImage(imageUri) { imgUrl ->
if (imgUrl.isNullOrBlank()) {
callback(null)
return@uploadImage
}
callback(imgUrl)
}
}
// fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
// viewModel.uploadImage(imageUri) { imgUrl ->
// if (imgUrl.isNullOrBlank()) {
// callback(null)
// return@uploadImage
// }
// callback(imgUrl)
// }
// }
fun createNewGoods(imageUri: Uri, param: GoodsAddParam, callback: (Boolean) -> Unit) {
viewModel.uploadImage(imageUri) { imgUrl ->
fun createNewGoods(file: File, param: GoodsAddParam, callback: (Boolean) -> Unit) {
viewModel.uploadImage(file) { imgUrl ->
if (imgUrl.isNullOrBlank()) {
toast("图片上传失败")
return@uploadImage
@@ -551,4 +585,15 @@ abstract class GoodsListActivity : ComponentActivity() {
viewModel.createNewGoods(param = param, callback = callback)
}
}
private fun recognizeFoodError() {
if (isAgainRecognize) {
Loading.dismiss()
recognizeCallback?.invoke(mutableListOf())
isAgainRecognize = false
} else {
handleGoodsResult()
}
}
}
@@ -19,7 +19,10 @@ import com.sw.inbound.ext.toSafeBigDecimal
import com.sw.inbound.ext.toSafeFloat
import com.sw.inbound.model.request.GoodsAddParam
import com.sw.inbound.model.response.DictType
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.ext.dp
import com.sw.inbound.utils.ext.gone
import com.sw.inbound.utils.ext.toast
@@ -46,6 +49,7 @@ class AddGoodsDialog(
private val cameraUtils: CameraUtils by lazy {
CameraUtils(activity!!)
}
override fun show() {
super.show()
cameraUtils.setPreviewController(previewView)
@@ -71,7 +75,10 @@ class AddGoodsDialog(
}
cameraUtils.initCamera()
val previewBinding =
LayoutCameraPreviewBinding.inflate(LayoutInflater.from(context), binding.flCameraPreview)
LayoutCameraPreviewBinding.inflate(
LayoutInflater.from(context),
binding.flCameraPreview
)
previewBinding.previewView.let {
it.updateLayoutParams {
width = 428.dp
@@ -98,9 +105,9 @@ class AddGoodsDialog(
cameraUtils.takePhoto(takePhotoCallback)
}
binding.btnUploadImg.gone()
binding.btnUploadImg.setOnClickListener {
uploadImage()
}
// binding.btnUploadImg.setOnClickListener {
// uploadImage()
// }
binding.tvGoodsType.let { tv ->
tv.text = "原材料"
tv.tag = GlobalData.goodsTypeList.firstOrNull { it.value == "原材料" }?.id
@@ -111,7 +118,7 @@ class AddGoodsDialog(
textView = binding.tvProcurementUnit,
arrowImage = binding.ivProcurementArrow,
list = GlobalData.unitTypeList,
height = 2*71.dp
height = 2 * 71.dp
)
// showDropDownList(
// binding.flGoodsType,
@@ -129,7 +136,7 @@ class AddGoodsDialog(
textView = binding.tvWarehouseUnit,
arrowImage = binding.ivWarehouseArrow,
list = GlobalData.unitTypeList,
height = 3*71.dp
height = 3 * 71.dp
) {
binding.tvSelectUseUnit.text = it.value
binding.tvSelectProcurementUnit.text = it.value
@@ -144,7 +151,7 @@ class AddGoodsDialog(
height: Int = 355.dp,
block: (DictType) -> Unit = {}
) {
dropdownView.setOnClickListener {v->
dropdownView.setOnClickListener { v ->
dropdownList.clear()
val tempList =
list.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
@@ -238,31 +245,51 @@ class AddGoodsDialog(
purchaseValue = goodsCount.toSafeFloat(),
purchasePrice = goodsPrice.toSafeBigDecimal(),
)
activity?.createNewGoods(imageUri!!, param) {
if (it.not()) {
context.toast("新增物品失败")
return@createNewGoods
activity?.let {
Loading.show(it)
}
ImageUtil.uriToBitmap(context, imageUri!!)?.let { bitmap ->
val newBmp = BitmapCropper.cropCenter(
original = bitmap,
targetWidth = 1000, targetHeight = 1300,
offsetX = 30, offsetY = 100
)
val file = BitmapSaver.saveToAppFilesDir(
newBmp,
context,
"IMG_CROP_${System.currentTimeMillis()}.jpg"
)
if(file == null) {
context.toast("请重新拍照后再试")
Loading.dismiss()
return@let
}
activity?.createNewGoods(file, param) {
Loading.dismiss()
if (it.not()) {
context.toast("新增物品失败")
return@createNewGoods
}
context.toast("新增物品成功")
confirmBlock(goodsName)
dismiss()
}
context.toast("新增物品成功")
confirmBlock(goodsName)
dismiss()
}
}
private var imageUri: Uri? = null
private fun uploadImage() {
if (imageUri == null) {
context.toast("请采集图片")
return
}
activity?.uploadImage(imageUri!!) { imgUrl ->
if (imgUrl.isNullOrBlank()) {
context.toast("图片上传失败")
return@uploadImage
}
context.toast(imgUrl)
}
}
// private fun uploadImage() {
// if (imageUri == null) {
// context.toast("请采集图片")
// return
// }
// activity?.uploadImage(imageUri!!) { imgUrl ->
// if (imgUrl.isNullOrBlank()) {
// context.toast("图片上传失败")
// return@uploadImage
// }
// context.toast(imgUrl)
// }
// }
}
@@ -151,7 +151,7 @@ class CollectSearchDialog(
confirmBlock = {
Thread {
activity?.runOnUiThread {
Loading.show(context)
Loading.show(activity!!)
}
val name = list[position].goodsName
val filterIdList = box?.all?.filter { it.name == name }?.map { it.id }
@@ -191,7 +191,7 @@ class CollectSearchDialog(
list.clear()
var queryList = box?.all?.distinctBy { it.name }
if (searchName.isNullOrBlank().not()) {
queryList = queryList?.filter { it.name?.contains(searchName) == true }
queryList = queryList?.filter { it.name?.contains(searchName!!) == true }
}
queryList?.forEach {
list.add((SearchGoodsInfo.Record(goodsName = it.name)))
@@ -88,14 +88,14 @@ class GoodsRecognizeDialog(
binding.btnAgainRecognize.setOnClickListener {
//dismiss()
activity?.againRecognizeFood { goodsList ->
binding.rvRecognize.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
list.clear()
list.addAll(goodsList)
recognizeAdapter.notifyDataSetChanged()
if (recognizeAdapter.list.isEmpty()) {
loadEmptyView()
return@againRecognizeFood
}
binding.rvRecognize.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
recognizeAdapter.notifyDataSetChanged()
}
}
}
@@ -10,7 +10,6 @@ import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.camera.view.PreviewView
import androidx.core.graphics.toColorInt
@@ -25,7 +24,6 @@ import com.sw.inbound.activity.GoodsListActivity
import com.sw.inbound.databinding.DialogGoodsStoreBinding
import com.sw.inbound.databinding.LayoutImagePreviewBinding
import com.sw.inbound.databinding.LayoutTakePhotoBinding
import com.sw.inbound.ext.toFormattedString
import com.sw.inbound.model.response.DictType
import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.model.response.SearchGoodsInfo
@@ -97,6 +95,9 @@ class GoodsStoreDialog(
binding.btnConfirm.setOnClickListener {
confirmInputData()
}
binding.tvTitle.setOnClickListener {
SensorScaleUtils.startScale(autoScale = true)
}
// binding.ivAddUnit.setOnClickListener {
// AddProcurementUnitDialog(context).show()
// }
@@ -124,13 +125,12 @@ class GoodsStoreDialog(
}
}
val first = goods.unitVoList!!.first { it.businessUnitId == dictType.id }
val stringBuilder = StringBuilder()
.append("1").append(dictType.value).append("=")
.append(first.purchaseValue!!.toInt().toString())
.append(goods.kcUnitName)
.append("")
.append("1").append(goods.kcUnitName).append("=")
.append(first.consumeValue).append("")
val stringBuilder =
StringBuilder().append("1").append(dictType.value).append("=")
.append(first.purchaseValue!!.toInt().toString())
.append(goods.kcUnitName).append("").append("1")
.append(goods.kcUnitName).append("=").append(first.consumeValue)
.append("")
binding.tvUnitCalculate.text = stringBuilder.toString()
//val count = getUnitCount(dictType.id!!)
//if (count.isBlank() || "0" == count) {
@@ -268,9 +268,7 @@ class GoodsStoreDialog(
StyleSpan(Typeface.BOLD)
)
appendText(
"",
ForegroundColorSpan("#FF000033".toColorInt()),
StyleSpan(Typeface.BOLD)
"", ForegroundColorSpan("#FF000033".toColorInt()), StyleSpan(Typeface.BOLD)
)
}
}
@@ -375,6 +373,9 @@ class GoodsStoreDialog(
}
}
}
binding.root.postDelayed({
SensorScaleUtils.startScale()
}, 2600)
}
private var imageUri: Uri? = null
@@ -435,8 +436,10 @@ class GoodsStoreDialog(
ImageUtil.uriToBitmap(context, imageUri!!)?.let { bitmap ->
val cropBitmap = BitmapCropper.cropCenter(
original = bitmap,
targetWidth = 1000, targetHeight = 1300,
offsetX = 30, offsetY = 100
targetWidth = 1000,
targetHeight = 1300,
offsetX = 30,
offsetY = 100
)
val file = BitmapSaver.saveToAppFilesDir(
cropBitmap, context, "IMG_CROP_${System.currentTimeMillis()}.jpg"
@@ -448,7 +451,11 @@ class GoodsStoreDialog(
Thread {
try {
val imageVector = FoodModule.bitmap2FloatArray(bitmap)
box?.put(Food(name = goods.goodsName, foodIdx = 0, foodVector = imageVector))
box?.put(
Food(
name = goods.goodsName, foodIdx = 0, foodVector = imageVector
)
)
} catch (e: Exception) {
e.printStackTrace()
}
@@ -1,26 +1,30 @@
package com.sw.inbound.dialog
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.WindowManager
import androidx.core.graphics.drawable.toDrawable
import com.sw.inbound.R
import com.sw.inbound.databinding.DialogLoadingBinding
import kotlin.let
import kotlin.run
object Loading {
private var dialog: LoadingDialog? = null
fun show(context: Context) {
fun show(activity: Activity) {
try {
if (activity.isFinishing || activity.isDestroyed) {
return
}
if (dialog?.isShowing == true) {
dialog?.dismiss()
}
if (dialog == null) {
dialog = LoadingDialog(context)
dialog = LoadingDialog(activity)
}
dialog?.show()
} catch (e: Exception) {
@@ -56,10 +60,10 @@ class LoadingDialog(
setCanceledOnTouchOutside(true)
window?.run {
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
//setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//)
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// )
}
setOnDismissListener {
onDismiss()
@@ -67,83 +71,3 @@ class LoadingDialog(
}
}
//class LoadingDialog3(
// private val activity: Activity,
// private val message: String = "加载中……",
// private val onDismiss: () -> Unit = {}
//) : DialogFragment() {
//
// override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// return SafeDialog(
// activity = activity,
// themeResId = R.style.ToastDialogTheme,
// ).apply {
// val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
// binding.tvMessage.text = message
// setContentView(binding.root)
// setCancelable(true)
// window?.run {
// setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// );
// }
// setOnDismissListener {
// onDismiss()
// }
// }
// }
//
// override fun dismiss() {
// super.dismiss()
// }
//
// override fun show(manager: FragmentManager, tag: String?) {
// runCatching {
// super.show(manager, tag)
// Handler(Looper.getMainLooper()).postDelayed({
// super.dismiss()
// }, 800)
// }.onFailure {
// it.printStackTrace()
// }
// }
//
//}
//class LoadingDialog(
// private val activity: Activity,
// private val message: String = "加载中……",
// private val onDismiss: () -> Unit = {}
//) : SafeDialog(
// activity = activity,
// themeResId = R.style.ToastDialogTheme,
//) {
//
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
// binding.tvMessage.text = message
// setContentView(binding.root)
// setCancelable(true)
// window?.run {
// setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// setFlags(
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// );
// }
// setOnDismissListener {
// onDismiss()
// }
// }
//
// fun show(manager: FragmentManager, tag: String?) {
// show()
// Handler(Looper.getMainLooper()).postDelayed({
// super.dismiss()
// }, 800)
// }
//
//}
@@ -61,14 +61,8 @@ object FoodModule {
NO_STD_RGB // [0.229, 0.224, 0.225] TORCHVISION_NORM_STD_RGB
)
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
// return floatArrayOf()
val floatArray = outputTensor.dataAsFloatArray
// try {
// if (bitmap.isRecycled.not()) {
// bitmap.recycle()
// }
// } catch (e: Exception) {
// e.printStackTrace()
// }
return floatArray
}
@@ -110,8 +104,13 @@ object FoodModule {
}
fun getFoodScoreList(bitmap: Bitmap, queryCount: Int = 15): List<IdNameScore> {
val floatArray = bitmap2FloatArray(bitmap)
// return emptyList()
val nameScoreList = queryFoodNameScore(floatArray, queryCount)
val maxScoreList = nameScoreList.groupBy { it.name }.map { (_, value) -> value.minByOrNull { it.score }!! }.toMutableList()
val maxScoreList = nameScoreList
.filter { it.score < 0.20 }
.groupBy { it.name }
.map { (_, value) -> value.minByOrNull { it.score }!! }
.toMutableList()
val map = mutableMapOf<String, Int>()
nameScoreList.forEach {
val key = it.name
@@ -142,7 +141,7 @@ object FoodModule {
data class IdNameScore(
val id:Long,
val name:String,
var name:String,
val score: Double
)
@@ -20,6 +20,7 @@ import com.sw.inbound.network.api.ApiService
import com.sw.inbound.utils.ContextUtils
import com.sw.inbound.utils.FileUtils
import timber.log.Timber
import java.io.File
import javax.inject.Inject
/**
@@ -126,6 +127,22 @@ class RemoteRepository @Inject constructor(
}
}
}
suspend fun uploadImage(file:File): ApiResponse<String> {
return safeApiCall {
//val codeRequestBody = RequestBody.create(
// MultipartBody.FORM,
// "4"
//)
val part = FileUtils.genRequestPart(file)
if (part == null) {
ApiResponse(code = "-1", msg = "解析图片失败")
} else {
//apiService.uploadImage(code = codeRequestBody, file = part)
apiService.uploadImage(file = part)
}
}
}
/**
* 部分收货
@@ -2,12 +2,17 @@ package com.sw.inbound.sdk
import android.os.Handler
import android.os.Looper
import com.sw.inbound.utils.MessageEvent
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 org.greenrobot.eventbus.EventBus
import timber.log.Timber
import kotlin.math.roundToInt
typealias WeightCallback = (Int) -> Unit
/**
@@ -18,18 +23,24 @@ object SensorScaleUtils {
const val serialPort = "/dev/ttyS7"
const val baudRate = 115200
private var mSensorScale: SensorScale? = null
var isValidWeight = false
private fun init() {
if (mSensorScale != null) {
return
}
mSensorScale = SensorScale(object : OnScaleResult {
/**
* 读取重量
*/
override fun readWeight(state: Int, value: Double) {
Handler(Looper.getMainLooper()).post {
callbackList.forEach {
it.invoke((value * 1000).roundToInt())
}
isValidWeight = true
callbackList.forEach {
it.invoke((value * 1000).roundToInt())
}
// EventBus.getDefault().post(MessageEvent((value * 1000).roundToInt()))
}
/**
@@ -40,9 +51,11 @@ object SensorScaleUtils {
}
override fun fail(errCode: Int) {
isValidWeight = false
Timber.e("fail code = $errCode")
Handler(Looper.getMainLooper()).post {
ToastUtils.showToast("秤读取数据异常")
startScale()
}
}
})
@@ -61,15 +74,16 @@ object SensorScaleUtils {
init()
mSensorScale?.openScale(serialPort, baudRate) { open ->
if (open && autoScale) {
Handler(Looper.getMainLooper()).postDelayed({
mSensorScale?.readWeight()
mSensorScale?.startContinuousRead()
}, 1500)
// ThreadUtils.launchOnIo {
// delay(1000)
// // 打开后需要等待后才能调用,否则会 1001 SDK未初始化
// mSensorScale?.startContinuousRead()
// }
// Handler(Looper.getMainLooper()).postDelayed({
// mSensorScale?.readWeight()
// mSensorScale?.startContinuousRead()
// }, 1500)
ThreadUtils.launchOnIo {
delay(1000)
// 打开后需要等待后才能调用,否则会 1001 SDK未初始化
mSensorScale?.readWeight()
mSensorScale?.startContinuousRead()
}
}
}
}
@@ -1,5 +1,6 @@
package com.sw.inbound.utils
import android.graphics.Bitmap
import android.util.DisplayMetrics
object BitmapCropper {
/**
@@ -22,8 +23,11 @@ object BitmapCropper {
startY = startY.coerceAtLeast(0)
val actualWidth = minOf(targetWidth, originalWidth - startX)
val actualHeight = minOf(targetHeight, originalHeight - startY)
return Bitmap.createBitmap(original, startX, startY, actualWidth, actualHeight)
return Bitmap.createBitmap(original, startX, startY, actualWidth, actualHeight).also {
// it.setConfig(Bitmap.Config.RGB_565)
// it.density = DisplayMetrics.DENSITY_LOW
}
}
}
@@ -27,7 +27,7 @@ object BitmapSaver {
context: Context,
fileName: String,
format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG,
quality: Int = 100
quality: Int = 10
): File? {
//val dir = context.getExternalFilesDir(null)
val dir = context.cacheDir
@@ -51,6 +51,9 @@ object FileUtils {
Timber.d("genRequestPart imageUri = $imageUri")
// 1. 从Uri获取文件
val file = getFileFromUri(context, imageUri)
return genRequestPart(file)
}
fun genRequestPart(file: File?): MultipartBody.Part? {
if (file == null) {
Timber.e("getFileFromUri file is null")
return null
@@ -6,9 +6,11 @@ import android.graphics.BitmapFactory
import android.net.Uri
object ImageUtil {
fun uriToBitmap(context: Context, uri: Uri): Bitmap? {
return try {
val options = BitmapFactory.Options()
options.inSampleSize = 10; // 这会将图片的尺寸缩小到原来的1/2
options.inPreferredConfig = Bitmap.Config.RGB_565
context.contentResolver.openInputStream(uri)?.use { stream ->
BitmapFactory.decodeStream(stream)
}
@@ -10,6 +10,7 @@ import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.ext.toJsonString
import dagger.hilt.android.lifecycle.HiltViewModel
import timber.log.Timber
import java.io.File
import javax.inject.Inject
/**
@@ -335,9 +336,20 @@ class ReceiptViewModel @Inject constructor(
}
}
fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
// fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
// launchWithLoading {
// val resp = repository.uploadImage(imageUri)
// if (!parseResponse(resp)) {
// callback(null)
// return@launchWithLoading
// }
// callback(resp.data)
// }
// }
fun uploadImage(file:File, callback: (String?) -> Unit) {
launchWithLoading {
val resp = repository.uploadImage(imageUri)
val resp = repository.uploadImage(file)
if (!parseResponse(resp)) {
callback(null)
return@launchWithLoading
@@ -365,4 +377,6 @@ class ReceiptViewModel @Inject constructor(
callback(true)
}
}
}
@@ -10,6 +10,7 @@
tools:ignore="HardcodedText">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="14"