支付完成倒计时3秒返回首页;秤默认置零取消,打开直接识别物品;人脸识别图片显示拉伸优化;设置页面切换是否收费模式首页逻辑处理;

This commit is contained in:
2025-12-18 18:25:15 +08:00
parent 1d0e1a62e2
commit ab3109f36a
26 changed files with 540 additions and 258 deletions
@@ -9,6 +9,7 @@ import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.view.Display
import android.view.View
import android.view.ViewOutlineProvider
import androidx.activity.OnBackPressedCallback
@@ -30,8 +31,10 @@ 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.ChargeModeEvent
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.FoodOrder
import com.sw.dualscreen.model.response.PaySuccessEvent
import com.sw.dualscreen.objbox.FoodModule
import com.sw.dualscreen.objbox.FoodModule.IdNameScore
import com.sw.dualscreen.presentation.MainScreenPresentation
@@ -47,6 +50,8 @@ import com.sw.dualscreen.viewmodel.UserViewModel
import com.sw.plate.utils.LightManager
import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import timber.log.Timber
import java.io.File
import java.time.LocalDateTime
@@ -55,6 +60,7 @@ import java.time.format.DateTimeFormatter
import java.util.Locale
import java.util.concurrent.Executors
import kotlin.math.roundToInt
import kotlin.text.compareTo
/**
* 服务员显示界面
@@ -106,6 +112,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
private var lastPhotoUri: Uri? = null // 最后拍照的图片
private var debouncer = Debouncer(2000)
private var isRecognitionFood = true
private var isFirstOpen = true
override fun getViewModel(): BaseViewModel {
return viewModel
@@ -120,18 +127,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
addBackEventListener()
FoodModule.init(this)
initView()
setupSecondaryDisplay()
viewModel.getUserFaceCache(pageNo = 1)
//setupSecondaryDisplay()
setupCamera()
//presentation?.step1FoodRecognizing()
initData()
}
private fun initData() {
// viewModel.getEquipmentToken()
viewModel.getUserFaceCache(pageNo = 1)
//viewModel.getUserFaceCache2()
// presentation?.step1()
presentation?.step1FoodRecognizing()
}
private fun initView() {
@@ -146,7 +151,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
updateDateTime()
binding.ivSetting.setOnClickListener {
startActivity(Intent(this, SettingActivity::class.java))
finish()
//finish()
}
//binding.foodDisplayLayout.setOnClickListener {
// val intent = Intent(this, FoodCollectionActivity::class.java)
@@ -218,59 +223,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
// binding.tvRescan.setOnClickListener {
// debouncer.debounce { recognizeFood() }
// }
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
}
//val realWeight = (lastWeight * 1000).roundToInt()
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
var foodWeight = 0.0
var eatWeight = 0.0
if (chargeMode == 0) {
//计费
if (mealPickupMode == 0) {
//即放即取
eatWeight = lastWeight * 1000
foodWeight = lastWeight * 1000
} else {
//余量计量
eatWeight = (recognizeWeight - lastWeight) * 1000
foodWeight = recognizeWeight * 1000
}
} else {
//不计费
foodWeight = recognizeWeight * 1000
eatWeight = if (mealPickupMode == 0) {
//即放即取
recognizeWeight * 1000
} else {
//余量计量
(recognizeWeight - lastWeight) * 1000
}
}
val eatNum = getEatNum(eatWeight, checkedItem!!.specWeight)
createOrder(
foodInfo = checkedItem!!,
foodWeight = foodWeight.roundToInt(),
eatWeight = eatWeight.roundToInt(),
eatNum = eatNum
) {
presentation?.dismiss()
startActivity(Intent(this, PayActivity::class.java).apply {
putExtra(PayActivity.FOOD_INFO, checkedItem!!)
putExtra(PayActivity.FOOD_EAT_NUM, eatNum)
putExtra(PayActivity.FOOD_ORDER_ID, foodOrderId)
})
}
}
binding.btnPay.setOnClickListener {
clickPayButton()
}
}
@@ -288,19 +242,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
recognizeWeight = lastWeight
presentation?.updateFood(foodInfo)
binding.tvFoodName.text = foodInfo.foodName
binding.previewView.visibility = View.GONE
binding.ivImg.visibility = View.VISIBLE
binding.previewView.gone()
binding.ivImg.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)
}
binding.ivImg.load(foodInfo.foodImg ?: foodInfo.photoUri)
//pauseAnalysis()
}
fun updateImage(imgUrl: Any?) {
binding.ivImg.load(imgUrl)
}
override fun registerDataChange() {
super.registerDataChange()
//// lifecycleScope.launch {
@@ -326,24 +283,31 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
SensorScaleUtils.addWeightListener { weight ->
Timber.d("registerDataChange weight = $weight")
presentation?.updateWeight(weight)
if (weight <= 0.005) {//余量取餐,检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
isRecognitionFood = true
}
if (weight - lastWeight > 0.05 && isRecognitionFood) { // 大于50g
if (presentation?.mealPickupMode == 1) {
isRecognitionFood = false
}
debouncer.debounce {
recognizeFood()
}
}
lastWeight = weight
val isWeightChange = weight - lastWeight > 0.05
recognizeByWeight(weight, isWeightChange)
}
}
private fun recognizeByWeight(weight: Double, isWeightChange: Boolean, block: () -> Unit = {}) {
presentation?.updateWeight(weight)
if (weight <= 0.005) {//余量取餐,检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
isRecognitionFood = true
}
if (isWeightChange && isRecognitionFood) { // 大于50g
if (presentation?.mealPickupMode == 1) {
isRecognitionFood = false
}
debouncer.debounce {
recognizeFood()
}
} else {
block()
}
lastWeight = weight
}
fun recognizeFood() {
LightManager.openRedLight()
LightManager.openGreenLight()
@@ -590,9 +554,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onError(exception: ImageCaptureException) {
Timber.e("拍照失败: ${exception.message}")
runOnUiThread {
ToastUtils.showToast("拍照失败: ${exception.message}")
}
//runOnUiThread {
// ToastUtils.showToast("拍照失败: ${exception.message}")
//}
// 恢复图像分析
isAnalyzing = true
}
@@ -600,35 +564,44 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
)
}
private fun setupSecondaryDisplay() {
private fun getSecondaryDisplay(): Display? {
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.displays
// 查找副屏(通常索引为1
if (displays.size > 1) {
val secondaryDisplay = displays[1]
// 创建副屏的Presentation
presentation = MainScreenPresentation(
activity = this,
display = secondaryDisplay,
userViewModel = viewModel,
recognizeViewModel = viewModels<RecognizeViewModel>().value
).apply {
setStepChangeCallback { step ->
if (step == 1) {
Timber.d("setStepChangeCallback${step}")
updateCurrentFood(null)
bottomSheetDialog?.dismiss()
}
if (displays.size > 1) return displays[1]
return null
}
private fun setupSecondaryDisplay() {
val secondaryDisplay = getSecondaryDisplay()
if (secondaryDisplay == null) {
ToastUtils.showToast("获取副屏失败")
return
}
// 创建副屏的Presentation
presentation = MainScreenPresentation(
activity = this,
display = secondaryDisplay,
userViewModel = viewModel,
recognizeViewModel = viewModels<RecognizeViewModel>().value
).apply {
setStepChangeCallback { step ->
if (step == 1) {
Timber.d("setStepChangeCallback${step}")
updateCurrentFood(null)
bottomSheetDialog?.dismiss()
}
}
//SecondaryScreenPresentation(
// activity = this,
// this,
// display = secondaryDisplay,
// viewModel = viewModel,
// recognizeViewModel = viewModels<RecognizeViewModel>().value
//)
show()
}
//SecondaryScreenPresentation(
// activity = this,
// this,
// display = secondaryDisplay,
// viewModel = viewModel,
// recognizeViewModel = viewModels<RecognizeViewModel>().value
//)
// presentation!!.setStepChangeCallback { step ->
// if (step == 1) {
// Timber.d("setStepChangeCallback${step}")
@@ -636,10 +609,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
// bottomSheetDialog?.dismiss()
// }
// }
presentation!!.show()
} else {
ToastUtils.showToast("获取副屏失败")
}
}
@SuppressLint("NotifyDataSetChanged")
@@ -651,7 +620,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onDestroy() {
//SensorScaleUtils.closeScale()
presentation?.dismiss()
presentation?.cancel()
super.onDestroy()
shutdownCamera()
}
@@ -664,16 +633,45 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onResume() {
super.onResume()
Timber.tag("onResume").d("=================onResume================")
// 启动定时器
handler.postDelayed(timeoutRunnable, TIME_OUT)
if (presentation?.isShowing == false) {
if (isFirstOpen) {
//首次
setupSecondaryDisplay()
presentation?.step1FoodRecognizing()
isFirstOpen = false
} else {
//副屏未显示重新加载
isRecognitionFood = true
if (presentation == null || !presentation!!.isShowing) {
lastWeight = 0.0
setupSecondaryDisplay()
presentation?.step1FoodRecognizing()
} else {
//已显示副屏,则进行更新
val weight = lastWeight
lastWeight = 0.0
presentation?.hideRecImage()
recognizeByWeight(weight, true)
}
}
//根据付费模式确认是否显示按钮
binding.btnPay.run {
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
if (mode == 0) visible() else gone()
}
val mode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0)
presentation?.updateMealPickupMode(mode ?: 0)
}
// fun retry() {
// val weight = lastWeight
// lastWeight = 0.0
// presentation?.hideRecImage()
// recognizeByWeight(weight, true)
// }
override fun onPause() {
super.onPause()
// 取消定时器
@@ -712,12 +710,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
block: () -> Unit
) {
Timber.tag(TAG).d("foodWeight=$foodWeight,eatWeight=$eatWeight")
if (foodWeight <= 5 || eatWeight <= 5) {
ToastUtils.showToast("请取走餐品")
return
val pickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
if (pickupMode == 0) {
if (foodWeight <= 5 || eatWeight <= 5) {
ToastUtils.showToast("请取走餐品")
return
}
}
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
val pickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
val order = FoodOrder(
deviceId = GlobalData.deviceId,
foodId = foodInfo.foodId,
@@ -768,4 +768,67 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
})
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onPaySuccessEvent(event: PaySuccessEvent) {
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)?:0
presentation?.hideNutritionView(chargeMode)
presentation?.cancel()
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onChargeModeEvent(event: ChargeModeEvent) {
presentation?.hideNutritionView(event.chargeMode)
// presentation?.cancel()
}
private fun clickPayButton() {
if (checkedItem == null) {
ToastUtils.showToast("暂无识别数据,请搜索选择")
return
}
//val realWeight = (lastWeight * 1000).roundToInt()
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
var foodWeight = 0.0
var eatWeight = 0.0
if (chargeMode == 0) {
//计费
if (mealPickupMode == 0) {
//即放即取
eatWeight = lastWeight * 1000
foodWeight = lastWeight * 1000
} else {
//余量计量
eatWeight = (recognizeWeight - lastWeight) * 1000
foodWeight = recognizeWeight * 1000
}
} else {
//不计费
foodWeight = recognizeWeight * 1000
eatWeight = if (mealPickupMode == 0) {
//即放即取
recognizeWeight * 1000
} else {
//余量计量
(recognizeWeight - lastWeight) * 1000
}
}
val eatNum = getEatNum(eatWeight, checkedItem!!.specWeight)
createOrder(
foodInfo = checkedItem!!,
foodWeight = foodWeight.roundToInt(),
eatWeight = eatWeight.roundToInt(),
eatNum = eatNum
) {
// TODO: 暂不关闭首页副屏
//presentation?.dismiss()
startActivity(Intent(this, PayActivity::class.java).apply {
putExtra(PayActivity.FOOD_INFO, checkedItem!!)
putExtra(PayActivity.FOOD_EAT_NUM, eatNum)
putExtra(PayActivity.FOOD_ORDER_ID, foodOrderId)
})
}
}
}