接口调试、增加人脸识别后主副屏支付金额逻辑、其它优化

This commit is contained in:
2025-12-03 18:40:47 +08:00
parent 29188c5944
commit 8899cae323
34 changed files with 1202 additions and 402 deletions
@@ -11,6 +11,7 @@ import android.os.Looper
import android.text.TextUtils
import android.view.View
import android.view.ViewOutlineProvider
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
@@ -21,20 +22,22 @@ import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import com.google.common.util.concurrent.ListenableFuture
import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.adapter.SearchFoodAdapter
import com.sw.dualscreen.databinding.ActivityMainBinding
import com.sw.dualscreen.ext.dp
import com.sw.dualscreen.ext.gone
import com.sw.dualscreen.ext.load
import com.sw.dualscreen.ext.visible
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.FoodOrder
import com.sw.dualscreen.objbox.FoodModule
import com.sw.dualscreen.objbox.FoodModule.IdNameScore
import com.sw.dualscreen.presentation.MainScreenPresentation
import com.sw.dualscreen.sdk.SensorScaleUtils
import com.sw.dualscreen.utils.BitmapSaver
import com.sw.dualscreen.utils.Debouncer
import com.sw.dualscreen.utils.GlideUtils
import com.sw.dualscreen.utils.GsonUtils
import com.sw.dualscreen.utils.ImageUtil
import com.sw.dualscreen.utils.SPUtil
@@ -65,8 +68,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
private val viewModel by viewModels<UserViewModel>()
private var imageCapture: ImageCapture? = null
private var isAnalyzing = true // 控制是否进行图像分析
// private var presentation: SecondaryScreenPresentation? = null
var isAnalyzing = true // 控制是否进行图像分析
// private var presentation: SecondaryScreenPresentation? = null
private var presentation: MainScreenPresentation? = null
private val executor = Executors.newSingleThreadExecutor()
private val handler by lazy { Handler(Looper.getMainLooper()) }
@@ -86,7 +90,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
}
}
private var checkedItem: FoodInfo? = null
var checkedItem: FoodInfo? = null
private var imageAnalysis: ImageAnalysis? = null
private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
private var canIdentify: Boolean = false
@@ -106,6 +110,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun initialize() {
super.initialize()
addBackEventListener()
FoodModule.init(this)
initView()
setupSecondaryDisplay()
@@ -204,45 +209,44 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
// binding.tvRescan.setOnClickListener {
// debouncer.debounce { recognizeFood() }
// }
binding.btnPay.setOnClickListener {
if (checkedItem == null) {
ToastUtils.showToast("暂无识别数据,请搜索选择")
return@setOnClickListener
binding.btnPay.let {
it.run {
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
if (mode == 0) visible() else gone()
}
it.setOnClickListener { v ->
if (checkedItem == null) {
ToastUtils.showToast("暂无识别数据,请搜索选择")
return@setOnClickListener
}
createOrder(checkedItem!!)
}
presentation?.dismiss()
startActivity(Intent(this, PayActivity::class.java).apply {
putExtra(PayActivity.FOOD_INFO, checkedItem)
})
}
}
fun updateCurrentFood(foodInfo: FoodInfo?) {
if (foodInfo != null) {
presentation?.updateFood(foodInfo)
binding.tvFoodName.text = foodInfo.foodName
binding.previewView.visibility = View.GONE
binding.ivImg.visibility = View.VISIBLE
val imgUrl = foodInfo.imgUrl
if (TextUtils.isEmpty(imgUrl)) {
takePhoto { imgUri ->
GlideUtils.loadRoundCornerImage(this, imgUri, binding.ivImg, 12)
presentation?.updateFood(foodInfo.copy(imgUrl = imgUri.toString()))
}
} else {
if (foodInfo.photoUri != null) {
GlideUtils.loadRoundCornerImage(this, foodInfo.photoUri, binding.ivImg, 12)
} else {
GlideUtils.loadRoundCornerImage(this, foodInfo.imgUrl, binding.ivImg, 12)
}
}
pauseAnalysis()
} else {
if (foodInfo == null) {
binding.tvFoodName.text = "-"
binding.previewView.visibility = View.VISIBLE
binding.ivImg.visibility = View.GONE
resumeAnalysis()
viewModel.cleanIdentifiedFoodInfoList()
return
}
pauseAnalysis()
presentation?.updateFood(foodInfo)
binding.tvFoodName.text = foodInfo.foodName
binding.previewView.visibility = View.GONE
binding.ivImg.visibility = View.VISIBLE
if (foodInfo.foodImg.isNullOrBlank()) {
takePhoto { imgUri ->
binding.ivImg.load(imgUri)
presentation?.updateFood(foodInfo.copy(foodImg = imgUri.toString()))
}
} else {
binding.ivImg.load(foodInfo.photoUri ?: foodInfo.foodImg)
}
//pauseAnalysis()
}
override fun registerDataChange() {
@@ -343,21 +347,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
@SuppressLint("NotifyDataSetChanged")
private fun updateFoodInfo(list: MutableList<FoodInfo>, scoreList: List<IdNameScore>) {
Timber.d("registerDataChange识别后查询接口数据:${GsonUtils.toJson(list)},识别数据:${GsonUtils.toJson(scoreList)}")
// TODO: 临时测试数据,后续删除-------------------
//if (list.isEmpty()) {
// //binding.flPay.visible()
// //binding.recyclerview.visible()
// //list.add(FoodInfo(foodName = "豆角茄子"))
// //list.add(FoodInfo(foodName = "豆芽炒粉条"))
// //list.add(FoodInfo(foodName = "岐山臊子面"))
// //list.add(FoodInfo(foodName = "肉末干拌面"))
// //list.add(FoodInfo(foodName = "雪菜肉丝面"))
// //list.add(FoodInfo(foodName = "康帅博方便面"))
// //list.add(FoodInfo(foodName = "担担面"))
// //list.add(FoodInfo(foodName = "四合一干拌面"))
//}
// TODO: 临时测试数据,后续删除-------------------
Timber.d(
"registerDataChange识别后查询接口数据:${GsonUtils.toJson(list)},识别数据:${
GsonUtils.toJson(
scoreList
)
}"
)
list.forEach { foodInfo ->
val scoreItem = scoreList.firstOrNull { it.name == foodInfo.foodName }
val score = scoreItem?.score ?: 0.0
@@ -476,7 +472,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
fun resumeAnalysis() {
Timber.d("resumeAnalysis isAnalyzing = $isAnalyzing")
if (isAnalyzing) return
isAnalyzing = true
// isAnalyzing = true
imageAnalysis?.setAnalyzer(executor) { imageProxy ->
if (presentation?.currentStep == 1) {
val bitmap = imageProxy.toBitmap()
@@ -578,13 +574,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
}
}
//SecondaryScreenPresentation(
// activity = this,
// this,
// display = secondaryDisplay,
// viewModel = viewModel,
// recognizeViewModel = viewModels<RecognizeViewModel>().value
//)
//SecondaryScreenPresentation(
// activity = this,
// this,
// display = secondaryDisplay,
// viewModel = viewModel,
// recognizeViewModel = viewModels<RecognizeViewModel>().value
//)
// presentation!!.setStepChangeCallback { step ->
// if (step == 1) {
// Timber.d("setStepChangeCallback${step}")
@@ -629,6 +625,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
val mode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0)
presentation?.updateMealPickupMode(mode ?: 0)
}
override fun onPause() {
super.onPause()
// 取消定时器
@@ -658,4 +655,61 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
handler.postDelayed(timeoutRunnable, TIME_OUT)
lastTouchTime = System.currentTimeMillis()
}
private fun createOrder(foodInfo: FoodInfo) {
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
val realWeight = (lastWeight * 1000).roundToInt()
val order = FoodOrder(
deviceId = GlobalData.deviceId,
foodId = foodInfo.foodId,
foodName = foodInfo.foodName ?: "",
foodMaterialId = foodInfo.foodMaterialId ?: "",
specId = foodInfo.specId ?: "",
foodWeight = realWeight,
eatWeight = realWeight,
//根据specId对应规格重量计算
eatNum = getEatNum(realWeight, foodInfo.specWeight ?: 0.0),
userId = null,
notPay = mode != 0,
)
viewModel.createOrder(order) { orderId ->
runOnUiThread {
if (orderId.isBlank()) {
ToastUtils.showToast("订单id为空")
return@runOnUiThread
}
foodOrderId = orderId
presentation?.dismiss()
startActivity(Intent(this, PayActivity::class.java).apply {
putExtra(PayActivity.FOOD_INFO, foodInfo)
putExtra(PayActivity.FOOD_ORDER_ID, orderId)
})
// ToastUtils.showToast("订单已生成")
}
}
}
private fun getEatNum(realWeight: Int, specWeight: Double): Int {
if (realWeight == 0 || specWeight == 0.0) return 0
return (realWeight / specWeight).roundToInt()
}
private var foodOrderId: String = ""
private var isExist = false
fun addBackEventListener() {
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (isExist.not()) {
ToastUtils.showToast("再按一次退出")
isExist = true
binding.root.postDelayed({
isExist = false
}, 2000)
return
}
finish()
}
})
}
}