This commit is contained in:
2026-01-09 18:38:55 +08:00
parent a6fa5f153a
commit ebc3d856d6
8 changed files with 98 additions and 52 deletions
+2 -2
View File
@@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-12-31T07:06:25.405532800Z"> <DropdownSelection timestamp="2026-01-09T06:05:40.833191600Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="Default" identifier="serial=192.168.1.45:5555;connection=52f5d52f" /> <DeviceId pluginId="Default" identifier="serial=192.168.1.35:5555;connection=d6972001" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>
@@ -377,7 +377,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
showWaitingDialog("识别中,请稍后……") showWaitingDialog("识别中,请稍后……")
takePhoto( takePhoto(
successCallback = { photoUri -> successCallback = { photoUri ->
Thread{ Thread {
onTakePhotoSuccess(photoUri) onTakePhotoSuccess(photoUri)
}.start() }.start()
failCount = 0 failCount = 0
@@ -766,22 +766,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
eatWeight: Int, eatWeight: Int,
eatNum: Int, eatNum: Int,
userId: String?, userId: String?,
notEnoughOneBlock: ()-> Unit = {}, notEnoughOneBlock: () -> Unit = {},
block: () -> Unit block: () -> Unit
) { ) {
Timber.tag(TAG).d("foodWeight=$foodWeight,eatWeight=$eatWeight") Timber.tag(TAG).d("foodWeight=$foodWeight,eatWeight=$eatWeight")
val pickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0 val pickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
if (pickupMode == 0) { // if (pickupMode == 0) {
if (foodWeight <= 5) { // if (foodWeight <= 5) {
ToastUtils.showToast("餐品重量不足") // ToastUtils.showToast("餐品重量不足")
return // return
} // }
if (eatWeight <= 5) { // if (eatWeight <= 5) {
ToastUtils.showToast("取餐重量过小") // ToastUtils.showToast("取餐重量过小")
return // return
} // }
} // }
if (eatNum == 0) { if (eatNum <= 0) {
ToastUtils.showToast("您好,当前重量不足一份") ToastUtils.showToast("您好,当前重量不足一份")
notEnoughOneBlock() notEnoughOneBlock()
return return
@@ -803,9 +803,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
//即放即取-1,称重-2 //即放即取-1,称重-2
mode = if (pickupMode == 1) 1 else 2 mode = if (pickupMode == 1) 1 else 2
) )
debouncer.debounce { submitOrder(order, block)
submitOrder(order, block)
}
} }
private fun submitOrder(order: FoodOrder, block: () -> Unit) { private fun submitOrder(order: FoodOrder, block: () -> Unit) {
@@ -822,7 +820,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
if (checkedItem!!.isFromSearch == true) { if (checkedItem!!.isFromSearch == true) {
//当前菜名为手动搜索选择,非识别结果,保存向量数据 //当前菜名为手动搜索选择,非识别结果,保存向量数据
Thread{ Thread {
saveFoodVector(checkedItem!!) saveFoodVector(checkedItem!!)
}.start() }.start()
} }
@@ -832,7 +830,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} }
fun getEatNum(realWeight: Double?, specWeight: Double?): Int { fun getEatNum(realWeight: Double?, specWeight: Double?): Int {
if (realWeight == null || realWeight == 0.0 || specWeight == null || specWeight == 0.0) return 1 if (realWeight == null || realWeight <= 0.0 || specWeight == null || specWeight <= 0.0) return 0
return (realWeight / specWeight).roundToInt() return (realWeight / specWeight).roundToInt()
} }
@@ -905,6 +903,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
//余量计量 //余量计量
eatWeight = (recognizeWeight - lastWeight) * 1000 eatWeight = (recognizeWeight - lastWeight) * 1000
foodWeight = recognizeWeight * 1000 foodWeight = recognizeWeight * 1000
Timber.d("eatWeight=$eatWeight, recognizeWeight=$recognizeWeight, lastWeight=$lastWeight")
} }
} else { } else {
//不计费 //不计费
@@ -1229,7 +1228,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
val file = BitmapSaver.saveToAppFilesDir( val file = BitmapSaver.saveToAppFilesDir(
bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg" bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
) )
Timber.tag(TAG).d("main,saveToAppFilesDir耗时:${System.currentTimeMillis() - startTime}") Timber.tag(TAG)
.d("main,saveToAppFilesDir耗时:${System.currentTimeMillis() - startTime}")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
Timber.d("registerDataChange photoUri bitmap保存文件路径:${file?.absolutePath}") Timber.d("registerDataChange photoUri bitmap保存文件路径:${file?.absolutePath}")
//val nameList = FoodModule.queryFood(bitmap) //val nameList = FoodModule.queryFood(bitmap)
@@ -148,4 +148,10 @@ data class FoodVector(
data class ResetBoxEvent( data class ResetBoxEvent(
var num: Int = 0 var num: Int = 0
)
data class WeightRecord(
var foodInfo: FoodInfo? = null,
var lastWeight: Int = 0,
var currentWeight: Int = 0
) )
@@ -59,6 +59,7 @@ import com.sw.plate.utils.arcface.face.model.CompareResult
import com.sw.plate.utils.arcface.face.model.FacePreviewInfo import com.sw.plate.utils.arcface.face.model.FacePreviewInfo
import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_READY
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@@ -109,7 +110,7 @@ class MainScreenPresentation(
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息 private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐 var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐
// var isKeepFaceState = true // var isKeepFaceState = true
var isKeepFaceState = false var isKeepFaceState = false
var currentUserId: String? = null var currentUserId: String? = null
@@ -162,7 +163,12 @@ class MainScreenPresentation(
isGoStep1 = false isGoStep1 = false
activity.runOnUiThread { activity.runOnUiThread {
Timber.tag(TAG).e("切回step1") Timber.tag(TAG).e("切回step1")
step1FoodRecognizing() if (mealPickupMode == 0) {
//即放即取
step1FoodRecognizing()
} else {
//秤上菜品不足,请补充
}
} }
} }
@@ -395,6 +401,7 @@ class MainScreenPresentation(
private var isLoadUnbilledMode = false private var isLoadUnbilledMode = false
private val df by lazy { DecimalFormat("#.##") } private val df by lazy { DecimalFormat("#.##") }
/** /**
* 餐品识别成功,不计费模式 * 餐品识别成功,不计费模式
*/ */
@@ -402,6 +409,20 @@ class MainScreenPresentation(
if (currentUserId.isNullOrBlank()) { if (currentUserId.isNullOrBlank()) {
return return
} }
//todo 清除人脸数据
// binding.dualCameraFaceRectView.clearFaceInfo()
// clearLeftFaceData()
// facePreviewInfoList?.clear()
// recognizeViewModel.updateRegisterStatus(REGISTER_STATUS_READY)
// pauseCamera()
// resumeCamera()
// TODO: 如何清除人脸数据重新识别
// stopCamera()
// setupArcCamera()
isLoadUnbilledMode = true isLoadUnbilledMode = true
Timber.tag(TAG).d("loadUnbilledMode") Timber.tag(TAG).d("loadUnbilledMode")
binding.calorieInclude.root.gone() binding.calorieInclude.root.gone()
@@ -419,7 +440,8 @@ class MainScreenPresentation(
binding.nutritionInclude.tvUserName.text = userNutrition?.name.maskName() binding.nutritionInclude.tvUserName.text = userNutrition?.name.maskName()
val recommendCalorie = userNutrition?.recommendCalorie ?: 0.0 val recommendCalorie = userNutrition?.recommendCalorie ?: 0.0
binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${df.format(recommendCalorie)}kcal" binding.nutritionInclude.tvRecommendHeat.text =
"推荐热量:${df.format(recommendCalorie)}kcal"
// binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${recommendCalorie.removeTrailingZeros()}kcal" // binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${recommendCalorie.removeTrailingZeros()}kcal"
//updateWeight(lastWeight / 1000) //updateWeight(lastWeight / 1000)
// ------------------------------------------------- // -------------------------------------------------
@@ -428,6 +450,9 @@ class MainScreenPresentation(
binding.root.postDelayed({ binding.root.postDelayed({
isLoadUnbilledMode = false isLoadUnbilledMode = false
}, 10000) }, 10000)
//上次已经识别过人脸
step3ShowRecognizeResult(currentUserId!!)
} }
private var isFirstOpen = true private var isFirstOpen = true
@@ -643,7 +668,7 @@ class MainScreenPresentation(
?: 0.0)) / 2, ?: 0.0)) / 2,
userNutrition?.maxCalorie ?: 0.0, userNutrition?.maxCalorie ?: 0.0,
) )
val calorieIndex = UserNutritionUtils.findCalorieIndex(energy.grain, calorieArray) val calorieIndex = UserNutritionUtils.findCalorieIndex(energy.calorie, calorieArray)
include.customKcalColumn.setImageDrawable(true, calorieIndex) include.customKcalColumn.setImageDrawable(true, calorieIndex)
var maxKcal = userNutrition?.maxCalorie ?: 1.0 var maxKcal = userNutrition?.maxCalorie ?: 1.0
Timber.tag(TAG).d("maxKcal = $maxKcal") Timber.tag(TAG).d("maxKcal = $maxKcal")
@@ -737,12 +762,16 @@ class MainScreenPresentation(
step1FoodRecognizing() step1FoodRecognizing()
} }
public override fun onStop() { fun stopCamera() {
rgbCameraHelper?.release() rgbCameraHelper?.release()
rgbCameraHelper = null rgbCameraHelper = null
irCameraHelper?.release() irCameraHelper?.release()
irCameraHelper = null irCameraHelper = null
recognizeViewModel.destroy() recognizeViewModel.destroy()
}
public override fun onStop() {
stopCamera()
super.onStop() super.onStop()
} }
@@ -760,6 +789,7 @@ class MainScreenPresentation(
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true) recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
} }
private var recognizeTime = 0L private var recognizeTime = 0L
private fun initArcViewModel() { private fun initArcViewModel() {
recognizeViewModel.setLiveType(livenessType) recognizeViewModel.setLiveType(livenessType)
@@ -1159,11 +1189,13 @@ class MainScreenPresentation(
return return
} }
createOrder(notEnoughOneBlock = { createOrder(notEnoughOneBlock = {
if (mealPickupMode == 0) { // if (mealPickupMode == 0) {
currentStep = 2 currentStep = 2
step2FaceRecognizing(currentFood!!) step2FaceRecognizing(currentFood!!)
} // }
}){ }) {
// TODO: 测试人脸识别问题--------------------
//recognizeViewModel.updateRegisterStatus(REGISTER_STATUS_READY)
if (MyApp.DEBUG) { if (MyApp.DEBUG) {
ToastUtils.showToast("订单已生成") ToastUtils.showToast("订单已生成")
} }
@@ -1182,7 +1214,7 @@ class MainScreenPresentation(
} }
} }
fun createOrder(notEnoughOneBlock: ()-> Unit={}, block: ()-> Unit) { fun createOrder(notEnoughOneBlock: () -> Unit = {}, block: () -> Unit) {
mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0 mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
val eatWeight = if (mealPickupMode == 0) { val eatWeight = if (mealPickupMode == 0) {
//即放即取 //即放即取
@@ -1214,7 +1246,7 @@ class MainScreenPresentation(
) )
} }
private fun clearLeftFaceData() { public fun clearLeftFaceData() {
facePreviewInfoList?.let { facePreviewInfoList?.let {
recognizeViewModel.clearLeftFace(facePreviewInfoList!!) recognizeViewModel.clearLeftFace(facePreviewInfoList!!)
} }
@@ -191,8 +191,8 @@ public class CustomImageView extends androidx.appcompat.widget.AppCompatImageVie
int myIndex = index; int myIndex = index;
if (index < 0) { if (index < 0) {
myIndex = 0; myIndex = 0;
}else if (index > 5) { }else if (index > 4) {
myIndex = 5; myIndex = 4;
} }
if (isBigImage) { if (isBigImage) {
//使用大图bigImgArr //使用大图bigImgArr
@@ -7,6 +7,7 @@ import com.sw.dualscreen.model.response.ApiResponse
import com.sw.dualscreen.model.response.EquipmentInfo import com.sw.dualscreen.model.response.EquipmentInfo
import com.sw.dualscreen.network.ApiClient import com.sw.dualscreen.network.ApiClient
import com.sw.dualscreen.repository.RemoteRepository import com.sw.dualscreen.repository.RemoteRepository
import com.sw.dualscreen.utils.Debouncer
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -24,15 +25,17 @@ abstract class BaseViewModel() : ViewModel() {
* 带进度条的请求 * 带进度条的请求
*/ */
protected fun launchWithLoading(block: suspend () -> Unit) { protected fun launchWithLoading(block: suspend () -> Unit) {
viewModelScope.launch { Debouncer(1000).debounce {
try { viewModelScope.launch {
_showLoading.value = true try {
block() _showLoading.value = true
} catch (e: Exception) { block()
// 错误处理可被子类重写 } catch (e: Exception) {
handleError(e) // 错误处理可被子类重写
} finally { handleError(e)
_showLoading.value = false } finally {
_showLoading.value = false
}
} }
} }
} }
@@ -41,19 +44,23 @@ abstract class BaseViewModel() : ViewModel() {
* 不带进度条的请求 * 不带进度条的请求
*/ */
protected fun launch(block: suspend () -> Unit) { protected fun launch(block: suspend () -> Unit) {
viewModelScope.launch() { Debouncer(1000).debounce {
try { viewModelScope.launch() {
block() try {
} catch (e: Exception) { block()
// 错误处理可被子类重写 } catch (e: Exception) {
handleError(e) // 错误处理可被子类重写
handleError(e)
}
} }
} }
} }
protected open fun parseResponse(response: ApiResponse<*>): Boolean { protected open fun parseResponse(response: ApiResponse<*>): Boolean {
val code = response.code val code = response.code
if (code == "00000" || code == "200" || code == "0") { //|| code == "200" || code == "0"
if (code == "00000" ) {
return true return true
} }
val message = response.msg val message = response.msg
@@ -15,6 +15,7 @@ import com.sw.dualscreen.model.response.UserFaceModel
import com.sw.dualscreen.model.response.UserFaceModel2 import com.sw.dualscreen.model.response.UserFaceModel2
import com.sw.dualscreen.model.response.UserNutrition import com.sw.dualscreen.model.response.UserNutrition
import com.sw.dualscreen.objbox.CollectedFoodInfo import com.sw.dualscreen.objbox.CollectedFoodInfo
import com.sw.dualscreen.utils.Debouncer
import com.sw.dualscreen.utils.SPUtil import com.sw.dualscreen.utils.SPUtil
import com.sw.dualscreen.utils.SpTool import com.sw.dualscreen.utils.SpTool
import com.sw.plate.App import com.sw.plate.App
@@ -563,7 +563,7 @@ public class RecognizeViewModel extends ViewModel implements RecognizeCallback {
} }
} }
private void updateRegisterStatus(int status) { public void updateRegisterStatus(int status) {
registerStatus = status; registerStatus = status;
} }