联合支付功能调试
This commit is contained in:
@@ -59,7 +59,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar", "*.jar"))))
|
//implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar", "*.jar"))))
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
implementation(libs.material)
|
implementation(libs.material)
|
||||||
@@ -110,17 +110,19 @@ dependencies {
|
|||||||
implementation(libs.pytorch.android)
|
implementation(libs.pytorch.android)
|
||||||
implementation(libs.pytorch.android.torchvision)
|
implementation(libs.pytorch.android.torchvision)
|
||||||
|
|
||||||
implementation("io.github.scwang90:refresh-layout-kernel:3.0.0-alpha")
|
implementation(libs.baseRecyclerViewAdapterHelper4)
|
||||||
implementation("io.github.scwang90:refresh-header-classics:3.0.0-alpha")
|
|
||||||
|
implementation(libs.refresh.layout.kernel)
|
||||||
|
implementation(libs.refresh.header.classics)
|
||||||
|
|
||||||
val objectboxVersion = "5.0.1"
|
val objectboxVersion = "5.0.1"
|
||||||
debugImplementation("io.objectbox:objectbox-android-objectbrowser:$objectboxVersion")
|
debugImplementation(libs.objectbox.android.objectbrowser)
|
||||||
// releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion")
|
// releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion")
|
||||||
// implementation("io.objectbox:objectbox-fulltext:5.0.1")
|
// implementation("io.objectbox:objectbox-fulltext:5.0.1")
|
||||||
|
|
||||||
implementation(libs.androidx.recyclerview)
|
implementation(libs.androidx.recyclerview)
|
||||||
|
|
||||||
implementation("org.greenrobot:eventbus:3.2.0")
|
implementation(libs.eventbus)
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(plugin = "io.objectbox")
|
apply(plugin = "io.objectbox")
|
||||||
Binary file not shown.
@@ -32,10 +32,10 @@ import com.sw.dualscreen.databinding.ActivityMainBinding
|
|||||||
import com.sw.dualscreen.dialog.RemindDialog
|
import com.sw.dualscreen.dialog.RemindDialog
|
||||||
import com.sw.dualscreen.ext.dp
|
import com.sw.dualscreen.ext.dp
|
||||||
import com.sw.dualscreen.ext.gone
|
import com.sw.dualscreen.ext.gone
|
||||||
|
import com.sw.dualscreen.ext.invisible
|
||||||
import com.sw.dualscreen.ext.load
|
import com.sw.dualscreen.ext.load
|
||||||
import com.sw.dualscreen.ext.visible
|
import com.sw.dualscreen.ext.visible
|
||||||
import com.sw.dualscreen.model.response.ChargeModeEvent
|
import com.sw.dualscreen.model.response.ChargeModeEvent
|
||||||
import com.sw.dualscreen.model.response.ClickBackEvent
|
|
||||||
import com.sw.dualscreen.model.response.FoodInfo
|
import com.sw.dualscreen.model.response.FoodInfo
|
||||||
import com.sw.dualscreen.model.response.FoodOrder
|
import com.sw.dualscreen.model.response.FoodOrder
|
||||||
import com.sw.dualscreen.model.response.PaySuccessEvent
|
import com.sw.dualscreen.model.response.PaySuccessEvent
|
||||||
@@ -79,7 +79,6 @@ import java.time.ZoneId
|
|||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +90,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "MainActivity"
|
private const val TAG = "MainActivity"
|
||||||
const val TIME_OUT = 5 * 60 * 1000L
|
const val TIME_OUT = 5 * 60 * 1000L
|
||||||
|
|
||||||
|
const val WEIGHT_CHANGE_VALUE = 25
|
||||||
|
const val WEIGHT_RESET_RECOGNIZE = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
private val viewModel by viewModels<UserViewModel>()
|
private val viewModel by viewModels<UserViewModel>()
|
||||||
@@ -101,28 +103,36 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
private var presentation: MainScreenPresentation? = null
|
private var presentation: MainScreenPresentation? = null
|
||||||
private val executor = Executors.newSingleThreadExecutor()
|
private val executor = Executors.newSingleThreadExecutor()
|
||||||
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||||
private val searchFoodList = mutableListOf<FoodInfo>()
|
|
||||||
private val adapter by lazy {
|
private val adapter by lazy {
|
||||||
MainFoodListAdapter(searchFoodList).apply {
|
MainFoodListAdapter(mutableListOf()).apply {
|
||||||
setOnItemClickListener { adapter, view, position ->
|
setOnItemClickListener { adapter, view, position ->
|
||||||
if (searchFoodList[position].isChecked) {
|
if (items[position].isChecked) {
|
||||||
return@setOnItemClickListener
|
return@setOnItemClickListener
|
||||||
}
|
}
|
||||||
searchFoodList.forEachIndexed { index, info ->
|
items.forEachIndexed { index, info ->
|
||||||
searchFoodList[index].isChecked = index == position
|
items[index].isChecked = index == position
|
||||||
}
|
}
|
||||||
val item = searchFoodList[position]
|
val item = items[position]
|
||||||
log("itemClick ${item.foodName}, position = $position")
|
log("itemClick ${item.foodName}, position = $position")
|
||||||
item.photoUri = null
|
item.photoUri = null
|
||||||
checkedItem = item
|
checkedItem = item
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
updateCurrentFood(item)
|
updateCurrentFood(item)
|
||||||
//0-计费,1-不计费
|
if (settlementMode == 0) {
|
||||||
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
//联合支付,切换菜品重新请求接口
|
||||||
//不计费模式切换菜品,重新加载数据
|
presentation?.let {
|
||||||
if (mode == 1) {
|
it.pauseCamera()
|
||||||
presentation?.isAgainLoadData = false
|
it.step2FaceRecognizing(item, true)
|
||||||
presentation?.loadUnbilledMode()
|
}
|
||||||
|
// presentation?.step3ShowRecognizeResult(presentation!!.currentUserId?:"")
|
||||||
|
} else {
|
||||||
|
//0-计费,1-不计费
|
||||||
|
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||||
|
//不计费模式切换菜品,重新加载数据
|
||||||
|
if (mode == 1) {
|
||||||
|
presentation?.isAgainLoadData = false
|
||||||
|
presentation?.loadUnbilledMode()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +142,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
|
private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
|
||||||
private var canIdentify: Boolean = false
|
private var canIdentify: Boolean = false
|
||||||
private var bottomSheetDialog: CustomBottomSheetDialog? = null
|
private var bottomSheetDialog: CustomBottomSheetDialog? = null
|
||||||
private var lastWeight: Double = 0.0
|
private var lastWeight: Int = 0
|
||||||
private var lastPhotoUri: Uri? = null // 最后拍照的图片
|
private var lastPhotoUri: Uri? = null // 最后拍照的图片
|
||||||
private var debouncer = Debouncer(5000)
|
private var debouncer = Debouncer(5000)
|
||||||
private var isRecognitionFood = true
|
private var isRecognitionFood = true
|
||||||
@@ -200,8 +210,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
checkedItem = it
|
checkedItem = it
|
||||||
it.photoUri = null
|
it.photoUri = null
|
||||||
updateCurrentFood(it)
|
updateCurrentFood(it)
|
||||||
searchFoodList.forEachIndexed { index, info ->
|
adapter.items.forEachIndexed { index, info ->
|
||||||
searchFoodList[index].isChecked = false
|
adapter.items[index].isChecked = false
|
||||||
}
|
}
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
@@ -209,7 +219,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.recyclerview.let {
|
binding.recyclerview.let {
|
||||||
it.layoutManager = GridLayoutManager(this, 2)
|
it.layoutManager = GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false)
|
||||||
it.adapter = adapter
|
it.adapter = adapter
|
||||||
}
|
}
|
||||||
binding.tvFoodName.setOnClickListener {
|
binding.tvFoodName.setOnClickListener {
|
||||||
@@ -220,7 +230,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var recognizeWeight = 0.0
|
private var recognizeWeight = 0
|
||||||
fun updateCurrentFood(foodInfo: FoodInfo?) {
|
fun updateCurrentFood(foodInfo: FoodInfo?) {
|
||||||
if (foodInfo == null) {
|
if (foodInfo == null) {
|
||||||
binding.tvFoodName.text = "-"
|
binding.tvFoodName.text = "-"
|
||||||
@@ -245,52 +255,75 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
binding.ivImg.load(imgUrl)
|
binding.ivImg.load(imgUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerDataChange() {
|
private fun readWeight(weight: Int) {
|
||||||
super.registerDataChange()
|
log("registerDataChange weight = $weight")
|
||||||
SensorScaleUtils.addWeightListener { weight ->
|
//runOnUiThread { binding.tvShowWeight.text="${weight*1000}克" }
|
||||||
log("registerDataChange weight = $weight")
|
if (settlementMode == 0) {
|
||||||
//runOnUiThread { binding.tvShowWeight.text="${weight*1000}克" }
|
//联合支付-------------------------------------------
|
||||||
if (presentation?.jointPaymentQueryFinish == true) {
|
//0-即放即取,1-余量计量
|
||||||
//0-即放即取,1-余量计量
|
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||||
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
if (mealPickupMode == 1) {
|
||||||
if (mealPickupMode == 0 && weight <= 0.005) {
|
return
|
||||||
isAnalyzing = false
|
|
||||||
presentation?.step1FoodRecognizing()
|
|
||||||
} else {
|
|
||||||
return@addWeightListener
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//即放即取+联合支付人脸查询订单完成
|
||||||
//if (presentation?.currentFood == null) return@addWeightListener
|
if (presentation!!.jointPaymentQueryFinish) {
|
||||||
if (lastWeight - weight > 0.005) {
|
if (weight > WEIGHT_RESET_RECOGNIZE) {
|
||||||
//及放及取,从秤上拿走超过5克
|
//已识别完成人脸并查询到订单数据,增加重量不再重新识别
|
||||||
if (presentation?.mealPickupMode == 0) {
|
return
|
||||||
presentation?.updateWeight(weight)
|
|
||||||
lastWeight = weight
|
|
||||||
return@addWeightListener
|
|
||||||
}
|
}
|
||||||
|
//重量小于等于5克时改为识别中页面
|
||||||
|
isAnalyzing = false
|
||||||
|
presentation?.step1FoodRecognizing()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (isPageVisible.not() || isStartRecognize.not()) {
|
if (weight <= WEIGHT_RESET_RECOGNIZE) {
|
||||||
if (ActivityManager.currentActivity() is MainActivity) {
|
//秤上重量过下,显示识别中页面
|
||||||
isPageVisible = true
|
presentation?.step1FoodRecognizing()
|
||||||
isStartRecognize = true
|
return
|
||||||
}
|
|
||||||
return@addWeightListener
|
|
||||||
}
|
}
|
||||||
//0.05
|
|
||||||
// val isWeightChange = abs(weight - lastWeight) > 0.02
|
// val isWeightChange = abs(weight - lastWeight) > 0.02
|
||||||
val isWeightChange = weight - lastWeight > 0.02
|
val isWeightChange = weight - lastWeight > WEIGHT_CHANGE_VALUE
|
||||||
if (weight != lastWeight) {
|
if (weight != lastWeight) {
|
||||||
log("recognizeByWeight---00001,weight=$weight,lastWeight=$lastWeight,isWeightChange=$isWeightChange")
|
log("recognizeByWeight---00001,weight=$weight,lastWeight=$lastWeight,isWeightChange=$isWeightChange")
|
||||||
}
|
}
|
||||||
recognizeByWeight(weight, isWeightChange)
|
recognizeByWeight(weight, isWeightChange)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//独立支付-------------------------------------------
|
||||||
|
if (lastWeight - weight > 5) {
|
||||||
|
//及放及取,从秤上拿走超过5克
|
||||||
|
if (presentation?.mealPickupMode == 0) {
|
||||||
|
presentation?.updateWeight(weight)
|
||||||
|
lastWeight = weight
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isPageVisible.not() || isStartRecognize.not()) {
|
||||||
|
if (ActivityManager.currentActivity() is MainActivity) {
|
||||||
|
isPageVisible = true
|
||||||
|
isStartRecognize = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// val isWeightChange = abs(weight - lastWeight) > 0.02
|
||||||
|
val isWeightChange = weight - lastWeight > WEIGHT_CHANGE_VALUE
|
||||||
|
if (weight != lastWeight) {
|
||||||
|
log("recognizeByWeight---00001,weight=$weight,lastWeight=$lastWeight,isWeightChange=$isWeightChange")
|
||||||
|
}
|
||||||
|
recognizeByWeight(weight, isWeightChange)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerDataChange() {
|
||||||
|
super.registerDataChange()
|
||||||
|
SensorScaleUtils.addWeightListener { value ->
|
||||||
|
readWeight(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recognizeByWeight(weight: Double, isWeightChange: Boolean, block: () -> Unit = {}) {
|
private fun recognizeByWeight(weight: Int, isWeightChange: Boolean, block: () -> Unit = {}) {
|
||||||
presentation?.updateWeight(weight)
|
presentation?.updateWeight(weight)
|
||||||
|
|
||||||
if (weight <= 0.005) {
|
if (weight <= WEIGHT_RESET_RECOGNIZE) {
|
||||||
log("recognizeByWeight---00002,秤重未超过5克")
|
log("recognizeByWeight---00002,秤重未超过5克")
|
||||||
//检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
|
//检测到秤上没有东西,重新启动识别菜品 && presentation?.mealPickupMode == 1
|
||||||
isRecognitionFood = true
|
isRecognitionFood = true
|
||||||
@@ -374,9 +407,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
// e.printStackTrace()
|
// e.printStackTrace()
|
||||||
// list
|
// list
|
||||||
// }
|
// }
|
||||||
searchFoodList.clear()
|
|
||||||
searchFoodList.addAll(list)
|
|
||||||
adapter.notifyDataSetChanged()
|
adapter.submitList(list)
|
||||||
|
binding.recyclerview.visible()
|
||||||
|
|
||||||
checkedItem = list[0].also {
|
checkedItem = list[0].also {
|
||||||
it.photoUri = lastPhotoUri
|
it.photoUri = lastPhotoUri
|
||||||
@@ -559,10 +593,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
fun clearFoodList() {
|
fun clearRecognizeFood() {
|
||||||
//adapter.updateData(listOf())
|
log("clearRecognizeFood")
|
||||||
searchFoodList.clear()
|
binding.recyclerview.invisible()
|
||||||
adapter.notifyDataSetChanged()
|
adapter.submitList(null)
|
||||||
|
binding.tvToSearch.gone()
|
||||||
|
|
||||||
|
binding.previewView.visible()
|
||||||
|
binding.ivImg.gone()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDateTime() {
|
private fun updateDateTime() {
|
||||||
@@ -594,7 +632,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
log("onResume-00001,isRefreshPage=$isRefreshPage")
|
log("onResume-00001,isRefreshPage=$isRefreshPage")
|
||||||
if (presentation == null || !presentation!!.isShowing) {
|
if (presentation == null || !presentation!!.isShowing) {
|
||||||
log("onResume-00002,副屏未显示,加载副屏")
|
log("onResume-00002,副屏未显示,加载副屏")
|
||||||
lastWeight = 0.0
|
lastWeight = 0
|
||||||
setupSecondaryDisplay()
|
setupSecondaryDisplay()
|
||||||
presentation?.step1FoodRecognizing()
|
presentation?.step1FoodRecognizing()
|
||||||
} else {
|
} else {
|
||||||
@@ -603,7 +641,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
isRefreshPage = false
|
isRefreshPage = false
|
||||||
//已显示副屏,则进行更新
|
//已显示副屏,则进行更新
|
||||||
val weight = lastWeight
|
val weight = lastWeight
|
||||||
lastWeight = 0.0
|
lastWeight = 0
|
||||||
presentation?.hideRecImage()
|
presentation?.hideRecImage()
|
||||||
presentation?.step1FoodRecognizing()
|
presentation?.step1FoodRecognizing()
|
||||||
|
|
||||||
@@ -662,7 +700,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
eatWeight: Int,
|
eatWeight: Int,
|
||||||
eatNum: Int,
|
eatNum: Int,
|
||||||
userId: String?,
|
userId: String?,
|
||||||
isMember:Boolean,
|
isMember: Boolean,
|
||||||
notEnoughOneBlock: () -> Unit = {},
|
notEnoughOneBlock: () -> Unit = {},
|
||||||
successBlock: () -> Unit
|
successBlock: () -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -800,36 +838,36 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
val mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||||
//0-计费,1-不计费
|
//0-计费,1-不计费
|
||||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
|
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) ?: 0
|
||||||
var foodWeight = 0.0
|
var foodWeight = 0
|
||||||
var eatWeight = 0.0
|
var eatWeight = 0
|
||||||
if (chargeMode == 0) {
|
if (chargeMode == 0) {
|
||||||
//计费
|
//计费
|
||||||
if (mealPickupMode == 0) {
|
if (mealPickupMode == 0) {
|
||||||
//即放即取
|
//即放即取
|
||||||
eatWeight = lastWeight * 1000
|
eatWeight = lastWeight
|
||||||
foodWeight = lastWeight * 1000
|
foodWeight = lastWeight
|
||||||
} else {
|
} else {
|
||||||
//余量计量
|
//余量计量
|
||||||
eatWeight = (recognizeWeight - lastWeight) * 1000
|
eatWeight = recognizeWeight - lastWeight
|
||||||
foodWeight = recognizeWeight * 1000
|
foodWeight = recognizeWeight
|
||||||
log("eatWeight=$eatWeight, recognizeWeight=$recognizeWeight, lastWeight=$lastWeight")
|
log("eatWeight=$eatWeight, recognizeWeight=$recognizeWeight, lastWeight=$lastWeight")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//不计费
|
//不计费
|
||||||
foodWeight = recognizeWeight * 1000
|
foodWeight = recognizeWeight
|
||||||
eatWeight = if (mealPickupMode == 0) {
|
eatWeight = if (mealPickupMode == 0) {
|
||||||
//即放即取
|
//即放即取
|
||||||
recognizeWeight * 1000
|
recognizeWeight
|
||||||
} else {
|
} else {
|
||||||
//余量计量
|
//余量计量
|
||||||
(recognizeWeight - lastWeight) * 1000
|
recognizeWeight - lastWeight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val eatNum = getEatNum(eatWeight, checkedItem!!.specWeight)
|
val eatNum = getEatNum(eatWeight.toDouble(), checkedItem!!.specWeight)
|
||||||
createOrder(
|
createOrder(
|
||||||
foodInfo = checkedItem!!,
|
foodInfo = checkedItem!!,
|
||||||
foodWeight = foodWeight.roundToInt(),
|
foodWeight = foodWeight,
|
||||||
eatWeight = eatWeight.roundToInt(),
|
eatWeight = eatWeight,
|
||||||
eatNum = eatNum,
|
eatNum = eatNum,
|
||||||
userId = null,
|
userId = null,
|
||||||
isMember = false
|
isMember = false
|
||||||
@@ -956,7 +994,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
// private val dealyMillis = 10 * 60 * 1000L
|
// private val dealyMillis = 10 * 60 * 1000L
|
||||||
private val initialDelay = 10 * 1000L
|
private val initialDelay = 10 * 1000L
|
||||||
private val dealyMillis = 5 * 1000L
|
private val dealyMillis = 5 * 1000L
|
||||||
// private var taskPageNo = 1
|
|
||||||
|
// private var taskPageNo = 1
|
||||||
fun startFaceTask() {
|
fun startFaceTask() {
|
||||||
faceTaskJob =
|
faceTaskJob =
|
||||||
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) {
|
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) {
|
||||||
@@ -1097,13 +1136,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 隐藏搜索按钮
|
|
||||||
*/
|
|
||||||
fun hideSearchView() {
|
|
||||||
binding.tvToSearch.gone()
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Subscribe(threadMode = ThreadMode.MAIN)
|
// @Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
// public fun onResetBox(event: ResetBoxEvent) {
|
// public fun onResetBox(event: ResetBoxEvent) {
|
||||||
// ObjectBox.boxStore.close()
|
// ObjectBox.boxStore.close()
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ class BusinessFragment: BaseFragment<FragmentBusinessBinding>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SensorScaleUtils.addWeightListener { value ->
|
SensorScaleUtils.addWeightListener { value ->
|
||||||
val realWeight = (value * 1000).roundToInt()
|
//val realWeight = (value * 1000).roundToInt()
|
||||||
binding.tvFoodWeight.text = "$realWeight"
|
binding.tvFoodWeight.text = "$value"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,19 +10,21 @@ import androidx.core.view.updateLayoutParams
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.chad.library.adapter4.BaseQuickAdapter
|
import com.chad.library.adapter4.BaseQuickAdapter
|
||||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||||
import com.sw.dualscreen.databinding.LayoutFoodListHeaderBinding
|
import com.sw.dualscreen.databinding.ListItemFoodOrderBinding
|
||||||
import com.sw.dualscreen.ext.dp
|
import com.sw.dualscreen.ext.dp
|
||||||
import com.sw.dualscreen.ext.format2String
|
import com.sw.dualscreen.ext.format2String
|
||||||
|
import com.sw.dualscreen.ext.gone
|
||||||
|
import com.sw.dualscreen.ext.visible
|
||||||
import com.sw.dualscreen.model.response.FoodItem
|
import com.sw.dualscreen.model.response.FoodItem
|
||||||
|
|
||||||
class FoodOrderAdapter(var list: MutableList<FoodItem>) :
|
class FoodOrderAdapter(var list: MutableList<FoodItem>) :
|
||||||
BaseQuickAdapter<FoodItem, FoodOrderAdapter.VH>(list) {
|
BaseQuickAdapter<FoodItem, FoodOrderAdapter.VH>(list) {
|
||||||
|
|
||||||
inner class VH(var binding: LayoutFoodListHeaderBinding) : QuickViewHolder(binding.root)
|
inner class VH(var binding: ListItemFoodOrderBinding) : QuickViewHolder(binding.root)
|
||||||
|
|
||||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||||
val inflater = LayoutInflater.from(context)
|
val inflater = LayoutInflater.from(context)
|
||||||
val binding = LayoutFoodListHeaderBinding.inflate(inflater, parent, false)
|
val binding = ListItemFoodOrderBinding.inflate(inflater, parent, false)
|
||||||
return VH(binding)
|
return VH(binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,9 +33,20 @@ class FoodOrderAdapter(var list: MutableList<FoodItem>) :
|
|||||||
val binding = holder.binding
|
val binding = holder.binding
|
||||||
item?.let {
|
item?.let {
|
||||||
binding.tvFoodName.text = it.foodName
|
binding.tvFoodName.text = it.foodName
|
||||||
binding.tvPriceNorm.text = it.foodPrice.format2String(2)
|
val foodPrice = it.foodPrice.format2String(2)
|
||||||
|
if (it.orderFrom == 2) {
|
||||||
|
binding.tvPriceNorm.text = "${it.specName}-${it.specWeight}克"
|
||||||
|
} else {
|
||||||
|
binding.tvPriceNorm.text = "${foodPrice}/${it.num}克"
|
||||||
|
}
|
||||||
|
//if (it.specName.isNullOrBlank().not()) {
|
||||||
|
// binding.tvPriceFlag.text = "[${it.specName}]"
|
||||||
|
//}
|
||||||
binding.tvWeight.text = "${it.num}克"
|
binding.tvWeight.text = "${it.num}克"
|
||||||
binding.tvAmount.text = it.price.format2String(2)
|
binding.tvAmount.text = it.price.format2String(2)
|
||||||
|
binding.tvLabel.run {
|
||||||
|
if (it.orderFrom == 2) visible() else gone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setTextColor(binding.tvFoodName, binding.tvPriceNorm, binding.tvWeight, binding.tvAmount)
|
setTextColor(binding.tvFoodName, binding.tvPriceNorm, binding.tvWeight, binding.tvAmount)
|
||||||
binding.root.updateLayoutParams<RecyclerView.LayoutParams> {
|
binding.root.updateLayoutParams<RecyclerView.LayoutParams> {
|
||||||
|
|||||||
@@ -177,7 +177,10 @@ data class FoodItem(
|
|||||||
val discount: Double = 0.0,
|
val discount: Double = 0.0,
|
||||||
val income: Double = 0.0,
|
val income: Double = 0.0,
|
||||||
val foodDifferenceId: Long = 0,
|
val foodDifferenceId: Long = 0,
|
||||||
val createTime: String? = null
|
val createTime: String? = null,
|
||||||
|
val specName: String? = null,
|
||||||
|
val specWeight: Int = 0,
|
||||||
|
val orderFrom: Int = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
data class FoodOrderModel(
|
data class FoodOrderModel(
|
||||||
|
|||||||
@@ -5,24 +5,16 @@ import android.annotation.SuppressLint
|
|||||||
import android.app.Presentation
|
import android.app.Presentation
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Outline
|
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
import android.hardware.Camera
|
import android.hardware.Camera
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
|
||||||
import android.util.DisplayMetrics
|
|
||||||
import android.view.Display
|
import android.view.Display
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewOutlineProvider
|
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isInvisible
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.postDelayed
|
|
||||||
import androidx.core.view.updateLayoutParams
|
import androidx.core.view.updateLayoutParams
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -30,7 +22,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import com.arcsoft.face.ErrorInfo
|
import com.arcsoft.face.ErrorInfo
|
||||||
import com.sw.dualscreen.BuildConfig
|
import com.sw.dualscreen.BuildConfig
|
||||||
import com.sw.dualscreen.GlobalKey
|
import com.sw.dualscreen.GlobalKey
|
||||||
import com.sw.dualscreen.MyApp
|
|
||||||
import com.sw.dualscreen.R
|
import com.sw.dualscreen.R
|
||||||
import com.sw.dualscreen.activity.MainActivity
|
import com.sw.dualscreen.activity.MainActivity
|
||||||
import com.sw.dualscreen.adapter.FoodOrderAdapter
|
import com.sw.dualscreen.adapter.FoodOrderAdapter
|
||||||
@@ -40,7 +31,6 @@ import com.sw.dualscreen.ext.format2String
|
|||||||
import com.sw.dualscreen.ext.gone
|
import com.sw.dualscreen.ext.gone
|
||||||
import com.sw.dualscreen.ext.load
|
import com.sw.dualscreen.ext.load
|
||||||
import com.sw.dualscreen.ext.maskName
|
import com.sw.dualscreen.ext.maskName
|
||||||
import com.sw.dualscreen.ext.roundedDecimalPlace
|
|
||||||
import com.sw.dualscreen.ext.screenSize
|
import com.sw.dualscreen.ext.screenSize
|
||||||
import com.sw.dualscreen.ext.visible
|
import com.sw.dualscreen.ext.visible
|
||||||
import com.sw.dualscreen.model.response.DinnerType
|
import com.sw.dualscreen.model.response.DinnerType
|
||||||
@@ -66,7 +56,6 @@ 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
|
||||||
@@ -105,14 +94,14 @@ class MainScreenPresentation(
|
|||||||
private var irFaceRectTransformer: FaceRectTransformer? = null
|
private var irFaceRectTransformer: FaceRectTransformer? = null
|
||||||
|
|
||||||
private var detectWeight = 0.0 //识别菜品时的重量
|
private var detectWeight = 0.0 //识别菜品时的重量
|
||||||
var lastWeight = 0.0 // 上一次的计算热量结果
|
var lastWeight = 0 // 上一次的计算热量结果
|
||||||
|
|
||||||
// private var userNutritionData: UserNutritionData? = null
|
// private var userNutritionData: UserNutritionData? = null
|
||||||
private var userNutrition: UserNutrition? = null
|
private var userNutrition: UserNutrition? = null
|
||||||
private var dinnerTypeInfo: DinnerType? = null
|
private var dinnerTypeInfo: DinnerType? = null
|
||||||
private val debouncer = Debouncer(500)
|
private val debouncer = Debouncer(500)
|
||||||
private var recognitionTime: Long = 0L // 人脸识别时的时间
|
private var recognitionTime: Long = 0L // 人脸识别时的时间
|
||||||
var recognitionWeight: Double = 0.0 // 人脸识别时的重量
|
var recognitionWeight: Int = 0 // 人脸识别时的重量
|
||||||
|
|
||||||
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
|
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
|
||||||
var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐
|
var mealPickupMode: Int = 0 // 取餐模式 0 即放即取 1 余量取餐
|
||||||
@@ -144,8 +133,8 @@ class MainScreenPresentation(
|
|||||||
|
|
||||||
private var isFirstGetWeight = true
|
private var isFirstGetWeight = true
|
||||||
|
|
||||||
fun updateWeight(weight: Double) {
|
fun updateWeight(weight: Int) {
|
||||||
lastWeight = weight * 1000 // 将千克转成克
|
lastWeight = weight
|
||||||
Timber.tag(TAG)
|
Timber.tag(TAG)
|
||||||
.d("updateWeight lastWeight = $weight, currentStep = $currentStep, isGoStep1 = $isGoStep1")
|
.d("updateWeight lastWeight = $weight, currentStep = $currentStep, isGoStep1 = $isGoStep1")
|
||||||
//0-即放即取,1-余量计量
|
//0-即放即取,1-余量计量
|
||||||
@@ -164,14 +153,14 @@ class MainScreenPresentation(
|
|||||||
// }
|
// }
|
||||||
// isFirstGetWeight = true
|
// isFirstGetWeight = true
|
||||||
// }
|
// }
|
||||||
if (currentStep == 2 && lastWeight <= 5 && isGoStep1) {
|
if (currentStep == 2 && lastWeight <= MainActivity.WEIGHT_RESET_RECOGNIZE && isGoStep1) {
|
||||||
//人脸识别过程中,秤上物品拿走
|
//人脸识别过程中,秤上物品拿走
|
||||||
isGoStep1 = false
|
isGoStep1 = false
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
Timber.tag(TAG).e("切回step1")
|
Timber.tag(TAG).e("切回step1")
|
||||||
step1FoodRecognizing()
|
step1FoodRecognizing()
|
||||||
}
|
}
|
||||||
} else if (lastWeight <= 5) {
|
} else if (lastWeight <= MainActivity.WEIGHT_RESET_RECOGNIZE) {
|
||||||
isGoStep1 = false
|
isGoStep1 = false
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
Timber.tag(TAG).e("切回step1")
|
Timber.tag(TAG).e("切回step1")
|
||||||
@@ -287,6 +276,14 @@ class MainScreenPresentation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setTopInfoVisible() {
|
||||||
|
binding.llTopInfo.visible()
|
||||||
|
binding.flFoodDetail.gone()
|
||||||
|
binding.llTopInfo.updateLayoutParams {
|
||||||
|
height = activity.screenSize[1] / 2 + 120.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示识别出的菜品信息
|
* 显示识别出的菜品信息
|
||||||
*/
|
*/
|
||||||
@@ -297,8 +294,7 @@ class MainScreenPresentation(
|
|||||||
currentStep = 3
|
currentStep = 3
|
||||||
stepChangeCallback(currentStep)
|
stepChangeCallback(currentStep)
|
||||||
|
|
||||||
binding.llTopInfo.visible()
|
setTopInfoVisible()
|
||||||
binding.flFoodDetail.gone()
|
|
||||||
//根据接口数据更新热量数据--------------------------
|
//根据接口数据更新热量数据--------------------------
|
||||||
userViewModel.getUserNutritionData(userId = userId) { nutrition ->
|
userViewModel.getUserNutritionData(userId = userId) { nutrition ->
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
@@ -491,6 +487,9 @@ class MainScreenPresentation(
|
|||||||
* 餐品识别中
|
* 餐品识别中
|
||||||
*/
|
*/
|
||||||
fun step1FoodRecognizing() {
|
fun step1FoodRecognizing() {
|
||||||
|
if (currentStep == 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}")
|
Timber.tag(TAG).d("main,step1,耗时:${System.currentTimeMillis() - startTime}")
|
||||||
startTime = System.currentTimeMillis()
|
startTime = System.currentTimeMillis()
|
||||||
jointPaymentQueryFinish = false
|
jointPaymentQueryFinish = false
|
||||||
@@ -505,7 +504,6 @@ class MainScreenPresentation(
|
|||||||
// }
|
// }
|
||||||
// return
|
// return
|
||||||
//}
|
//}
|
||||||
currentStep = 1
|
|
||||||
LightManager.closeGreenLight()
|
LightManager.closeGreenLight()
|
||||||
LightManager.closeRedLight()
|
LightManager.closeRedLight()
|
||||||
|
|
||||||
@@ -513,12 +511,9 @@ class MainScreenPresentation(
|
|||||||
currentFood = null
|
currentFood = null
|
||||||
// userNutritionData = null
|
// userNutritionData = null
|
||||||
userNutrition = null
|
userNutrition = null
|
||||||
recognitionWeight = 0.0
|
recognitionWeight = 0
|
||||||
|
|
||||||
stepChangeCallback(currentStep)
|
setTopInfoVisible()
|
||||||
|
|
||||||
binding.llTopInfo.visible()
|
|
||||||
binding.flFoodDetail.gone()
|
|
||||||
|
|
||||||
binding.calorieInclude.root.gone()
|
binding.calorieInclude.root.gone()
|
||||||
binding.nutritionInclude.root.gone()
|
binding.nutritionInclude.root.gone()
|
||||||
@@ -537,8 +532,10 @@ class MainScreenPresentation(
|
|||||||
binding.flRecognizeIr.gone()
|
binding.flRecognizeIr.gone()
|
||||||
|
|
||||||
pauseCamera()
|
pauseCamera()
|
||||||
activity.clearFoodList()
|
activity.clearRecognizeFood()
|
||||||
activity.hideSearchView()
|
|
||||||
|
currentStep = 1
|
||||||
|
stepChangeCallback(currentStep)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fun foodRecSuccess(foodInfo: FoodInfo) {
|
// fun foodRecSuccess(foodInfo: FoodInfo) {
|
||||||
@@ -560,9 +557,14 @@ class MainScreenPresentation(
|
|||||||
/**
|
/**
|
||||||
* 用户人脸识别中
|
* 用户人脸识别中
|
||||||
*/
|
*/
|
||||||
fun step2FaceRecognizing(foodInfo: FoodInfo) {
|
fun step2FaceRecognizing(foodInfo: FoodInfo, hideFoodDetail: Boolean = false) {
|
||||||
isGoStep1 = true
|
isGoStep1 = true
|
||||||
Timber.tag(TAG).d("main,step2,耗时:${System.currentTimeMillis() - startTime}")
|
Timber.tag(TAG).d("main,step2,耗时:${System.currentTimeMillis() - startTime}")
|
||||||
|
|
||||||
|
if (hideFoodDetail) {
|
||||||
|
setTopInfoVisible()
|
||||||
|
}
|
||||||
|
|
||||||
startTime = System.currentTimeMillis()
|
startTime = System.currentTimeMillis()
|
||||||
currentStep = 2
|
currentStep = 2
|
||||||
LightManager.closeRedLight()
|
LightManager.closeRedLight()
|
||||||
@@ -586,7 +588,7 @@ class MainScreenPresentation(
|
|||||||
dinnerTypeInfo = null
|
dinnerTypeInfo = null
|
||||||
// userNutritionData = null
|
// userNutritionData = null
|
||||||
userNutrition = null
|
userNutrition = null
|
||||||
recognitionWeight = 0.0
|
recognitionWeight = 0
|
||||||
|
|
||||||
stepChangeCallback(currentStep)
|
stepChangeCallback(currentStep)
|
||||||
currentFood = foodInfo
|
currentFood = foodInfo
|
||||||
@@ -668,12 +670,12 @@ class MainScreenPresentation(
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateNutrition(weight1: Double) {
|
private fun calculateNutrition(value: Int) {
|
||||||
if (currentFood == null || userNutrition == null) {
|
if (currentFood == null || userNutrition == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var weight = weight1
|
var weight = value
|
||||||
if (weight < 0) weight = 0.0
|
if (weight < 0) weight = 0
|
||||||
debouncer.debounce {
|
debouncer.debounce {
|
||||||
Timber.tag(TAG)
|
Timber.tag(TAG)
|
||||||
.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
.d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
|
||||||
@@ -684,7 +686,7 @@ class MainScreenPresentation(
|
|||||||
currentFood!!,
|
currentFood!!,
|
||||||
// userNutritionData!!,
|
// userNutritionData!!,
|
||||||
userNutrition!!,
|
userNutrition!!,
|
||||||
weight,
|
weight.toDouble(),
|
||||||
dinnerType = dinnerType ?: ""
|
dinnerType = dinnerType ?: ""
|
||||||
)
|
)
|
||||||
// Timber.tag(TAG).d("calculateNutrition calcResultInfo = $calcResultInfo")
|
// Timber.tag(TAG).d("calculateNutrition calcResultInfo = $calcResultInfo")
|
||||||
@@ -830,8 +832,23 @@ class MainScreenPresentation(
|
|||||||
isRecognition = false
|
isRecognition = false
|
||||||
|
|
||||||
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
||||||
|
//triggerReidentify()
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 重置人脸跟踪状态,让已在画面中的人脸重新触发识别
|
||||||
|
* 适用场景:切换按钮后需要重新识别当前画面中的人脸
|
||||||
|
*/
|
||||||
|
fun triggerReidentify() {
|
||||||
|
// 清除UI上的人脸框
|
||||||
|
binding.dualCameraFaceRectView.clearFaceInfo()
|
||||||
|
// 清除本地跟踪数据
|
||||||
|
clearLeftFaceData()
|
||||||
|
// 重置上一次的 trackId,避免 drawPreviewInfo 中的去重逻辑拦截
|
||||||
|
lastFaceTrackId = -1
|
||||||
|
// 插入空帧,让引擎重置内部跟踪状态
|
||||||
|
// isRecognition 保持 true,相机继续送帧,下一帧真实人脸会产生新 trackId
|
||||||
|
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)
|
||||||
@@ -1187,8 +1204,7 @@ class MainScreenPresentation(
|
|||||||
}
|
}
|
||||||
createOrder(notEnoughOneBlock = {
|
createOrder(notEnoughOneBlock = {
|
||||||
if (activity.settlementMode == 0) {
|
if (activity.settlementMode == 0) {
|
||||||
binding.flFoodDetail.gone()
|
setTopInfoVisible()
|
||||||
binding.llTopInfo.visible()
|
|
||||||
}
|
}
|
||||||
// if (mealPickupMode == 0) {
|
// if (mealPickupMode == 0) {
|
||||||
currentStep = 2
|
currentStep = 2
|
||||||
@@ -1249,11 +1265,11 @@ class MainScreenPresentation(
|
|||||||
//userViewModel.postUserNutritionData(listOf(userNutritionParam))
|
//userViewModel.postUserNutritionData(listOf(userNutritionParam))
|
||||||
activity.createOrder(
|
activity.createOrder(
|
||||||
foodInfo = currentFood!!,
|
foodInfo = currentFood!!,
|
||||||
foodWeight = lastWeight.roundToInt(),
|
foodWeight = lastWeight,
|
||||||
eatWeight = eatWeight.roundToInt(),
|
eatWeight = eatWeight,
|
||||||
eatNum = activity.getEatNum(eatWeight, currentFood!!.specWeight),
|
eatNum = activity.getEatNum(eatWeight.toDouble(), currentFood!!.specWeight),
|
||||||
userId = currentUserId,
|
userId = currentUserId,
|
||||||
isMember = isMember ,
|
isMember = isMember,
|
||||||
notEnoughOneBlock = notEnoughOneBlock,
|
notEnoughOneBlock = notEnoughOneBlock,
|
||||||
successBlock = {
|
successBlock = {
|
||||||
activity.runOnUiThread {
|
activity.runOnUiThread {
|
||||||
@@ -1316,11 +1332,12 @@ class MainScreenPresentation(
|
|||||||
binding.flFoodDetail.visible()
|
binding.flFoodDetail.visible()
|
||||||
binding.detailInclude.let {
|
binding.detailInclude.let {
|
||||||
it.root.updateLayoutParams {
|
it.root.updateLayoutParams {
|
||||||
height = activity.screenSize[1]/2
|
height = activity.screenSize[1] / 2 + 120.dp
|
||||||
}
|
}
|
||||||
it.tvFoodList.run {
|
it.tvFoodList.run {
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
|
layoutManager =
|
||||||
|
LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
|
||||||
adapter = foodOrderAdapter
|
adapter = foodOrderAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1332,10 +1349,36 @@ class MainScreenPresentation(
|
|||||||
}
|
}
|
||||||
foodOrderAdapter.notifyDataSetChanged()
|
foodOrderAdapter.notifyDataSetChanged()
|
||||||
binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克"
|
binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克"
|
||||||
binding.detailInclude.tvTotalCalorie.text = "总热量:${model.calorie.roundToInt()}千卡"
|
binding.detailInclude.tvTotalCalorie.text =
|
||||||
|
"总热量:${model.calorie.roundToInt()}千卡"
|
||||||
jointPaymentQueryFinish = true
|
jointPaymentQueryFinish = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造符合分辨率的 NV21 格式全黑帧
|
||||||
|
* @param width 图像宽度(如 1920)
|
||||||
|
* @param height 图像高度(如 1080)
|
||||||
|
* @return 合法的全黑帧字节数组
|
||||||
|
*/
|
||||||
|
private fun createBlackNV21Frame(width: Int, height: Int): ByteArray {
|
||||||
|
val frameSize = width * height
|
||||||
|
val nv21Data = ByteArray(frameSize * 3 / 2) // NV21 格式长度 = 宽×高×1.5
|
||||||
|
|
||||||
|
// Y 分量(亮度)设为 0(全黑),UV 分量设为 128(默认值)
|
||||||
|
// 1. 填充 Y 分量(前 frameSize 个字节)
|
||||||
|
// Arrays.fill(nv21Data, 0, frameSize, 0.toByte())
|
||||||
|
nv21Data.fill(0, 0, frameSize)
|
||||||
|
// 2. 填充 UV 分量(后 frameSize/2 个字节)
|
||||||
|
// Arrays.fill(nv21Data, frameSize, nv21Data.size, 128.toByte())
|
||||||
|
nv21Data.fill(128.toByte(), frameSize, nv21Data.size)
|
||||||
|
|
||||||
|
return nv21Data
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用示例:构造 1920×1080 的全黑帧(长度 1382400)
|
||||||
|
// private val emptyFrame = createBlackNV21Frame(1920, 1080)
|
||||||
|
private val emptyFrame = createBlackNV21Frame(1280, 720)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import timber.log.Timber
|
|||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
typealias Callback = (Double) -> Unit
|
typealias Callback = (Double) -> Unit
|
||||||
typealias WeightCallback = (Double) -> Unit
|
typealias WeightCallback = (Int) -> Unit
|
||||||
|
|
||||||
private const val TAG = "SensorScaleUtils"
|
private const val TAG = "SensorScaleUtils"
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ object SensorScaleUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
weightCallbackList.forEach {
|
weightCallbackList.forEach {
|
||||||
it.invoke(value)
|
it.invoke((value * 1000).roundToInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@android:color/darker_gray"/>
|
||||||
|
<stroke android:color="#cdcdcd" android:width="1dp"/>
|
||||||
|
<corners android:radius="5dp"/>
|
||||||
|
</shape>
|
||||||
@@ -285,7 +285,7 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/meatTv"
|
android:id="@+id/meatTv"
|
||||||
style="@style/takeFoodNameTv"
|
style="@style/takeFoodNameTv"
|
||||||
android:text="蛋肉"
|
android:text="肉蛋豆"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
android:id="@+id/tvFoodName"
|
android:id="@+id/tvFoodName"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="2.5"
|
android:layout_weight="2.1"
|
||||||
android:text="菜品名称"
|
android:text="菜品名称"
|
||||||
android:textColor="#FF889AC2"
|
android:textColor="#FF889AC2"
|
||||||
android:textSize="26sp"
|
android:textSize="26sp"
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
android:id="@+id/tvPriceNorm"
|
android:id="@+id/tvPriceNorm"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.6"
|
||||||
android:text="规格"
|
android:text="规格"
|
||||||
android:textColor="#FF889AC2"
|
android:textColor="#FF889AC2"
|
||||||
android:textSize="26sp"
|
android:textSize="26sp"
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<!-- 菜品名称列,权重2.5 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="2.1"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvFoodName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="菜品名称"
|
||||||
|
android:textColor="#FF889AC2"
|
||||||
|
android:textSize="25sp"
|
||||||
|
android:paddingHorizontal="5dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center_vertical|start" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvLabel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="档口"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:background="@drawable/bg_order_flag"
|
||||||
|
android:paddingHorizontal="5dp"
|
||||||
|
android:paddingVertical="1dp"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 规格列,权重1.0 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1.6"
|
||||||
|
android:gravity="center">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPriceNorm"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="规格"
|
||||||
|
android:textColor="#FF889AC2"
|
||||||
|
android:textSize="25sp"
|
||||||
|
android:paddingHorizontal="5dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPriceFlag"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="[大份]"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:paddingHorizontal="5dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- 重量列,权重1.0 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvWeight"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
tools:text="重量(克)"
|
||||||
|
android:textColor="#FF889AC2"
|
||||||
|
android:textSize="25sp"
|
||||||
|
android:paddingHorizontal="5dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center" />
|
||||||
|
|
||||||
|
<!-- 小计列,权重1.0 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvAmount"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1.0"
|
||||||
|
tools:text="小计(元)"
|
||||||
|
android:textColor="#FF889AC2"
|
||||||
|
android:textSize="25sp"
|
||||||
|
android:paddingHorizontal="5dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:gravity="center" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
agp = "8.10.1"
|
agp = "8.10.1"
|
||||||
core = "3.4.1"
|
core = "3.4.1"
|
||||||
androidCore = "3.3.0"
|
androidCore = "3.3.0"
|
||||||
|
eventbus = "3.2.0"
|
||||||
glide = "4.16.0"
|
glide = "4.16.0"
|
||||||
kotlin = "2.0.21"
|
kotlin = "2.0.21"
|
||||||
coreKtx = "1.10.1"
|
coreKtx = "1.10.1"
|
||||||
@@ -14,6 +15,9 @@ activity = "1.8.0"
|
|||||||
constraintlayout = "2.1.4"
|
constraintlayout = "2.1.4"
|
||||||
accompanistPermissions = "0.37.3"
|
accompanistPermissions = "0.37.3"
|
||||||
cameraCore = "1.4.1"
|
cameraCore = "1.4.1"
|
||||||
|
objectboxVersion = "5.0.1"
|
||||||
|
refreshLayoutKernel = "3.0.0-alpha"
|
||||||
|
refreshHeaderClassics = "3.0.0-alpha"
|
||||||
retrofit = "3.0.0"
|
retrofit = "3.0.0"
|
||||||
okhttp = "4.12.0"
|
okhttp = "4.12.0"
|
||||||
timber = "5.0.1"
|
timber = "5.0.1"
|
||||||
@@ -30,11 +34,13 @@ pytorch = "1.13.0"
|
|||||||
|
|
||||||
recyclerview = "1.3.2"
|
recyclerview = "1.3.2"
|
||||||
|
|
||||||
#baseQuickAdapter = "4.1.2"
|
baseQuickAdapter = "3.0.4"
|
||||||
|
baseQuickAdapter4 = "4.1.2"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
android-core = { module = "com.google.zxing:android-core", version.ref = "androidCore" }
|
||||||
core = { module = "com.google.zxing:core", version.ref = "core" }
|
core = { module = "com.google.zxing:core", version.ref = "core" }
|
||||||
|
eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbus" }
|
||||||
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||||
@@ -56,7 +62,10 @@ hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", ve
|
|||||||
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
|
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hiltAndroid" }
|
||||||
|
|
||||||
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" }
|
||||||
|
objectbox-android-objectbrowser = { module = "io.objectbox:objectbox-android-objectbrowser", version.ref = "objectboxVersion" }
|
||||||
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||||
|
refresh-header-classics = { module = "io.github.scwang90:refresh-header-classics", version.ref = "refreshHeaderClassics" }
|
||||||
|
refresh-layout-kernel = { module = "io.github.scwang90:refresh-layout-kernel", version.ref = "refreshLayoutKernel" }
|
||||||
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
||||||
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
|
||||||
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
|
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
|
||||||
@@ -68,10 +77,12 @@ androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref
|
|||||||
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
||||||
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||||
|
|
||||||
|
#noinspection Aligned16KB
|
||||||
pytorch-android = { group = "org.pytorch", name = "pytorch_android", version.ref = "pytorch" }
|
pytorch-android = { group = "org.pytorch", name = "pytorch_android", version.ref = "pytorch" }
|
||||||
pytorch-android-torchvision = { group = "org.pytorch", name = "pytorch_android_torchvision", version.ref = "pytorch" }
|
pytorch-android-torchvision = { group = "org.pytorch", name = "pytorch_android_torchvision", version.ref = "pytorch" }
|
||||||
|
|
||||||
#base-quick-adapter-ktx = { module = "io.github.cymchad:BaseRecyclerViewAdapterHelper4", version.ref = "baseQuickAdapter" }
|
#baseRecyclerViewAdapterHelper = { module = "com.github.CymChad:BaseRecyclerViewAdapterHelper", version.ref = "baseQuickAdapter" }
|
||||||
|
baseRecyclerViewAdapterHelper4 = { module = "io.github.cymchad:BaseRecyclerViewAdapterHelper4", version.ref = "baseQuickAdapter4" }
|
||||||
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
|
androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user