接口调试、增加人脸识别后主副屏支付金额逻辑、其它优化
This commit is contained in:
@@ -16,6 +16,7 @@ import android.view.ViewOutlineProvider
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.arcsoft.face.ErrorInfo
|
||||
@@ -26,6 +27,7 @@ import com.sw.dualscreen.databinding.PresentationMainScreenBinding
|
||||
import com.sw.dualscreen.ext.dp
|
||||
import com.sw.dualscreen.ext.format2String
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.ext.maskName
|
||||
import com.sw.dualscreen.ext.visible
|
||||
import com.sw.dualscreen.model.request.UserNutritionParam
|
||||
@@ -33,8 +35,6 @@ import com.sw.dualscreen.model.response.DinnerType
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.model.response.UserNutritionData
|
||||
import com.sw.dualscreen.utils.Debouncer
|
||||
import com.sw.dualscreen.utils.GlideUtils
|
||||
import com.sw.dualscreen.utils.GsonUtils
|
||||
import com.sw.dualscreen.utils.SPUtil
|
||||
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||
import com.sw.plate.utils.LightManager
|
||||
@@ -55,6 +55,7 @@ import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class MainScreenPresentation(
|
||||
@@ -63,7 +64,7 @@ class MainScreenPresentation(
|
||||
val userViewModel: UserViewModel,
|
||||
val recognizeViewModel: RecognizeViewModel,
|
||||
private val onDismissListener: () -> Unit = {}
|
||||
) : Presentation(activity, display), ViewTreeObserver.OnGlobalLayoutListener {
|
||||
) : Presentation(activity, display), ViewTreeObserver.OnGlobalLayoutListener {
|
||||
|
||||
companion object {
|
||||
const val TAG = "SubScreenPresentation"
|
||||
@@ -71,6 +72,7 @@ class MainScreenPresentation(
|
||||
|
||||
private lateinit var binding: PresentationMainScreenBinding
|
||||
private lateinit var stepChangeCallback: (Int) -> Unit
|
||||
|
||||
// 当前步骤
|
||||
var currentStep: Int = 0
|
||||
|
||||
@@ -110,11 +112,19 @@ class MainScreenPresentation(
|
||||
|
||||
fun updateWeight(weight: Double) {
|
||||
lastWeight = weight * 1000 // 将千克转成克
|
||||
Timber.tag(TAG).d("updateWeight lastWeight = $weight, currentStep = $currentStep, isGoStep1 = $isGoStep1")
|
||||
if ((currentStep == 2) &&
|
||||
lastWeight <= 5 &&
|
||||
isGoStep1
|
||||
) {//人脸识别过程中,秤上物品拿走
|
||||
Timber.tag(TAG)
|
||||
.d("updateWeight lastWeight = $weight, currentStep = $currentStep, isGoStep1 = $isGoStep1")
|
||||
// if (lastWeight <= 5) {
|
||||
// activity.isAnalyzing = false
|
||||
// }
|
||||
if (currentStep == 2 && lastWeight <= 5 && isGoStep1) {
|
||||
//人脸识别过程中,秤上物品拿走
|
||||
isGoStep1 = false
|
||||
activity.runOnUiThread {
|
||||
Timber.tag(TAG).e("切回step1")
|
||||
step1FoodRecognizing()
|
||||
}
|
||||
} else if (lastWeight <= 5) {
|
||||
isGoStep1 = false
|
||||
activity.runOnUiThread {
|
||||
Timber.tag(TAG).e("切回step1")
|
||||
@@ -140,6 +150,7 @@ class MainScreenPresentation(
|
||||
}
|
||||
calculateNutrition(recognitionWeight - lastWeight)
|
||||
}
|
||||
|
||||
fun setStepChangeCallback(callback: (Int) -> Unit) {
|
||||
stepChangeCallback = callback
|
||||
}
|
||||
@@ -200,10 +211,10 @@ class MainScreenPresentation(
|
||||
Timber.tag(TAG).d("registerDataChange nutritionData = $it")
|
||||
userNutritionData = it
|
||||
if (it == null) return@collect
|
||||
step3ShowRecognizeResult()
|
||||
//binding.nutritionInclude.tvUserName.text = it.userName.maskName()
|
||||
//binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${it.recommendMin}-${it.recommendMax}"
|
||||
//updateWeight(lastWeight / 1000)
|
||||
// step3ShowRecognizeResult()
|
||||
// //binding.nutritionInclude.tvUserName.text = it.userName.maskName()
|
||||
// //binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${it.recommendMin}-${it.recommendMax}"
|
||||
// //updateWeight(lastWeight / 1000)
|
||||
}
|
||||
}
|
||||
activity.lifecycleScope.launch {
|
||||
@@ -227,20 +238,22 @@ class MainScreenPresentation(
|
||||
ToastUtils.showToast("选中物品为空")
|
||||
return
|
||||
}
|
||||
updateFoodInfo(currentFood!!)
|
||||
// updateFoodInfo(currentFood!!)
|
||||
|
||||
foodRecSuccess(currentFood!!)
|
||||
//foodRecSuccess(currentFood!!)
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
// //binding.ivRecImage.let {
|
||||
// it.outlineProvider = object : ViewOutlineProvider() {
|
||||
// override fun getOutline(view: View, outline: Outline) {
|
||||
// outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
|
||||
// }
|
||||
// }
|
||||
// it.clipToOutline = true
|
||||
// }
|
||||
binding.ivRecImage.let {
|
||||
it.outlineProvider = object : ViewOutlineProvider() {
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
|
||||
}
|
||||
}
|
||||
it.clipToOutline = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisplayRemoved() {
|
||||
super.onDisplayRemoved()
|
||||
onDismissListener()
|
||||
@@ -274,11 +287,46 @@ class MainScreenPresentation(
|
||||
|
||||
//updateFoodInfo(foodInfo)
|
||||
|
||||
userNutritionData?.let {
|
||||
Timber.tag(TAG).d("loadBilledMode:${GsonUtils.toJson(it)}")
|
||||
// userNutritionData?.let {
|
||||
// Timber.tag(TAG).d("loadBilledMode:${GsonUtils.toJson(it)}")
|
||||
// }
|
||||
currentFood?.let {
|
||||
val specPrice = it.specPrice?:0.0
|
||||
val vipPrice = it.vipPrice?:0.0
|
||||
binding.tvNormalPrice.text = "${specPrice.format2String(2)} 元/份"
|
||||
binding.tvVipPrice.text = "${vipPrice.format2String(2)} 元/份"
|
||||
|
||||
var calorie = getIntNutritionValue(it.calorie)
|
||||
calorie = max(calorie, 0)
|
||||
val fat = getIntNutritionValue(it.fat)
|
||||
val protein = getIntNutritionValue(it.protein)
|
||||
val carbohydrate = getIntNutritionValue(it.carbohydrate)
|
||||
|
||||
val fatRate = getNutritionRate(fat, calorie)
|
||||
val proteinRate = getNutritionRate(protein, calorie)
|
||||
val carbohydrateRate = getNutritionRate(carbohydrate, calorie)
|
||||
binding.calorieInclude.run {
|
||||
tvCalorie.text = "$calorie"
|
||||
tvFatRate.text = "$fatRate%"
|
||||
tvProteinRate.text = "$proteinRate%"
|
||||
tvCarbohydrateRate.text = "$carbohydrateRate%"
|
||||
|
||||
viewFatLine.updateLayoutParams { height = (fatRate/100.0*84).roundToInt()*1.dp }
|
||||
viewProteinLine.updateLayoutParams { height = (proteinRate/100.0*84).roundToInt()*1.dp }
|
||||
viewCarbohydrateLine.updateLayoutParams { height = (carbohydrateRate/100.0*84).roundToInt()*1.dp }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun getNutritionRate(value: Int, total: Int): Int{
|
||||
if (value == 0 || total == 0) return 0
|
||||
return (100.0 * value / total).roundToInt()
|
||||
}
|
||||
|
||||
private fun getIntNutritionValue(text: String?): Int {
|
||||
return if (text.isNullOrBlank()) 0 else text.toFloat().roundToInt() }
|
||||
|
||||
/**
|
||||
* 餐品识别成功,不计费模式
|
||||
*/
|
||||
@@ -296,7 +344,8 @@ class MainScreenPresentation(
|
||||
//updateFoodInfo(foodInfo)
|
||||
userNutritionData?.let {
|
||||
binding.nutritionInclude.tvUserName.text = it.userName.maskName()
|
||||
binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${it.recommendMin}-${it.recommendMax}kcal"
|
||||
binding.nutritionInclude.tvRecommendHeat.text =
|
||||
"推荐热量:${it.recommendMin}-${it.recommendMax}kcal"
|
||||
updateWeight(lastWeight / 1000)
|
||||
}
|
||||
}
|
||||
@@ -307,7 +356,7 @@ class MainScreenPresentation(
|
||||
fun step1FoodRecognizing() {
|
||||
hideStandbyScreen()
|
||||
activity.resetTouchTime()
|
||||
|
||||
activity.resumeAnalysis()
|
||||
Timber.tag(TAG).d("step1")
|
||||
//if (abs(lastWeight.toInt()) <= 5) {
|
||||
// activity.runOnUiThread {
|
||||
@@ -332,8 +381,8 @@ class MainScreenPresentation(
|
||||
binding.tvFoodName.text = "餐品识别中..."
|
||||
binding.tvFoodRecPrompt.visible()
|
||||
binding.flCameraView.visible()
|
||||
binding.ivRecImage.gone()
|
||||
binding.ivPreviewImage.visible()
|
||||
//binding.ivRecImage.gone()
|
||||
binding.ivFaceRecMask.gone()
|
||||
binding.tvFaceTip.gone()
|
||||
binding.llPriceInfo.gone()
|
||||
@@ -344,17 +393,21 @@ class MainScreenPresentation(
|
||||
activity.clearFoodList()
|
||||
}
|
||||
|
||||
fun foodRecSuccess(foodInfo: FoodInfo) {
|
||||
//识别逻辑完成根据是否计费显示不同页面
|
||||
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
if (mode == 0) {
|
||||
//计费
|
||||
loadBilledMode()
|
||||
} else {
|
||||
//不计费
|
||||
loadUnbilledMode()
|
||||
}
|
||||
}
|
||||
// fun foodRecSuccess(foodInfo: FoodInfo) {
|
||||
// //识别逻辑完成根据是否计费显示不同页面
|
||||
// val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
// if (mode == 0) {
|
||||
// //计费
|
||||
// loadBilledMode()
|
||||
// } else {
|
||||
// //不计费
|
||||
// //userViewModel.getUserNutritionData(
|
||||
// // userId = userId,
|
||||
// // foodId = currentFood!!.foodId!!
|
||||
// //)
|
||||
// loadUnbilledMode()
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 用户人脸识别中
|
||||
@@ -377,7 +430,7 @@ class MainScreenPresentation(
|
||||
binding.tvFoodRecPrompt.visible()
|
||||
binding.llPriceInfo.gone()
|
||||
|
||||
//binding.ivRecImage.gone()
|
||||
binding.ivRecImage.gone()
|
||||
binding.ivPreviewImage.gone()
|
||||
|
||||
dinnerTypeInfo = null
|
||||
@@ -386,7 +439,9 @@ class MainScreenPresentation(
|
||||
|
||||
stepChangeCallback(currentStep)
|
||||
currentFood = foodInfo
|
||||
|
||||
userViewModel.getDinnerType()
|
||||
|
||||
resumeCamera()
|
||||
}
|
||||
|
||||
@@ -395,18 +450,37 @@ class MainScreenPresentation(
|
||||
fun updateFood(foodInfo: FoodInfo?) {
|
||||
Timber.tag(TAG).d("updateFood")
|
||||
currentFood = foodInfo
|
||||
if (foodInfo != null) {
|
||||
if (foodInfo == null) {
|
||||
return
|
||||
}
|
||||
binding.tvFoodName.text = foodInfo.foodName
|
||||
binding.ivPreviewImage.gone()
|
||||
binding.ivRecImage.let {
|
||||
it.visible()
|
||||
val imageUrl = if (foodInfo.foodImg.isNullOrBlank()) foodInfo.photoUri else foodInfo.foodImg
|
||||
it.load(imageUrl)
|
||||
}
|
||||
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
if (mode == 0) {
|
||||
//计费,查询营养信息、价格信息------------------------
|
||||
loadBilledMode()
|
||||
} else {
|
||||
//不计费
|
||||
//开启人脸识别
|
||||
if (currentStep == 1) {
|
||||
step2FaceRecognizing(foodInfo)
|
||||
} else {
|
||||
updateFoodInfo(foodInfo)
|
||||
}
|
||||
}
|
||||
//if (currentStep == 1) {
|
||||
// step2FaceRecognizing(foodInfo)
|
||||
//} else {
|
||||
// updateFoodInfo(foodInfo)
|
||||
//}
|
||||
}
|
||||
|
||||
private fun updateFoodInfo(foodInfo: FoodInfo) {
|
||||
binding.tvFoodName.text = foodInfo.foodName
|
||||
binding.ivPreviewImage.gone()
|
||||
// binding.tvFoodName.text = foodInfo.foodName
|
||||
// binding.ivPreviewImage.gone()
|
||||
//binding.ivRecImage.visible()
|
||||
// if (foodInfo.photoUri != null) {
|
||||
// GlideUtils.loadRoundCornerImage(
|
||||
@@ -429,9 +503,11 @@ class MainScreenPresentation(
|
||||
var weight = weight1
|
||||
if (weight < 0) weight = 0.0
|
||||
debouncer.debounce {
|
||||
Timber.tag(TAG).d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
||||
Timber.tag(TAG)
|
||||
.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
||||
val dinnerType = dinnerTypeInfo!!.dinnerType!!
|
||||
Timber.tag(TAG).d("calculateNutrition foodName = ${currentFood!!.foodName}, dinnerType = $dinnerType, userId = ${userNutritionData!!.userId}")
|
||||
Timber.tag(TAG)
|
||||
.d("calculateNutrition foodName = ${currentFood!!.foodName}, dinnerType = $dinnerType, userId = ${userNutritionData!!.userId}")
|
||||
val calcResultInfo = UserNutritionUtils.calculateNutrition(
|
||||
currentFood!!,
|
||||
userNutritionData!!,
|
||||
@@ -528,6 +604,7 @@ class MainScreenPresentation(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateImage(bitmap: Bitmap) {
|
||||
activity.runOnUiThread {
|
||||
binding.ivPreviewImage.setImageBitmap(bitmap)
|
||||
@@ -538,10 +615,11 @@ class MainScreenPresentation(
|
||||
* 余量取餐
|
||||
*/
|
||||
fun updateMealPickupMode(mode: Int) {
|
||||
Timber.tag(TAG).d("updateMealPickupMode mode = $mode")
|
||||
mealPickupMode = mode
|
||||
step1FoodRecognizing()
|
||||
Timber.tag(TAG).d("updateMealPickupMode mode = $mode")
|
||||
mealPickupMode = mode
|
||||
step1FoodRecognizing()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
if (rgbCameraHelper != null) {
|
||||
rgbCameraHelper!!.release()
|
||||
@@ -605,7 +683,8 @@ class MainScreenPresentation(
|
||||
|
||||
recognizeViewModel.recognizeConfiguration
|
||||
.observe(activity, Observer { recognizeConfiguration: RecognizeConfiguration? ->
|
||||
Timber.tag(TAG).i("recognizeConfiguration: observe = ${recognizeConfiguration.toString()}")
|
||||
Timber.tag(TAG)
|
||||
.i("recognizeConfiguration: observe = ${recognizeConfiguration.toString()}")
|
||||
})
|
||||
recognizeViewModel.recognizeNotice.observe(activity, Observer { notice: String? ->
|
||||
Timber.tag(TAG).i("recognizeNotice observe notice = $notice")
|
||||
@@ -614,26 +693,34 @@ class MainScreenPresentation(
|
||||
recognizeViewModel.recognizeUserId.observe(
|
||||
activity,
|
||||
Observer { compareResult: CompareResult ->
|
||||
Timber.tag(TAG).i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}")
|
||||
Timber.tag(TAG)
|
||||
.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}")
|
||||
recognitionTime = System.currentTimeMillis()
|
||||
recognitionWeight = lastWeight
|
||||
lastFaceTrackId = compareResult.trackId
|
||||
val faceEntity = compareResult.faceEntity
|
||||
val userId = faceEntity.userName
|
||||
if (userId == null ) return@Observer
|
||||
if (userId == null) return@Observer
|
||||
if (currentFood == null) {
|
||||
//重新识别
|
||||
activity.runOnUiThread {
|
||||
ToastUtils.showToast("currentFood == null")
|
||||
}
|
||||
//activity.recognizeFood()
|
||||
//step1FoodRecognizing()
|
||||
return@Observer
|
||||
currentFood = activity.checkedItem
|
||||
}
|
||||
userViewModel.getUserNutritionData(
|
||||
userId = userId,
|
||||
foodId = currentFood!!.foodId!!
|
||||
)
|
||||
if (currentFood == null) {
|
||||
activity.runOnUiThread {
|
||||
ToastUtils.showToast("请选择菜品")
|
||||
return@runOnUiThread
|
||||
}
|
||||
}
|
||||
// TODO: ------------------人脸识别成功
|
||||
//-------------------------------------------------
|
||||
// TODO: ------------------人脸识别成功
|
||||
|
||||
step3ShowRecognizeResult()
|
||||
//根据接口数据更新热量数据--------------------------
|
||||
loadUnbilledMode()
|
||||
// userViewModel.getUserNutritionData(
|
||||
// userId = userId,
|
||||
// foodId = currentFood!!.foodId!!
|
||||
// )
|
||||
})
|
||||
|
||||
recognizeViewModel.drawRectInfoText.observe(activity, Observer { info ->
|
||||
@@ -724,7 +811,8 @@ class MainScreenPresentation(
|
||||
displayOrientation: Int,
|
||||
isMirror: Boolean
|
||||
) {
|
||||
Timber.tag(TAG).d("initRgbCamera Rgb onCameraOpened: cameraId = $cameraId, displayOrientation = $displayOrientation")
|
||||
Timber.tag(TAG)
|
||||
.d("initRgbCamera Rgb onCameraOpened: cameraId = $cameraId, displayOrientation = $displayOrientation")
|
||||
activity.runOnUiThread({
|
||||
val previewSizeRgb = camera.getParameters().getPreviewSize()
|
||||
val layoutParams = adjustPreviewViewSize(
|
||||
@@ -733,8 +821,10 @@ class MainScreenPresentation(
|
||||
previewSizeRgb, displayOrientation, 0.6F
|
||||
)
|
||||
|
||||
Timber.tag(TAG).d("initRgbCamera previewSizeRgb = ${previewSizeRgb.width}-${previewSizeRgb.height}")
|
||||
Timber.tag(TAG).d("initRgbCamera layoutParams = ${layoutParams.width}-${layoutParams.height}")
|
||||
Timber.tag(TAG)
|
||||
.d("initRgbCamera previewSizeRgb = ${previewSizeRgb.width}-${previewSizeRgb.height}")
|
||||
Timber.tag(TAG)
|
||||
.d("initRgbCamera layoutParams = ${layoutParams.width}-${layoutParams.height}")
|
||||
Timber.tag(TAG).d(
|
||||
"initRgbCamera isMirror = ${isMirror}, isDrawRgbRectHorizontalMirror = ${
|
||||
ConfigUtil.isDrawRgbRectHorizontalMirror(
|
||||
@@ -790,16 +880,19 @@ class MainScreenPresentation(
|
||||
}
|
||||
|
||||
override fun onCameraConfigurationChanged(cameraID: Int, displayOrientation: Int) {
|
||||
Timber.tag(TAG).i("initRgbCamera onCameraConfigurationChanged: threadName = ${Thread.currentThread().name}")
|
||||
Timber.tag(TAG)
|
||||
.i("initRgbCamera onCameraConfigurationChanged: threadName = ${Thread.currentThread().name}")
|
||||
if (rgbFaceRectTransformer != null) {
|
||||
rgbFaceRectTransformer!!.cameraDisplayOrientation = displayOrientation
|
||||
}
|
||||
Timber.tag(TAG).i("initRgbCamera onCameraConfigurationChanged: $cameraID $displayOrientation")
|
||||
Timber.tag(TAG)
|
||||
.i("initRgbCamera onCameraConfigurationChanged: $cameraID $displayOrientation")
|
||||
}
|
||||
}
|
||||
val measuredWidth = binding.dualCameraTexturePreviewRgb.measuredWidth
|
||||
val measuredHeight = binding.dualCameraTexturePreviewRgb.measuredHeight
|
||||
Timber.tag(TAG).i("initRgbCamera measuredWidth=$measuredWidth,measuredHeight=$measuredHeight")
|
||||
val measuredHeight = binding.dualCameraTexturePreviewRgb.measuredHeight
|
||||
Timber.tag(TAG)
|
||||
.i("initRgbCamera measuredWidth=$measuredWidth,measuredHeight=$measuredHeight")
|
||||
|
||||
val previewConfig: PreviewConfig = recognizeViewModel.previewConfig
|
||||
rgbCameraHelper = DualCameraHelper.Builder()
|
||||
@@ -831,7 +924,8 @@ class MainScreenPresentation(
|
||||
displayOrientation: Int,
|
||||
isMirror: Boolean
|
||||
) {
|
||||
Timber.tag(TAG).d("initIrCamera IR onCameraOpened: cameraId = $cameraId, displayOrientation = $displayOrientation")
|
||||
Timber.tag(TAG)
|
||||
.d("initIrCamera IR onCameraOpened: cameraId = $cameraId, displayOrientation = $displayOrientation")
|
||||
val previewSizeIr = camera.getParameters().getPreviewSize()
|
||||
val layoutParams = adjustPreviewViewSize(
|
||||
binding.dualCameraTexturePreviewRgb,
|
||||
@@ -872,7 +966,8 @@ class MainScreenPresentation(
|
||||
if (irFaceRectTransformer != null) {
|
||||
irFaceRectTransformer!!.cameraDisplayOrientation = displayOrientation
|
||||
}
|
||||
Timber.tag(TAG).i("initIrCamera onCameraConfigurationChanged: cameraID = $cameraID, displayOrientation = $displayOrientation")
|
||||
Timber.tag(TAG)
|
||||
.i("initIrCamera onCameraConfigurationChanged: cameraID = $cameraID, displayOrientation = $displayOrientation")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,14 +1011,17 @@ class MainScreenPresentation(
|
||||
// 识别成功
|
||||
binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList)
|
||||
}
|
||||
|
||||
if (facePreviewInfoList.isEmpty() || (lastFaceTrackId != facePreviewInfoList[0]!!.trackId)) {
|
||||
val listIsEmpty = facePreviewInfoList.isEmpty()
|
||||
val listFirstTrackId = if (listIsEmpty.not()) facePreviewInfoList[0]!!.trackId else null
|
||||
Timber.tag(TAG).d("listIsEmpty=$listIsEmpty,lastFaceTrackId=$lastFaceTrackId,listFirstTrackId=$listFirstTrackId")
|
||||
if (listIsEmpty || (lastFaceTrackId != listFirstTrackId)) {
|
||||
if (lastFaceTrackId != -1) {
|
||||
mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||
Timber.tag(TAG).i("$lastFaceTrackId 用户离开")
|
||||
lastFaceTrackId = -1
|
||||
postUserData()
|
||||
if (mealPickupMode == 0) {
|
||||
activity.isAnalyzing = false
|
||||
step1FoodRecognizing()
|
||||
} else {
|
||||
step2FaceRecognizing(currentFood!!)
|
||||
@@ -935,7 +1033,8 @@ class MainScreenPresentation(
|
||||
fun postUserData() {
|
||||
Timber.tag(TAG).d("postUserData")
|
||||
if (userNutritionData == null || currentFood == null) {
|
||||
Timber.tag(TAG).d("postUserData userNutritionData = ${userNutritionData == null}, currentFood = ${currentFood == null}")
|
||||
Timber.tag(TAG)
|
||||
.d("postUserData userNutritionData = ${userNutritionData == null}, currentFood = ${currentFood == null}")
|
||||
return
|
||||
}
|
||||
var eatWeight = 0.0
|
||||
@@ -947,7 +1046,7 @@ class MainScreenPresentation(
|
||||
}
|
||||
val userNutritionParam = UserNutritionParam(
|
||||
userId = userNutritionData?.userId!!,
|
||||
foodId = currentFood?.foodId !!,
|
||||
foodId = currentFood?.foodId!!,
|
||||
faceTime = recognitionTime,
|
||||
faceEndTime = System.currentTimeMillis(),
|
||||
eatWeight = eatWeight,//lastWeight
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.databinding.PresentationFacePayBinding
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.utils.GsonUtils
|
||||
import com.sw.dualscreen.view.CustomDialog
|
||||
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||
import com.sw.plate.utils.ToastUtils
|
||||
@@ -267,13 +268,30 @@ class FacePayPresentation(
|
||||
activity.runOnUiThread {
|
||||
//ToastUtils.showToast("用户人脸识别成功,挑战支付页面")
|
||||
showWaitingDialog("刷脸支付中,请稍后……")
|
||||
binding.root.postDelayed({
|
||||
hideWaitingDialog()
|
||||
activity.paySuccess()
|
||||
binding.root.postDelayed({
|
||||
dismiss()
|
||||
},500)
|
||||
},1500)
|
||||
userViewModel.getMemberInfo(memberId = userId) { memberInfo ->
|
||||
activity.runOnUiThread {
|
||||
if (memberInfo == null) {
|
||||
ToastUtils.showToast("查询会员信息失败,请稍后重试")
|
||||
return@runOnUiThread
|
||||
}
|
||||
userViewModel.bindOrder(userId, activity.foodOrderId) { bindResult ->
|
||||
activity.runOnUiThread {
|
||||
if (bindResult.not()) {
|
||||
hideWaitingDialog()
|
||||
ToastUtils.showToast("订单绑定失败")
|
||||
return@runOnUiThread
|
||||
}
|
||||
binding.root.postDelayed({
|
||||
hideWaitingDialog()
|
||||
activity.showPayInfo(memberInfo)
|
||||
binding.root.postDelayed({
|
||||
dismiss()
|
||||
},500)
|
||||
},1500)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// userViewModel.getUserNutritionData(
|
||||
// userId = userId,
|
||||
@@ -577,6 +595,8 @@ class FacePayPresentation(
|
||||
// } else {
|
||||
// step2FaceRecognizing(currentFood!!)
|
||||
// }
|
||||
|
||||
resumeCamera()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+108
-44
@@ -2,24 +2,23 @@ package com.sw.dualscreen.presentation.pay
|
||||
|
||||
import android.app.Presentation
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.text.SpannedString
|
||||
import android.text.style.AbsoluteSizeSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.Display
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.text.buildSpannedString
|
||||
import com.sw.dualscreen.R
|
||||
import com.sw.dualscreen.activity.PayActivity
|
||||
import com.sw.dualscreen.databinding.PresentationScanQrcodePayBinding
|
||||
import com.sw.dualscreen.ext.format2String
|
||||
import com.sw.dualscreen.ext.gone
|
||||
import com.sw.dualscreen.ext.invisible
|
||||
import com.sw.dualscreen.ext.load
|
||||
import com.sw.dualscreen.ext.visible
|
||||
import com.sw.dualscreen.model.response.MemberInfo
|
||||
import com.sw.dualscreen.model.response.TextBean
|
||||
import com.sw.dualscreen.utils.SpannedUtils
|
||||
|
||||
class ScanQrCodePayPresentation(
|
||||
val activity: PayActivity,
|
||||
display: Display,
|
||||
val type:Int,
|
||||
val type: Int,
|
||||
private val onDismissListener: () -> Unit = {}
|
||||
) : Presentation(activity, display) {
|
||||
|
||||
@@ -38,74 +37,139 @@ class ScanQrCodePayPresentation(
|
||||
}
|
||||
|
||||
var foodName: String? = null
|
||||
var payAmount: String? = null
|
||||
var payQrCodePic: Any? = null
|
||||
|
||||
//总价格
|
||||
var totalPrice = 0.0
|
||||
|
||||
//余额
|
||||
private var balance = 0.0
|
||||
|
||||
//实际支付金额
|
||||
private var realPayPrice = 0.0
|
||||
//扣除余额
|
||||
private var expensesBalance = 0.0
|
||||
|
||||
private fun initView() {
|
||||
when(type) {
|
||||
0->{
|
||||
when (type) {
|
||||
0 -> {
|
||||
binding.layoutVip.gone()
|
||||
binding.layoutPaySuccess.gone()
|
||||
binding.layoutScanQrCode.visible()
|
||||
|
||||
binding.tvPayTip.text = "请扫码支付或出示付款码"
|
||||
binding.tvFoodName.text = foodName
|
||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||
binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
||||
listOf(
|
||||
TextBean(text = "¥", textSize = 32),
|
||||
TextBean(text = totalPrice.format2String(2), textSize = 48),
|
||||
)
|
||||
)
|
||||
binding.ivPayQrCode.load(payQrCodePic)
|
||||
}
|
||||
1->{
|
||||
|
||||
1 -> {
|
||||
binding.layoutVip.visible()
|
||||
binding.layoutPaySuccess.gone()
|
||||
binding.layoutScanQrCode.visible()
|
||||
|
||||
val memberInfo = activity.memberInfo
|
||||
totalPrice = activity.foodInfo?.vipPrice ?: 0.0
|
||||
balance = (memberInfo?.topUpBalance ?: 0.0) + (memberInfo?.rewardBalance ?: 0.0)
|
||||
realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
||||
expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
||||
|
||||
memberInfo?.let { loadUserInfo(it) }
|
||||
binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
||||
listOf(
|
||||
TextBean(text = "¥", textSize = 20),
|
||||
TextBean(text = balance.format2String(2), textSize = 32),
|
||||
)
|
||||
)
|
||||
|
||||
binding.tvFoodName.text = foodName
|
||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||
binding.ivPayQrCode.load(payQrCodePic)
|
||||
binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
||||
listOf(
|
||||
TextBean(text = "¥", textSize = 32),
|
||||
TextBean(text = totalPrice.format2String(2), textSize = 48),
|
||||
)
|
||||
)
|
||||
binding.ivPayQrCode.run {
|
||||
// load(payQrCodePic)
|
||||
if (balance >= totalPrice) invisible() else visible()
|
||||
}
|
||||
|
||||
binding.ivHeadPic.load(R.mipmap.ic_launcher)
|
||||
binding.tvUserName.text = "张三"
|
||||
binding.tvUserPhone.text = "132****5678"
|
||||
binding.tvUserBalance.text = getBalanceText("0.00")
|
||||
|
||||
binding.tvPayTip.text = getPayTip("-16.80", "22.00")
|
||||
binding.tvPayTip.text = SpannedUtils.getAmountText(getAmountList())
|
||||
}
|
||||
2->{
|
||||
|
||||
2 -> {
|
||||
binding.layoutVip.visible()
|
||||
binding.layoutPaySuccess.visible()
|
||||
binding.layoutScanQrCode.gone()
|
||||
|
||||
binding.ivHeadPic.load(R.mipmap.ic_launcher)
|
||||
binding.tvUserName.text = "张三"
|
||||
binding.tvUserPhone.text = "132****5678"
|
||||
binding.tvUserBalance.text = getBalanceText("0.00")
|
||||
val memberInfo = activity.memberInfo
|
||||
totalPrice = activity.foodInfo?.vipPrice ?: 0.0
|
||||
balance = (memberInfo?.topUpBalance ?: 0.0) + (memberInfo?.rewardBalance ?: 0.0)
|
||||
realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
||||
expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
||||
|
||||
binding.tvPayInfo.text = "余额扣除 16.80 元,在线支付 20.00 元"
|
||||
memberInfo?.let { loadUserInfo(it) }
|
||||
val remainBalance = if (balance >= totalPrice) balance - totalPrice else 0.0
|
||||
binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
||||
listOf(
|
||||
TextBean(text = "¥", textSize = 24),
|
||||
TextBean(text = remainBalance.format2String(2), textSize = 36),
|
||||
)
|
||||
)
|
||||
|
||||
binding.tvPayInfo.text =
|
||||
"余额扣除 ${expensesBalance.format2String(2)} 元,在线支付 ${totalPrice.format2String(2)} 元"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPayTip(startAmount:String, endAmount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("余额扣除 ", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(startAmount, ForegroundColorSpan("#FF0A1428".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(" 元,还需支付 ", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(endAmount, ForegroundColorSpan("#FF0A1428".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(" 元", ForegroundColorSpan("#FF5E7585".toColorInt()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
private fun loadUserInfo(item: MemberInfo) {
|
||||
binding.ivHeadPic.load(R.mipmap.ic_launcher)
|
||||
binding.tvUserName.text = item.name
|
||||
|
||||
val phone = item.phone ?: ""
|
||||
binding.tvUserPhone.text =
|
||||
if (phone.length == 11)
|
||||
phone.replace(phone.substring(3, 7), "****")
|
||||
else
|
||||
phone
|
||||
}
|
||||
|
||||
private fun getBalanceText(amount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("¥", AbsoluteSizeSpan(20, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(amount, AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
private fun getAmountList(): List<TextBean> {
|
||||
val list: MutableList<TextBean> = mutableListOf()
|
||||
|
||||
private fun getAmountText(amount: String): SpannedString {
|
||||
return buildSpannedString {
|
||||
append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
list.add(TextBean(text = "余额扣除 ", textSize = 30, textColor = "#FF5E7585"))
|
||||
list.add(
|
||||
TextBean(
|
||||
text = "-${expensesBalance.format2String(2)}",
|
||||
textSize = 30,
|
||||
textColor = "#FF0A1428"
|
||||
)
|
||||
)
|
||||
|
||||
if (balance >= totalPrice) {
|
||||
//余额大于等于总价格,使用余额支付
|
||||
TextBean(text = " 元,扣除后可用余额 ", textSize = 30, textColor = "#FF5E7585")
|
||||
val remainingBalance = balance - totalPrice
|
||||
TextBean(
|
||||
text = remainingBalance.format2String(2),
|
||||
textSize = 30,
|
||||
textColor = "#FF0A1428"
|
||||
)
|
||||
} else {
|
||||
//余额小于总价格,使用余额+扫码支付
|
||||
//实际支付金额
|
||||
TextBean(text = " 元,还需支付 ", textSize = 30, textColor = "#FF5E7585")
|
||||
TextBean(text = realPayPrice.format2String(2), textSize = 30, textColor = "#FF0A1428")
|
||||
TextBean(text = " 元", textSize = 30, textColor = "#FF5E7585")
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
override fun onDisplayRemoved() {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.sw.dualscreen.presentation.pay
|
||||
|
||||
import android.view.TextureView
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import java.util.concurrent.ExecutorService
|
||||
|
||||
|
||||
|
||||
class TransmitScreen {
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user