接口联调

This commit is contained in:
2025-11-28 18:46:41 +08:00
parent 9bcd7c9983
commit 29188c5944
39 changed files with 1882 additions and 1662 deletions
+2 -1
View File
@@ -22,8 +22,9 @@ class MyApp : App() {
Timber.plant(Timber.DebugTree()) Timber.plant(Timber.DebugTree())
var deviceId = AppUtil.getUDID(this) var deviceId = AppUtil.getUDID(this)
Timber.d("UDID = ${AppUtil.getUDID(this)}") Timber.d("UDID = ${AppUtil.getUDID(this)}")
deviceId = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e" // deviceId = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e"
GlobalData.deviceId = deviceId GlobalData.deviceId = deviceId
GlobalData.appBaseUrl = "http://192.168.1.201:14801"
ObjectBox.init(this) ObjectBox.init(this)
// 初始化崩溃处理器 // 初始化崩溃处理器
CrashHandler.init(this) CrashHandler.init(this)
@@ -11,7 +11,7 @@
//import com.sw.dualscreen.dialog.WarnDialog //import com.sw.dualscreen.dialog.WarnDialog
//import com.sw.dualscreen.ext.addOnActionSearchListener //import com.sw.dualscreen.ext.addOnActionSearchListener
//import com.sw.dualscreen.ext.hideKeyboard //import com.sw.dualscreen.ext.hideKeyboard
//import com.sw.dualscreen.objbox.CollectedFoodBean //import com.sw.dualscreen.objbox.CollectedFoodInfo
//import com.sw.dualscreen.objbox.Food //import com.sw.dualscreen.objbox.Food
//import com.sw.dualscreen.objbox.ObjectBox //import com.sw.dualscreen.objbox.ObjectBox
//import com.sw.dualscreen.viewmodel.BaseViewModel //import com.sw.dualscreen.viewmodel.BaseViewModel
@@ -31,7 +31,7 @@
// return ActivityCollectedDataBinding.inflate(layoutInflater) // return ActivityCollectedDataBinding.inflate(layoutInflater)
// } // }
// //
// private val list: MutableList<CollectedFoodBean> = mutableListOf() // private val list: MutableList<CollectedFoodInfo> = mutableListOf()
// private val adapter by lazy { // private val adapter by lazy {
// CollectedFoodAdapter(list).apply { // CollectedFoodAdapter(list).apply {
// isStateViewEnable = true // isStateViewEnable = true
@@ -88,7 +88,7 @@
// queryList = queryList?.filter { it.name?.contains(searchName) == true } // queryList = queryList?.filter { it.name?.contains(searchName) == true }
// } // }
// queryList?.forEach { // queryList?.forEach {
// list.add(CollectedFoodBean(foodName = it.name)) // list.add(CollectedFoodInfo(foodName = it.name))
// } // }
// adapter.notifyDataSetChanged() // adapter.notifyDataSetChanged()
// if (list.isEmpty()) { // if (list.isEmpty()) {
@@ -11,7 +11,7 @@ import com.sw.dualscreen.databinding.LayoutEmptySearchBinding
import com.sw.dualscreen.dialog.WarnDialog import com.sw.dualscreen.dialog.WarnDialog
import com.sw.dualscreen.ext.addOnActionSearchListener import com.sw.dualscreen.ext.addOnActionSearchListener
import com.sw.dualscreen.ext.hideKeyboard import com.sw.dualscreen.ext.hideKeyboard
import com.sw.dualscreen.objbox.CollectedFoodBean import com.sw.dualscreen.objbox.CollectedFoodInfo
import com.sw.dualscreen.objbox.Food import com.sw.dualscreen.objbox.Food
import com.sw.dualscreen.objbox.ObjectBox import com.sw.dualscreen.objbox.ObjectBox
import com.sw.dualscreen.viewmodel.BaseViewModel import com.sw.dualscreen.viewmodel.BaseViewModel
@@ -30,7 +30,7 @@ class CollectedFoodActivity : BaseActivity<ActivityCollectedFoodBinding>() {
return ActivityCollectedFoodBinding.inflate(layoutInflater) return ActivityCollectedFoodBinding.inflate(layoutInflater)
} }
private val list: MutableList<CollectedFoodBean> = mutableListOf() private val list: MutableList<CollectedFoodInfo> = mutableListOf()
private val adapter by lazy { private val adapter by lazy {
CollectedFoodNewAdapter(list).apply { CollectedFoodNewAdapter(list).apply {
isStateViewEnable = true isStateViewEnable = true
@@ -88,7 +88,7 @@ class CollectedFoodActivity : BaseActivity<ActivityCollectedFoodBinding>() {
val totalList = box?.all val totalList = box?.all
?.filter { it.name!=null } ?.filter { it.name!=null }
?.groupBy { it.name!! } ?.groupBy { it.name!! }
?.map { CollectedFoodBean(foodName = it.key, count = it.value.size) } ?.map { CollectedFoodInfo(foodName = it.key, foodCount = it.value.size) }
//var queryMap:Map<String, List<Food>> ?= null //var queryMap:Map<String, List<Food>> ?= null
if (searchName.isNullOrBlank().not()) { if (searchName.isNullOrBlank().not()) {
//queryMap = totalMap?.filter { it.key.contains(searchName) } //queryMap = totalMap?.filter { it.key.contains(searchName) }
@@ -106,7 +106,18 @@ class CollectedFoodActivity : BaseActivity<ActivityCollectedFoodBinding>() {
loadEmptyView() loadEmptyView()
} }
binding.root.hideKeyboard() binding.root.hideKeyboard()
viewModel.getCollectedFoodList(pageNo = pageNo) {
if (it.isNotEmpty()) {
list.addAll(it)
runOnUiThread {
adapter.notifyDataSetChanged()
} }
}
}
}
private var pageNo = 1
private var emptyBinding: LayoutEmptySearchBinding? = null private var emptyBinding: LayoutEmptySearchBinding? = null
private fun loadEmptyView() { private fun loadEmptyView() {
@@ -29,20 +29,23 @@ class InitActivity : BaseActivity<ActivityInitBinding>() {
override fun initialize() { override fun initialize() {
super.initialize() super.initialize()
val isSuccess = viewModel.checkEquipmentInfo() binding.root.postDelayed({
if (isSuccess) {
goMainActivity() goMainActivity()
return }, 1000)
} // val isSuccess = viewModel.checkEquipmentInfo()
binding.imgQr.setImageBitmap( // if (isSuccess) {
QRCodeUtil.generateQRCode( // goMainActivity()
content = GlobalData.deviceId, // return
size = 200 // }
) // binding.imgQr.setImageBitmap(
) // QRCodeUtil.generateQRCode(
binding.initButton.setOnClickListener { // content = GlobalData.deviceId,
viewModel.getDeviceToken() // size = 200
} // )
// )
// binding.initButton.setOnClickListener {
// viewModel.getDeviceToken()
// }
} }
override fun registerDataChange() { override fun registerDataChange() {
@@ -114,7 +114,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} }
private fun initData() { private fun initData() {
viewModel.getEquipmentToken() // viewModel.getEquipmentToken()
viewModel.getUserFaceCache(pageNo = 1)
// presentation?.step1() // presentation?.step1()
presentation?.step1FoodRecognizing() presentation?.step1FoodRecognizing()
} }
@@ -200,10 +201,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.tvFoodName.setOnClickListener { binding.tvFoodName.setOnClickListener {
SensorScaleUtils.zero() SensorScaleUtils.zero()
} }
binding.tvRescan.setOnClickListener { // binding.tvRescan.setOnClickListener {
debouncer.debounce { recognizeFood() } // debouncer.debounce { recognizeFood() }
} // }
binding.btnPay.setOnClickListener { binding.btnPay.setOnClickListener {
if (checkedItem == null) {
ToastUtils.showToast("暂无识别数据,请搜索选择")
return@setOnClickListener
}
presentation?.dismiss() presentation?.dismiss()
startActivity(Intent(this, PayActivity::class.java).apply { startActivity(Intent(this, PayActivity::class.java).apply {
putExtra(PayActivity.FOOD_INFO, checkedItem) putExtra(PayActivity.FOOD_INFO, checkedItem)
@@ -317,9 +322,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
if (TextUtils.isEmpty(foodName)) { if (TextUtils.isEmpty(foodName)) {
LightManager.closeGreenLight() LightManager.closeGreenLight()
LightManager.closeRedLight() LightManager.closeRedLight()
binding.layoutRescan.visibility = View.VISIBLE //binding.layoutRescan.visibility = View.VISIBLE
binding.flPay.visible()
binding.tvToSearch.let {
it.text = "未识别到,去手动搜索"
it.visible()
}
} else { } else {
binding.layoutRescan.visibility = View.GONE //binding.layoutRescan.visibility = View.GONE
viewModel.getFoodInfo(foodName) { list -> viewModel.getFoodInfo(foodName) { list ->
runOnUiThread { runOnUiThread {
updateFoodInfo(list.toMutableList(), scoreList) updateFoodInfo(list.toMutableList(), scoreList)
@@ -367,7 +377,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
LightManager.closeRedLight() LightManager.closeRedLight()
binding.flPay.visible() binding.flPay.visible()
binding.tvToSearch.visible() binding.tvToSearch.let {
it.text = "以上都不是,手动搜索"
it.visible()
}
} else { } else {
binding.flPay.gone() binding.flPay.gone()
binding.tvToSearch.gone() binding.tvToSearch.gone()
@@ -65,9 +65,7 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
if (binding.btnPayCash.isChecked) { if (binding.btnPayCash.isChecked) {
return@setOnClickListener return@setOnClickListener
} }
if (cashPayFragment == null) {
cashPayFragment = CashPayFragment() cashPayFragment = CashPayFragment()
}
showFragment(cashPayFragment!!, TAG_PAY_CASH) showFragment(cashPayFragment!!, TAG_PAY_CASH)
switchButton(false, true, false, false) switchButton(false, true, false, false)
} }
@@ -75,9 +73,7 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
if (binding.btnPayNumber.isChecked) { if (binding.btnPayNumber.isChecked) {
return@setOnClickListener return@setOnClickListener
} }
if (numberPayFragment == null) {
numberPayFragment = NumberPayFragment() numberPayFragment = NumberPayFragment()
}
showFragment(numberPayFragment!!, TAG_PAY_NUMBER) showFragment(numberPayFragment!!, TAG_PAY_NUMBER)
switchButton(false, false, true, false) switchButton(false, false, true, false)
} }
@@ -92,9 +88,7 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
} }
private fun showScanQrCodePay() { private fun showScanQrCodePay() {
if (qrCodePayFragment == null) {
qrCodePayFragment = ScanQrCodePayFragment() qrCodePayFragment = ScanQrCodePayFragment()
}
showFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE) showFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE)
switchButton(true, false, false, false) switchButton(true, false, false, false)
} }
@@ -107,9 +101,7 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
} }
fun showFacePay() { fun showFacePay() {
if (facePayFragment == null) {
facePayFragment = FacePayFragment() facePayFragment = FacePayFragment()
}
showFragment(facePayFragment!!, TAG_PAY_FACE) showFragment(facePayFragment!!, TAG_PAY_FACE)
switchButton(false, false, false, true) switchButton(false, false, false, true)
} }
@@ -149,9 +141,7 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
// } // }
fun showPayResult() { fun showPayResult() {
if (payResultFragment == null) {
payResultFragment = PayResultFragment() payResultFragment = PayResultFragment()
}
showFragment(payResultFragment!!, TAG_PAY_RESULT) showFragment(payResultFragment!!, TAG_PAY_RESULT)
} }
@@ -162,9 +152,10 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
facePayFragment?.presentation?.dismiss() facePayFragment?.presentation?.dismiss()
super.onDestroy() super.onDestroy()
} }
private var scanQrCodePayPresentation: ScanQrCodePayPresentation?=null
private var scanQrCodePayPresentation: ScanQrCodePayPresentation? = null
fun paySuccess() { fun paySuccess() {
showFragment(PayResultFragment(),"") showFragment(PayResultFragment(), "")
if (displays.size > 1) { if (displays.size > 1) {
scanQrCodePayPresentation = ScanQrCodePayPresentation( scanQrCodePayPresentation = ScanQrCodePayPresentation(
activity = this, activity = this,
@@ -15,7 +15,7 @@ import kotlin.text.replace
class SettingActivity : BaseActivity<ActivitySettingBinding>() { class SettingActivity : BaseActivity<ActivitySettingBinding>() {
private val viewModel by viewModels<UserViewModel>() val viewModel by viewModels<UserViewModel>()
override fun getViewModel(): BaseViewModel { override fun getViewModel(): BaseViewModel {
return viewModel return viewModel
} }
@@ -34,12 +34,16 @@ import com.sw.dualscreen.utils.ImageUtil
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import io.objectbox.Box import io.objectbox.Box
import io.objectbox.kotlin.boxFor import io.objectbox.kotlin.boxFor
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import timber.log.Timber import timber.log.Timber
import java.io.File
import kotlin.getValue import kotlin.getValue
class CollectFragment : BaseFragment<FragmentCollectBinding>() { class CollectFragment : BaseFragment<FragmentCollectBinding>() {
companion object { companion object {
private const val TAG = "CollectFragment"
const val MAX_COUNT = 5 const val MAX_COUNT = 5
} }
private var selectedFoodId: String? = "" private var selectedFoodId: String? = ""
@@ -59,7 +63,7 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
SearchFoodAdapter(searchFoodList).apply { SearchFoodAdapter(searchFoodList).apply {
setOnItemClickListener { adapter, view, position -> setOnItemClickListener { adapter, view, position ->
checkedItem = searchFoodList[position] checkedItem = searchFoodList[position]
selectedFoodId = checkedItem!!.id selectedFoodId = checkedItem!!.foodId
selectedFoodName = checkedItem!!.foodName selectedFoodName = checkedItem!!.foodName
val isChecked = checkedItem!!.isChecked val isChecked = checkedItem!!.isChecked
searchFoodList[position].isChecked = isChecked.not() searchFoodList[position].isChecked = isChecked.not()
@@ -78,8 +82,11 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
addOnItemChildClickListener(R.id.ivDelete) { _, _, position -> addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
foodCollectionList[position].let { foodCollectionList[position].let {
it.bitmap = null it.bitmap = null
it.imageVector = null
it.imageFile = null
it.isShowCamera = true it.isShowCamera = true
it.isFinish = false it.isFinish = false
it.uploadSuccess = false
} }
notifyItemChanged(position) notifyItemChanged(position)
} }
@@ -91,28 +98,45 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
private val cameraCallback: (Uri) -> Unit = { uri -> private val cameraCallback: (Uri) -> Unit = { uri ->
val index = foodCollectionList.indexOfFirst { it.bitmap == null } try {
val index = foodCollectionList.indexOfFirst { it.imageFile == null }
if (index == -1) { if (index == -1) {
ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据") ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
rerurn@cameraCallback rerurn@cameraCallback
} }
ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap -> ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
// val cropBitmap = BitmapCropper.cropCenter( // val cropBitmap = BitmapCropper.cropCenter(
// original = bitmap, // original = bitmap,
// targetWidth = 1300, targetHeight = 900, // targetWidth = 1300, targetHeight = 900,
// //offsetX = 30, offsetY = 100 // //offsetX = 30, offsetY = 100
// ) // )
initBox()
val imageVector = try {
FoodModule.bitmap2FloatArray(bitmap)
} catch (e: Exception) {
e.printStackTrace()
ToastUtils.showToast("操作失败")
return@let
}
val file = BitmapSaver.saveToAppFilesDir( val file = BitmapSaver.saveToAppFilesDir(
bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg" bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg"
) )
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}") Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
foodCollectionList[index].let { foodCollectionList[index].let {
it.bitmap = bitmap it.imageVector = imageVector
it.bitmap = null
it.isShowCamera = false it.isShowCamera = false
it.imageUri = file?.toUri() it.imageFile = file
} }
collectionAdapter.notifyItemChanged(index) collectionAdapter.notifyItemChanged(index)
if (bitmap.isRecycled.not()) {
bitmap.recycle()
}
}
} catch (e: Exception) {
e.printStackTrace()
ToastUtils.showToast("程序异常")
} }
} }
@@ -157,7 +181,9 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
Toast.makeText(requireActivity(), "请拍摄菜品照片", Toast.LENGTH_SHORT).show() Toast.makeText(requireActivity(), "请拍摄菜品照片", Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
vectorThread() vectorThread(){
upload()
}
} }
binding.editFoodName.setOnEditorActionListener { v, actionId, event -> binding.editFoodName.setOnEditorActionListener { v, actionId, event ->
@@ -190,13 +216,43 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
} }
} }
private fun vectorThread() { private fun uploadCollectFoodPics(files: List<File?>, params: HashMap<String, RequestBody>, callback: (Boolean) -> Unit) {
(requireActivity() as SettingActivity).viewModel.uploadCollectFoodPics(files,params, callback)
}
private fun upload() {
val params = HashMap<String, RequestBody>()
//params["placeId"] = restId.toRequestBody()
params["foodId"] = checkedItem!!.foodId.toRequestBody()
params["foodName"] = checkedItem!!.foodName!!.toRequestBody()
//params["foodVector"] = foodVector.toRequestBody()
for (index in foodCollectionList.indices step 5) {
val end = if(index + 5 < foodCollectionList.size - 1) index + 5 else foodCollectionList.size - 1
val subList = foodCollectionList.subList(index, end)
val subFiles = subList.map { it.imageFile }
uploadCollectFoodPics(subFiles, params) { isSuccess->
Timber.tag(TAG).d("uploadMultipleImages: ${isSuccess}")
subList.filter { it.imageFile!=null }.forEach { it.uploadSuccess = isSuccess }
// val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
// runOnUiThread {
// binding.btnUploadImage.text = "待上传图片${count}张"
// if (count == 0) {
// Loading.dismiss()
// }
// }
}
}
}
private fun vectorThread(block:()-> Unit) {
settingActivity?.showWaitingDialog("加载中……") settingActivity?.showWaitingDialog("加载中……")
Thread { Thread {
foodCollectionList foodCollectionList
.filter { it.bitmap != null } // .filter { it.bitmap != null }
.filter { it.imageVector != null }
.forEachIndexed { index, it -> .forEachIndexed { index, it ->
image2VectorTask(it, index) image2VectorTask(imageVector = it.imageVector!!, index)
} }
activity?.runOnUiThread { activity?.runOnUiThread {
binding.root.postDelayed({ binding.root.postDelayed({
@@ -212,25 +268,24 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
} }
} }
private fun image2VectorTask(item: FoodCollectionBean, position: Int) { private fun image2VectorTask(imageVector: FloatArray, position: Int) {
initBox() initBox()
val imageVector = FoodModule.bitmap2FloatArray(item.bitmap!!) // val imageVector = FoodModule.bitmap2FloatArray(item.bitmap!!)
//
// val base64Str = FloatBase64Utils.floatArrayToBase64(imageVector) //// val base64Str = FloatBase64Utils.floatArrayToBase64(imageVector)
// Timber.tag("mzf1").e(base64Str) //// Timber.tag("mzf1").e(base64Str)
//// viewModel.postImageData( ////// viewModel.postImageData(
//// context, ////// context,
//// foodId = selectedFoodId.toString(), ////// foodId = selectedFoodId.toString(),
//// foodName = selectedFoodName.toString(), ////// foodName = selectedFoodName.toString(),
//// foodVector = base64Str, ////// foodVector = base64Str,
//// uri = item.imageUri!! ////// uri = item.imageUri!!
//// ) ////// )
box?.put(Food(name = checkedItem!!.foodName, foodIdx = 0, foodVector = imageVector)) box?.put(Food(name = checkedItem!!.foodName, foodIdx = 0, foodVector = imageVector))
foodCollectionList[position].let { foodCollectionList[position].let {
it.imageVector = imageVector // it.imageVector = imageVector
it.isFinish = true it.isFinish = true
} }
activity?.runOnUiThread { activity?.runOnUiThread {
collectionAdapter.notifyItemChanged(position) collectionAdapter.notifyItemChanged(position)
} }
@@ -33,14 +33,24 @@ class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
override fun onHiddenChanged(hidden: Boolean) { override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden) super.onHiddenChanged(hidden)
if (hidden) { if (hidden) {
binding.root.postDelayed({ delayDismiss()
presentation?.dismiss()
}, 500)
return return
} }
showSubScreen() showSubScreen()
} }
override fun onDestroy() {
delayDismiss()
super.onDestroy()
}
private fun delayDismiss() {
presentation?.dismiss()
//binding.root.postDelayed({
// presentation?.dismiss()
//}, 100)
}
private fun showSubScreen() { private fun showSubScreen() {
// 查找副屏(通常索引为1 // 查找副屏(通常索引为1
if (displays.size > 1) { if (displays.size > 1) {
@@ -29,14 +29,24 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
override fun onHiddenChanged(hidden: Boolean) { override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden) super.onHiddenChanged(hidden)
if (hidden) { if (hidden) {
binding.root.postDelayed({ delayDismiss()
presentation?.dismiss()
}, 500)
return return
} }
showSubScreen() showSubScreen()
} }
override fun onDestroy() {
delayDismiss()
super.onDestroy()
}
private fun delayDismiss() {
presentation?.dismiss()
//binding.root.postDelayed({
// presentation?.dismiss()
//}, 100)
}
fun loadBitmap(frame: Bitmap) { fun loadBitmap(frame: Bitmap) {
binding.ivFaceImage.setImageBitmap(frame) binding.ivFaceImage.setImageBitmap(frame)
} }
@@ -29,14 +29,24 @@ class NumberPayFragment: BaseFragment<FragmentNumberPayBinding>() {
override fun onHiddenChanged(hidden: Boolean) { override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden) super.onHiddenChanged(hidden)
if (hidden) { if (hidden) {
binding.root.postDelayed({ delayDismiss()
presentation?.dismiss()
}, 500)
return return
} }
showSubScreen() showSubScreen()
} }
override fun onDestroy() {
delayDismiss()
super.onDestroy()
}
private fun delayDismiss() {
presentation?.dismiss()
//binding.root.postDelayed({
// presentation?.dismiss()
//}, 100)
}
private fun showSubScreen() { private fun showSubScreen() {
// 查找副屏(通常索引为1 // 查找副屏(通常索引为1
if (displays.size > 1) { if (displays.size > 1) {
@@ -25,6 +25,8 @@ class ScanQrCodePayFragment: BaseFragment<FragmentScanQrcodePayBinding>() {
private var payAmount: String? = null private var payAmount: String? = null
private var payQrCodePic: Any? = null private var payQrCodePic: Any? = null
var presentation: ScanQrCodePayPresentation?=null var presentation: ScanQrCodePayPresentation?=null
private var countDownJob: Job? = null
override fun inflateViewBinding(): FragmentScanQrcodePayBinding { override fun inflateViewBinding(): FragmentScanQrcodePayBinding {
return FragmentScanQrcodePayBinding.inflate(layoutInflater) return FragmentScanQrcodePayBinding.inflate(layoutInflater)
} }
@@ -47,14 +49,25 @@ class ScanQrCodePayFragment: BaseFragment<FragmentScanQrcodePayBinding>() {
override fun onHiddenChanged(hidden: Boolean) { override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden) super.onHiddenChanged(hidden)
if (hidden) { if (hidden) {
binding.root.postDelayed({ delayDismiss()
presentation?.dismiss()
}, 500)
return return
} }
showSubScreen() showSubScreen()
} }
override fun onDestroy() {
delayDismiss()
countDownJob?.cancel() // 自动取消订阅,防止内存泄漏
super.onDestroy()
}
private fun delayDismiss() {
presentation?.dismiss()
//binding.root.postDelayed({
// presentation?.dismiss()
//}, 100)
}
private fun showSubScreen() { private fun showSubScreen() {
// 查找副屏(通常索引为1 // 查找副屏(通常索引为1
if (displays.size > 1) { if (displays.size > 1) {
@@ -90,9 +103,4 @@ class ScanQrCodePayFragment: BaseFragment<FragmentScanQrcodePayBinding>() {
} }
) )
} }
private var countDownJob: Job? = null
override fun onDestroy() {
super.onDestroy()
countDownJob?.cancel() // 自动取消订阅,防止内存泄漏
}
} }
@@ -10,11 +10,11 @@
//import com.sw.dualscreen.R //import com.sw.dualscreen.R
//import com.sw.dualscreen.databinding.ListItemCollectedDataBinding //import com.sw.dualscreen.databinding.ListItemCollectedDataBinding
//import com.sw.dualscreen.databinding.ListItemFoodCollectionBinding //import com.sw.dualscreen.databinding.ListItemFoodCollectionBinding
//import com.sw.dualscreen.objbox.CollectedFoodBean //import com.sw.dualscreen.objbox.CollectedFoodInfo
//import com.sw.dualscreen.objbox.FoodCollectionBean //import com.sw.dualscreen.objbox.FoodCollectionBean
// //
//class CollectedFoodAdapter (var list: MutableList<CollectedFoodBean>) : //class CollectedFoodAdapter (var list: MutableList<CollectedFoodInfo>) :
// BaseQuickAdapter<CollectedFoodBean, CollectedFoodAdapter.VH>(list) { // BaseQuickAdapter<CollectedFoodInfo, CollectedFoodAdapter.VH>(list) {
// //
// inner class VH(var binding: ListItemCollectedDataBinding) : QuickViewHolder(binding.root) // inner class VH(var binding: ListItemCollectedDataBinding) : QuickViewHolder(binding.root)
// //
@@ -24,7 +24,7 @@
// return VH(binding) // return VH(binding)
// } // }
// //
// override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodBean?) { // override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodInfo?) {
// holder.binding.tvFoodName.text = item?.foodName // holder.binding.tvFoodName.text = item?.foodName
// holder.binding.divider.run { // holder.binding.divider.run {
// visibility = if (position == list.size - 1) View.GONE else View.VISIBLE // visibility = if (position == list.size - 1) View.GONE else View.VISIBLE
@@ -6,10 +6,10 @@ import android.view.ViewGroup
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.ListItemCollectedFoodBinding import com.sw.dualscreen.databinding.ListItemCollectedFoodBinding
import com.sw.dualscreen.objbox.CollectedFoodBean import com.sw.dualscreen.objbox.CollectedFoodInfo
class CollectedFoodNewAdapter(var list: MutableList<CollectedFoodBean>) : class CollectedFoodNewAdapter(var list: MutableList<CollectedFoodInfo>) :
BaseQuickAdapter<CollectedFoodBean, CollectedFoodNewAdapter.VH>(list) { BaseQuickAdapter<CollectedFoodInfo, CollectedFoodNewAdapter.VH>(list) {
inner class VH(var binding: ListItemCollectedFoodBinding) : QuickViewHolder(binding.root) inner class VH(var binding: ListItemCollectedFoodBinding) : QuickViewHolder(binding.root)
@@ -19,9 +19,9 @@ class CollectedFoodNewAdapter(var list: MutableList<CollectedFoodBean>) :
return VH(binding) return VH(binding)
} }
override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodBean?) { override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodInfo?) {
holder.binding.tvFoodName.text = item?.foodName holder.binding.tvFoodName.text = item?.foodName
holder.binding.tvCollectedNum.text = "已采集${item?.count}" holder.binding.tvCollectedNum.text = "已采集${item?.foodCount}"
} }
} }
@@ -26,7 +26,7 @@ class SearchFoodAdapter(var list: MutableList<FoodInfo>) :
text = item.foodName text = item.foodName
} else { } else {
val score = (item.score / 100.0).format2String(2) val score = (item.score / 100.0).format2String(2)
text = item.foodName + if (item.score != 0) "-${score}%" else "" text = item.foodName + (if (item.score != 0) "-${score}%" else "")
} }
isChecked = item.isChecked isChecked = item.isChecked
} }
@@ -1,17 +1,16 @@
package com.sw.dualscreen.model.response package com.sw.dualscreen.model.response
data class ApiResponse<T>( data class ApiResponse<T>(
val code: Int? = 0, val code: String,
val message: String? = "", val msg: String? = "",
val result: T? = null, val data: T? = null
val success: Boolean? = false,
val timestamp: Long? = 0
) { ) {
fun isSuccess(): Boolean { fun isSuccess(): Boolean = ("00000" == code)
return success == true
} val result: T?
get() = data
val message: String?
get() = msg
} }
@@ -0,0 +1,5 @@
package com.sw.dualscreen.model.response
data class FoodSearchReq(
var nameList:List<String>
)
@@ -1,42 +1,47 @@
package com.sw.dualscreen.model.response package com.sw.dualscreen.model.response
//{"id":"1992804086323437569","dinnerType":"晚餐","chargeType":1,"fixedAmount":3.0000}
import android.os.Parcelable data class DinnerType(
import com.google.gson.annotations.SerializedName val id: String? = "",
import kotlinx.parcelize.Parcelize //餐次
@Parcelize
data class DinnerTypeInfo(
@SerializedName("dinnerType")
val dinnerType: DinnerType? = DinnerType()
) : Parcelable {
@Parcelize
data class DinnerType(
@SerializedName("createBy")
val createBy: String? = "",
@SerializedName("createTime")
val createTime: String? = "",
@SerializedName("delFlag")
val delFlag: Int? = 0,
@SerializedName("dinnerType")
val dinnerType: String? = "", val dinnerType: String? = "",
@SerializedName("endTime") //餐次收费模式(0称重,1固定,2不收费)
val endTime: String? = "", val chargeType: Int = 0,
@SerializedName("id") //固定收费(元) 仅charge_type = 1 时
val id: Int? = 0, val fixedAmount: Double?=null
@SerializedName("isSync") )
val isSync: Int? = 0, //@Parcelize
@SerializedName("isSyncCopy") //data class DinnerTypeInfo(
val isSyncCopy: Int? = 0, // @SerializedName("dinnerType")
@SerializedName("restId") // val dinnerType: DinnerType? = DinnerType()
val restId: String? = "", //) : Parcelable
@SerializedName("startTime") //
val startTime: String? = "", //@Parcelize
@SerializedName("sysOrgCode") //data class DinnerType(
val sysOrgCode: String? = "", // @SerializedName("createBy")
@SerializedName("updateBy") // val createBy: String? = "",
val updateBy: String? = "", // @SerializedName("createTime")
@SerializedName("updateTime") // val createTime: String? = "",
val updateTime: String? = "" // @SerializedName("delFlag")
) : Parcelable // val delFlag: Int? = 0,
} // @SerializedName("dinnerType")
// val dinnerType: String? = "",
// @SerializedName("endTime")
// val endTime: String? = "",
// @SerializedName("id")
// val id: Int? = 0,
// @SerializedName("isSync")
// val isSync: Int? = 0,
// @SerializedName("isSyncCopy")
// val isSyncCopy: Int? = 0,
// @SerializedName("restId")
// val restId: String? = "",
// @SerializedName("startTime")
// val startTime: String? = "",
// @SerializedName("sysOrgCode")
// val sysOrgCode: String? = "",
// @SerializedName("updateBy")
// val updateBy: String? = "",
// @SerializedName("updateTime")
// val updateTime: String? = ""
//) : Parcelable
@@ -12,11 +12,11 @@ data class EquipmentInfo(
@SerializedName("appPackageUrl") @SerializedName("appPackageUrl")
val appPackageUrl: String? = "", val appPackageUrl: String? = "",
@SerializedName("arcsoftActiveKey") @SerializedName("arcsoftActiveKey")
val arcsoftActiveKey: String? = "", var arcsoftActiveKey: String? = "",
@SerializedName("arcsoftAppId") @SerializedName("arcsoftAppId")
val arcsoftAppId: String? = "", var arcsoftAppId: String? = "",
@SerializedName("arcsoftSdkKey") @SerializedName("arcsoftSdkKey")
val arcsoftSdkKey: String? = "", var arcsoftSdkKey: String? = "",
@SerializedName("arrayCross") @SerializedName("arrayCross")
val arrayCross: Int? = 0, val arrayCross: Int? = 0,
@SerializedName("arrayMode") @SerializedName("arrayMode")
@@ -24,9 +24,9 @@ data class EquipmentInfo(
@SerializedName("arrayVertical") @SerializedName("arrayVertical")
val arrayVertical: Int? = 0, val arrayVertical: Int? = 0,
@SerializedName("canteenId") @SerializedName("canteenId")
val canteenId: String? = "", var canteenId: String? = "",
@SerializedName("canteenName") @SerializedName("canteenName")
val canteenName: String? = "", var canteenName: String? = "",
@SerializedName("clientServerIp") @SerializedName("clientServerIp")
val clientServerIp: String? = "", val clientServerIp: String? = "",
@SerializedName("createBy") @SerializedName("createBy")
@@ -1,6 +1,5 @@
package com.sw.dualscreen.model.response package com.sw.dualscreen.model.response
import android.net.Uri import android.net.Uri
import android.os.Parcelable import android.os.Parcelable
import android.text.TextUtils import android.text.TextUtils
@@ -12,58 +11,63 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class FoodInfo( data class FoodInfo(
@SerializedName("foodLabel") //菜品id
val foodLabel: String? = "", val foodId:String,
@SerializedName("foodName") //菜品名称
val foodName: String? = "", val foodName:String? = null,
@SerializedName("foodTypeAndRealIntakeVoList") //能量
val foodTypeAndRealIntakeVoList: List<FoodTypeAndRealIntakeVo?>? = listOf(), val calorie:String? = null,
/** //蛋白质
* 食物id val protein:String? = null,
*/ //脂肪
@SerializedName("id") val fat:String? = null,
val id: String? = "", //碳水化合物
@SerializedName("imgUrl") val carbohydrate:String? = null,
var imgUrl: String? = "", //规格售卖价格(元)
/** val specPrice:String? = null,
* 拍照结果 //VIP售卖价(元)
*/ val vipPrice:String? = null,
var score: Int = 0,
var isChecked: Boolean = false,
var photoUri: Uri? = null, var photoUri: Uri? = null,
var imgUrl: String? = "",
// @SerializedName("foodTypeAndRealIntakeVoList")
// val foodTypeAndRealIntakeVoList: List<FoodTypeAndRealIntakeVo>? = listOf(),
@SerializedName("stFoodInfoMaterial") @SerializedName("stFoodInfoMaterial")
val stFoodInfoMaterial: StFoodInfoMaterial? = StFoodInfoMaterial(), val stFoodInfoMaterial: StFoodInfoMaterial? = StFoodInfoMaterial(),
@SerializedName("stFoodInfoPagoda") // @SerializedName("stFoodInfoPagoda")
val stFoodInfoPagoda: StFoodInfoPagoda? = StFoodInfoPagoda(), // val stFoodInfoPagoda: StFoodInfoPagoda? = StFoodInfoPagoda(),
@SerializedName("stFoodInfoPagodaAPPVO") @SerializedName("stFoodInfoPagodaAPPVO")
val stFoodInfoPagodaAPPVO: StFoodInfoPagodaAPPVO? = StFoodInfoPagodaAPPVO(), val stFoodInfoPagodaAPPVO: StFoodInfoPagodaAPPVO? = StFoodInfoPagodaAPPVO(),
@SerializedName("stFoodInfoSetting") // @SerializedName("stFoodInfoSetting")
val stFoodInfoSetting: StFoodInfoSetting? = StFoodInfoSetting(), // val stFoodInfoSetting: StFoodInfoSetting? = StFoodInfoSetting(),
@SerializedName("stFoodInfoSpecificationList") // @SerializedName("stFoodInfoSpecificationList")
val stFoodInfoSpecificationList: List<StFoodInfoSpecification?>? = listOf(), // val stFoodInfoSpecificationList: List<StFoodInfoSpecification>? = listOf(),
var score: Int = 0, ) : Parcelable
var isChecked: Boolean = false
) : Parcelable {
@Parcelize
data class FoodTypeAndRealIntakeVo(
@SerializedName("childMaterClassName")
val childMaterClassName: String? = "",
@SerializedName("foodId")
val foodId: String? = "",
@SerializedName("goodsId")
val goodsId: String? = "",
@SerializedName("goodsName")
val goodsName: String? = "",
@SerializedName("materClassName")
val materClassName: String? = "",
@SerializedName("materId")
val materId: String? = "",
@SerializedName("materialType")
val materialType: String? = "",
@SerializedName("realityIntake")
val realityIntake: String? = ""
) : Parcelable
@Parcelize //@Parcelize
data class StFoodInfoMaterial( //data class FoodTypeAndRealIntakeVo(
// @SerializedName("childMaterClassName")
// val childMaterClassName: String? = "",
// @SerializedName("foodId")
// val foodId: String? = "",
// @SerializedName("goodsId")
// val goodsId: String? = "",
// @SerializedName("goodsName")
// val goodsName: String? = "",
// @SerializedName("materClassName")
// val materClassName: String? = "",
// @SerializedName("materId")
// val materId: String? = "",
// @SerializedName("materialType")
// val materialType: String? = "",
// @SerializedName("realityIntake")
// val realityIntake: String? = ""
//) : Parcelable
@Parcelize
data class StFoodInfoMaterial(
@SerializedName("ash") @SerializedName("ash")
val ash: Double? = 0.0, val ash: Double? = 0.0,
@SerializedName("avitE") @SerializedName("avitE")
@@ -142,52 +146,52 @@ data class FoodInfo(
val water: Double? = 0.0, val water: Double? = 0.0,
@SerializedName("zn") @SerializedName("zn")
val zn: Double? = 0.0 val zn: Double? = 0.0
) : Parcelable ) : Parcelable
@Parcelize //@Parcelize
data class StFoodInfoPagoda( //data class StFoodInfoPagoda(
@SerializedName("aquatic") // @SerializedName("aquatic")
val aquatic: String? = "", // val aquatic: String? = "",
@SerializedName("birds") // @SerializedName("birds")
val birds: String? = "", // val birds: String? = "",
@SerializedName("delFlag") // @SerializedName("delFlag")
val delFlag: String? = "", // val delFlag: String? = "",
@SerializedName("egg") // @SerializedName("egg")
val egg: String? = "", // val egg: String? = "",
@SerializedName("foodId") // @SerializedName("foodId")
val foodId: String? = "", // val foodId: String? = "",
@SerializedName("fruits") // @SerializedName("fruits")
val fruits: String? = "", // val fruits: String? = "",
@SerializedName("grain") // @SerializedName("grain")
val grain: String? = "", // val grain: String? = "",
@SerializedName("id") // @SerializedName("id")
val id: String? = "", // val id: String? = "",
@SerializedName("isSync") // @SerializedName("isSync")
val isSync: String? = "", // val isSync: String? = "",
@SerializedName("isSyncCopy") // @SerializedName("isSyncCopy")
val isSyncCopy: String? = "", // val isSyncCopy: String? = "",
@SerializedName("livestock") // @SerializedName("livestock")
val livestock: String? = "", // val livestock: String? = "",
@SerializedName("milk") // @SerializedName("milk")
val milk: String? = "", // val milk: String? = "",
@SerializedName("nuts") // @SerializedName("nuts")
val nuts: String? = "", // val nuts: String? = "",
@SerializedName("oil") // @SerializedName("oil")
val oil: String? = "", // val oil: String? = "",
@SerializedName("potato") // @SerializedName("potato")
val potato: String? = "", // val potato: String? = "",
@SerializedName("salt") // @SerializedName("salt")
val salt: String? = "", // val salt: String? = "",
@SerializedName("soya") // @SerializedName("soya")
val soya: String? = "", // val soya: String? = "",
@SerializedName("sugar") // @SerializedName("sugar")
val sugar: String? = "", // val sugar: String? = "",
@SerializedName("vegetable") // @SerializedName("vegetable")
val vegetable: String? = "" // val vegetable: String? = ""
) : Parcelable //) : Parcelable
@Parcelize @Parcelize
data class StFoodInfoPagodaAPPVO( data class StFoodInfoPagodaAPPVO(
@SerializedName("fruits") @SerializedName("fruits")
val fruits: String? = "", val fruits: String? = "",
@SerializedName("fruitsRecommend") @SerializedName("fruitsRecommend")
@@ -214,7 +218,7 @@ data class FoodInfo(
val vegetable: String? = "", val vegetable: String? = "",
@SerializedName("vegetableRecommend") @SerializedName("vegetableRecommend")
val vegetableRecommend: String? = "" val vegetableRecommend: String? = ""
) : Parcelable { ) : Parcelable {
fun fruitsValue(): Double = fun fruitsValue(): Double =
if (TextUtils.isEmpty(fruits)) if (TextUtils.isEmpty(fruits))
@@ -235,69 +239,68 @@ data class FoodInfo(
if (TextUtils.isEmpty(meat)) if (TextUtils.isEmpty(meat))
0.0 0.0
else meat!!.toDouble() else meat!!.toDouble()
}
@Parcelize
data class StFoodInfoSetting(
@SerializedName("addFoodWeight")
val addFoodWeight: String? = "",
@SerializedName("bowlPlateWeight")
val bowlPlateWeight: String? = "",
@SerializedName("delFlag")
val delFlag: String? = "",
@SerializedName("foodId")
val foodId: String? = "",
@SerializedName("foodStatus")
val foodStatus: String? = "",
@SerializedName("id")
val id: String? = "",
@SerializedName("inventoryStatus")
val inventoryStatus: Boolean? = false,
@SerializedName("isSync")
val isSync: String? = "",
@SerializedName("isSyncCopy")
val isSyncCopy: String? = "",
@SerializedName("replenishWeight")
val replenishWeight: String? = "",
@SerializedName("residueType")
val residueType: String? = "",
@SerializedName("tablewareStatus")
val tablewareStatus: Boolean? = false,
@SerializedName("tablewareWeight")
val tablewareWeight: String? = "",
@SerializedName("warningStatus")
val warningStatus: String? = "",
@SerializedName("weighStatus")
val weighStatus: String? = "",
@SerializedName("weighUnitId")
val weighUnitId: String? = "",
@SerializedName("weighUnitName")
val weighUnitName: String? = ""
) : Parcelable
@Parcelize
data class StFoodInfoSpecification(
@SerializedName("bowlPlateWeight")
val bowlPlateWeight: Double? = 0.0,
@SerializedName("defaultStatus")
val defaultStatus: String? = "",
@SerializedName("delFlag")
val delFlag: String? = "",
@SerializedName("foodId")
val foodId: String? = "",
@SerializedName("id")
val id: String? = "",
@SerializedName("isSync")
val isSync: String? = "",
@SerializedName("isSyncCopy")
val isSyncCopy: String? = "",
@SerializedName("specId")
val specId: String? = "",
@SerializedName("specName")
val specName: String? = "",
@SerializedName("specPrice")
val specPrice: String? = "",
@SerializedName("specWeight")
val specWeight: Double? = 0.0
) : Parcelable
} }
//@Parcelize
//data class StFoodInfoSetting(
// @SerializedName("addFoodWeight")
// val addFoodWeight: String? = "",
// @SerializedName("bowlPlateWeight")
// val bowlPlateWeight: String? = "",
// @SerializedName("delFlag")
// val delFlag: String? = "",
// @SerializedName("foodId")
// val foodId: String? = "",
// @SerializedName("foodStatus")
// val foodStatus: String? = "",
// @SerializedName("id")
// val id: String? = "",
// @SerializedName("inventoryStatus")
// val inventoryStatus: Boolean? = false,
// @SerializedName("isSync")
// val isSync: String? = "",
// @SerializedName("isSyncCopy")
// val isSyncCopy: String? = "",
// @SerializedName("replenishWeight")
// val replenishWeight: String? = "",
// @SerializedName("residueType")
// val residueType: String? = "",
// @SerializedName("tablewareStatus")
// val tablewareStatus: Boolean? = false,
// @SerializedName("tablewareWeight")
// val tablewareWeight: String? = "",
// @SerializedName("warningStatus")
// val warningStatus: String? = "",
// @SerializedName("weighStatus")
// val weighStatus: String? = "",
// @SerializedName("weighUnitId")
// val weighUnitId: String? = "",
// @SerializedName("weighUnitName")
// val weighUnitName: String? = ""
//) : Parcelable
//@Parcelize
//data class StFoodInfoSpecification(
// @SerializedName("bowlPlateWeight")
// val bowlPlateWeight: Double? = 0.0,
// @SerializedName("defaultStatus")
// val defaultStatus: String? = "",
// @SerializedName("delFlag")
// val delFlag: String? = "",
// @SerializedName("foodId")
// val foodId: String? = "",
// @SerializedName("id")
// val id: String? = "",
// @SerializedName("isSync")
// val isSync: String? = "",
// @SerializedName("isSyncCopy")
// val isSyncCopy: String? = "",
// @SerializedName("specId")
// val specId: String? = "",
// @SerializedName("specName")
// val specName: String? = "",
// @SerializedName("specPrice")
// val specPrice: String? = "",
// @SerializedName("specWeight")
// val specWeight: Double? = 0.0
//) : Parcelable
@@ -10,14 +10,15 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class UserFaceModel( data class UserFaceModel(
@SerializedName("faceFeature") // @SerializedName("faceFeature")
val faceFeature: String? = "", // val faceFeature: String? = "",
@SerializedName("faceFeatureString") // @SerializedName("faceFeatureString")
val faceFeatureString: String? = "", // val faceFeatureString: String? = "",
@SerializedName("faceType") // @SerializedName("faceType")
val faceType: String? = "", // val faceType: String? = "",
@SerializedName("userFaceId") // @SerializedName("userFaceId")
val userFaceId: String? = "", // val userFaceId: String? = "",
@SerializedName("userId") // @SerializedName("userId")
val userId: String? = "" val userId: String? = "",
val faceFeatureStr: String? = ""
) : Parcelable ) : Parcelable
@@ -3,16 +3,16 @@ package com.sw.dualscreen.network.api
import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.model.request.UserNutritionParam import com.sw.dualscreen.model.request.UserNutritionParam
import com.sw.dualscreen.model.response.ApiResponse import com.sw.dualscreen.model.response.ApiResponse
import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.DinnerType
import com.sw.dualscreen.model.response.EquipmentInfo
import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.UserFaceInfo import com.sw.dualscreen.model.response.FoodSearchReq
import com.sw.dualscreen.model.response.UserFaceModel
import com.sw.dualscreen.model.response.UserNutritionData import com.sw.dualscreen.model.response.UserNutritionData
import com.sw.dualscreen.objbox.CollectedFoodInfo
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.RequestBody import okhttp3.RequestBody
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Multipart import retrofit2.http.Multipart
import retrofit2.http.POST import retrofit2.http.POST
import retrofit2.http.Part import retrofit2.http.Part
@@ -25,41 +25,54 @@ interface ApiService {
/** /**
* device获取token * device获取token
*/ */
@GET("sys/getEquipmentToken") // @GET("sys/getEquipmentToken")
suspend fun getDeviceToken( // suspend fun getDeviceToken(
@Query("qrcodeId") qrcodeId: String, // @Query("qrcodeId") qrcodeId: String,
@Query("appVersion") appVersion: String = GlobalData.appVersion // @Query("appVersion") appVersion: String = GlobalData.appVersion
): ApiResponse<String> // ): ApiResponse<String>
/** /**
*获取配置信息 *获取配置信息
*/ */
@GET("equipment/stEquipment/queryByEquipmentCode") // @GET("equipment/stEquipment/queryByEquipmentCode")
suspend fun getDeviceInfo( // suspend fun getDeviceInfo(
@Query("equipmentCode") equipmentCode: String, // @Query("equipmentCode") equipmentCode: String,
@Query("appVersion") appVersion: String = GlobalData.appVersion, // @Query("appVersion") appVersion: String = GlobalData.appVersion,
@Header("X-Access-Token") token: String // @Header("X-Access-Token") token: String
): ApiResponse<EquipmentInfo> // ): ApiResponse<EquipmentInfo>
/** /**
* 获取业务服务器token * 获取业务服务器token
*/ */
@GET // @GET
suspend fun getEquipmentToken( // suspend fun getEquipmentToken(
@Url url: String = "${GlobalData.appBaseUrl}/sys/getEquipmentToken", // @Url url: String = "${GlobalData.appBaseUrl}/sys/getEquipmentToken",
@Query("appVersion") appVersion: String = GlobalData.appVersion, // @Query("appVersion") appVersion: String = GlobalData.appVersion,
@Query("qrcodeId") qrcodeId: String // @Query("qrcodeId") qrcodeId: String
): ApiResponse<String> // ): ApiResponse<String>
/** /**
* 获取人脸数据 * 获取人脸数据
*/ */
@GET @POST
suspend fun getUserFaceCache( suspend fun getUserFaceCache(
@Url url: String = "${GlobalData.appBaseUrl}/stapi/cquser/getUserFaceCache/v2", // @Url url: String = "${GlobalData.appBaseUrl}/stapi/cquser/getUserFaceCache/v2",
@Query("appVersion") appVersion: String = GlobalData.appVersion, @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/faceFeature/list",
@Query("pageIndex") pageIndex: Int // @Query("appVersion") appVersion: String = GlobalData.appVersion,
): ApiResponse<UserFaceInfo> // @Query("pageIndex") pageIndex: Int
@Body param: Map<String, Int>
// @Query("pageNum") pageNum: Int,
// @Query("pageSize") pageSize: Int
): ApiResponse<List<UserFaceModel>>
/**
* 获取已采集数据列表
*/
@POST
suspend fun getCollectedFoodList(
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/boothMachine/app/dishPage",
@Body param: Map<String, Int>
): ApiResponse<List<CollectedFoodInfo>>
/** /**
@@ -67,11 +80,14 @@ interface ApiService {
*/ */
@GET @GET
suspend fun getRestInfoFoodsByType( suspend fun getRestInfoFoodsByType(
@Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getRestInfoFoodsByType/stall", // @Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getRestInfoFoodsByType/stall",
@Query("appVersion") appVersion: String = GlobalData.appVersion, // @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/boothMachine/app/getFoodsByFoodNamePage",
@Query("restId") restId: String, @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/boothMachine/app/getFoodsByFoodNameList",
@Query("type") type: Int, @Query("name") foodName: String,
@Query("foodName") foodName: String, // @Query("appVersion") appVersion: String = GlobalData.appVersion,
// @Query("restId") restId: String,
// @Query("type") type: Int,
// @Query("foodName") foodName: String,
): ApiResponse<List<FoodInfo>> ): ApiResponse<List<FoodInfo>>
/** /**
@@ -91,10 +107,11 @@ interface ApiService {
*/ */
@GET @GET
suspend fun getDinnerType( suspend fun getDinnerType(
@Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getCanteenDinnerType", // @Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getCanteenDinnerType",
@Query("appVersion") appVersion: String = GlobalData.appVersion, @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/boothMachine/app/getRegionRule",
@Query("canteenId") restId: String, // @Query("appVersion") appVersion: String = GlobalData.appVersion,
): ApiResponse<DinnerTypeInfo> // @Query("canteenId") restId: String,
): ApiResponse<DinnerType>
/** /**
* 提交就餐数据 * 提交就餐数据
@@ -108,11 +125,13 @@ interface ApiService {
/** /**
* 获取菜品信息 * 获取菜品信息
*/ */
@GET @POST
suspend fun getFoodInfo( suspend fun getFoodInfo(
@Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getRestInfoFoodsByType/stall/v2", // @Url url: String = "${GlobalData.appBaseUrl}/zhstapi/zhst/getRestInfoFoodsByType/stall/v2",
@Query("restId") restId: String, @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/boothMachine/app/goodsList",
@Query("foodNames") foodName: String, // @Query("restId") restId: String,
// @Query("foodNames") foodName: String
@Body req: FoodSearchReq
): ApiResponse<List<FoodInfo>> ): ApiResponse<List<FoodInfo>>
@@ -121,10 +140,11 @@ interface ApiService {
*/ */
@Multipart @Multipart
@POST @POST
suspend fun postImageData( suspend fun uploadCollectFoodPics(
@Url url: String = "http://192.168.1.201:14801/terminal/neglect/dishCollectionVectorData/add", // @Url url: String = "http://192.168.1.201:14801/terminal/neglect/dishCollectionVectorData/add",
@PartMap params: Map<String, @JvmSuppressWildcards RequestBody>, @Url url: String = "http://192.168.1.201:14801/terminal/neglect/boothMachine/app/dishCollectionVectorData/add",
@Part image: MultipartBody.Part? @PartMap params: HashMap<String, RequestBody>,
@Part foodPics: List<MultipartBody.Part>
): ApiResponse<String> ): ApiResponse<String>
} }
@@ -1,6 +1,7 @@
package com.sw.dualscreen.network.interceptor package com.sw.dualscreen.network.interceptor
import android.text.TextUtils import android.text.TextUtils
import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.utils.SPUtil import com.sw.dualscreen.utils.SPUtil
import com.sw.plate.App import com.sw.plate.App
@@ -18,7 +19,10 @@ class RequestInterceptor : Interceptor {
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.header("Accept", "application/json") .header("Accept", "application/json")
// .header("Authorization", "Bearer ${getToken()}") // .header("Authorization", "Bearer ${getToken()}")
.header("X-Access-Token", getToken(originalRequest)) // .header("X-Access-Token", getToken(originalRequest))
// .header("X-DEVICE-CODE", "bcf396ed-78f6-3864-9837-7c37c5b2ec41")
.header("X-DEVICE-CODE", GlobalData.deviceId)
.header("authorization", "57ee87183f2a4fa59683ec9ef41c8f5d")
val newRequest = requestBuilder.build() val newRequest = requestBuilder.build()
@@ -2,6 +2,7 @@ package com.sw.dualscreen.objbox
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri import android.net.Uri
import java.io.File
data class FoodClassInfo( data class FoodClassInfo(
var class_names: List<String>, var class_names: List<String>,
@@ -17,14 +18,20 @@ data class FoodClassInfo(
//) //)
data class FoodCollectionBean( data class FoodCollectionBean(
var imageUri: Uri? = null, var imageFile: File? = null,
var bitmap: Bitmap? = null, var bitmap: Bitmap? = null,
var imageVector: FloatArray? = null, var imageVector: FloatArray? = null,
var isShowCamera: Boolean = false, var isShowCamera: Boolean = false,
var isFinish:Boolean = false var isFinish:Boolean = false,
var uploadSuccess:Boolean = false
) )
data class CollectedFoodBean( data class CollectedFoodInfo(
var foodName: String?, var id: String? = null,
var count: Int = 0 var placeId: String? = null,
var foodId: String? = null,
var foodName: String? = null,
var foodPic: Any? = null,
var foodVector: Any? = null,
var foodCount: Int = 0
) )
@@ -29,7 +29,7 @@ import com.sw.dualscreen.ext.gone
import com.sw.dualscreen.ext.maskName import com.sw.dualscreen.ext.maskName
import com.sw.dualscreen.ext.visible import com.sw.dualscreen.ext.visible
import com.sw.dualscreen.model.request.UserNutritionParam import com.sw.dualscreen.model.request.UserNutritionParam
import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.DinnerType
import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.UserNutritionData import com.sw.dualscreen.model.response.UserNutritionData
import com.sw.dualscreen.utils.Debouncer import com.sw.dualscreen.utils.Debouncer
@@ -89,7 +89,7 @@ class MainScreenPresentation(
private var detectWeight = 0.0 //识别菜品时的重量 private var detectWeight = 0.0 //识别菜品时的重量
private var lastWeight = 0.0 // 上一次的计算热量结果 private var lastWeight = 0.0 // 上一次的计算热量结果
private var userNutritionData: UserNutritionData? = null private var userNutritionData: UserNutritionData? = null
private var dinnerTypeInfo: DinnerTypeInfo? = 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 // 人脸识别时的时间
private var recognitionWeight: Double = 0.0 // 人脸识别时的重量 private var recognitionWeight: Double = 0.0 // 人脸识别时的重量
@@ -228,27 +228,18 @@ class MainScreenPresentation(
return return
} }
updateFoodInfo(currentFood!!) updateFoodInfo(currentFood!!)
// binding.flPreview.visibility = View.VISIBLE
// binding.ivRecImage.visibility = View.VISIBLE
// binding.flFace.visibility = View.INVISIBLE
//// binding.ivFaceBg.visibility = View.GONE
// binding.tvFaceTip.visibility = View.GONE
//
//// binding.tvBottomTip.visibility = View.GONE
// binding.nutritionInclude.clNutritionData.visibility = View.VISIBLE
foodRecSuccess(currentFood!!) foodRecSuccess(currentFood!!)
} }
private fun initView() { private fun initView() {
binding.ivRecImage.let { // //binding.ivRecImage.let {
it.outlineProvider = object : ViewOutlineProvider() { // it.outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) { // override fun getOutline(view: View, outline: Outline) {
outline.setRoundRect(0, 0, view.width, view.height, 12f.dp) // outline.setRoundRect(0, 0, view.width, view.height, 12f.dp)
} // }
} // }
it.clipToOutline = true // it.clipToOutline = true
} // }
} }
override fun onDisplayRemoved() { override fun onDisplayRemoved() {
super.onDisplayRemoved() super.onDisplayRemoved()
@@ -270,7 +261,7 @@ class MainScreenPresentation(
/** /**
* 餐品识别成功,计费模式 * 餐品识别成功,计费模式
*/ */
fun loadBilledMode(foodInfo: FoodInfo) { fun loadBilledMode() {
binding.calorieInclude.root.visible() binding.calorieInclude.root.visible()
binding.nutritionInclude.root.gone() binding.nutritionInclude.root.gone()
@@ -279,7 +270,7 @@ class MainScreenPresentation(
binding.tvFaceTip.gone() binding.tvFaceTip.gone()
binding.tvFoodRecPrompt.gone() binding.tvFoodRecPrompt.gone()
binding.llPriceInfo.visible() binding.llPriceInfo.visible()
binding.ivRecImage.gone() //binding.ivRecImage.gone()
//updateFoodInfo(foodInfo) //updateFoodInfo(foodInfo)
@@ -291,7 +282,7 @@ class MainScreenPresentation(
/** /**
* 餐品识别成功,不计费模式 * 餐品识别成功,不计费模式
*/ */
fun loadUnbilledMode(foodInfo: FoodInfo) { fun loadUnbilledMode() {
binding.calorieInclude.root.gone() binding.calorieInclude.root.gone()
binding.nutritionInclude.root.visible() binding.nutritionInclude.root.visible()
@@ -300,7 +291,7 @@ class MainScreenPresentation(
binding.tvFaceTip.gone() binding.tvFaceTip.gone()
binding.tvFoodRecPrompt.gone() binding.tvFoodRecPrompt.gone()
binding.llPriceInfo.gone() binding.llPriceInfo.gone()
binding.ivRecImage.gone() //binding.ivRecImage.gone()
//updateFoodInfo(foodInfo) //updateFoodInfo(foodInfo)
userNutritionData?.let { userNutritionData?.let {
@@ -342,10 +333,12 @@ class MainScreenPresentation(
binding.tvFoodRecPrompt.visible() binding.tvFoodRecPrompt.visible()
binding.flCameraView.visible() binding.flCameraView.visible()
binding.ivPreviewImage.visible() binding.ivPreviewImage.visible()
binding.ivRecImage.gone() //binding.ivRecImage.gone()
binding.ivFaceRecMask.gone() binding.ivFaceRecMask.gone()
binding.tvFaceTip.gone() binding.tvFaceTip.gone()
binding.llPriceInfo.gone() binding.llPriceInfo.gone()
binding.flFace.gone()
binding.flRecognizeIr.gone()
pauseCamera() pauseCamera()
activity.clearFoodList() activity.clearFoodList()
@@ -356,10 +349,10 @@ class MainScreenPresentation(
val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0) val mode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
if (mode == 0) { if (mode == 0) {
//计费 //计费
loadBilledMode(foodInfo) loadBilledMode()
} else { } else {
//不计费 //不计费
loadUnbilledMode(foodInfo) loadUnbilledMode()
} }
} }
@@ -377,13 +370,14 @@ class MainScreenPresentation(
binding.tvFoodName.text = foodInfo.foodName binding.tvFoodName.text = foodInfo.foodName
binding.flFace.visible() binding.flFace.visible()
binding.flRecognizeIr.visible()
binding.flCameraView.visible() binding.flCameraView.visible()
binding.ivFaceRecMask.visible() binding.ivFaceRecMask.visible()
binding.tvFaceTip.visible() binding.tvFaceTip.visible()
binding.tvFoodRecPrompt.visible() binding.tvFoodRecPrompt.visible()
binding.llPriceInfo.gone() binding.llPriceInfo.gone()
binding.ivRecImage.gone() //binding.ivRecImage.gone()
binding.ivPreviewImage.gone() binding.ivPreviewImage.gone()
dinnerTypeInfo = null dinnerTypeInfo = null
@@ -413,22 +407,22 @@ class MainScreenPresentation(
private fun updateFoodInfo(foodInfo: FoodInfo) { private fun updateFoodInfo(foodInfo: FoodInfo) {
binding.tvFoodName.text = foodInfo.foodName binding.tvFoodName.text = foodInfo.foodName
binding.ivPreviewImage.gone() binding.ivPreviewImage.gone()
binding.ivRecImage.visible() //binding.ivRecImage.visible()
if (foodInfo.photoUri != null) { // if (foodInfo.photoUri != null) {
GlideUtils.loadRoundCornerImage( // GlideUtils.loadRoundCornerImage(
context, // context,
url = foodInfo.photoUri, // url = foodInfo.photoUri,
imageView = binding.ivRecImage, // imageView = //binding.ivRecImage,
radius = 12 // radius = 12
) // )
} else { // } else {
GlideUtils.loadRoundCornerImage( // GlideUtils.loadRoundCornerImage(
context, // context,
url = foodInfo.imgUrl, // url = foodInfo.imgUrl,
imageView = binding.ivRecImage, // imageView = //binding.ivRecImage,
radius = 12 // radius = 12
) // )
} // }
} }
private fun calculateNutrition(weight1: Double) { private fun calculateNutrition(weight1: Double) {
@@ -436,7 +430,7 @@ class MainScreenPresentation(
if (weight < 0) weight = 0.0 if (weight < 0) weight = 0.0
debouncer.debounce { debouncer.debounce {
Timber.tag(TAG).d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight") Timber.tag(TAG).d("calculateNutrition weight = $weight, recognitionWeight = $recognitionWeight")
val dinnerType = dinnerTypeInfo!!.dinnerType!!.dinnerType!! 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( val calcResultInfo = UserNutritionUtils.calculateNutrition(
currentFood!!, currentFood!!,
@@ -638,7 +632,7 @@ class MainScreenPresentation(
} }
userViewModel.getUserNutritionData( userViewModel.getUserNutritionData(
userId = userId, userId = userId,
foodId = currentFood!!.id!! foodId = currentFood!!.foodId!!
) )
}) })
@@ -953,7 +947,7 @@ class MainScreenPresentation(
} }
val userNutritionParam = UserNutritionParam( val userNutritionParam = UserNutritionParam(
userId = userNutritionData?.userId!!, userId = userNutritionData?.userId!!,
foodId = currentFood?.id!!, foodId = currentFood?.foodId !!,
faceTime = recognitionTime, faceTime = recognitionTime,
faceEndTime = System.currentTimeMillis(), faceEndTime = System.currentTimeMillis(),
eatWeight = eatWeight,//lastWeight eatWeight = eatWeight,//lastWeight
File diff suppressed because it is too large Load Diff
@@ -18,31 +18,31 @@ abstract class BaseRepository {
when (e) { when (e) {
is HttpException -> { is HttpException -> {
ApiResponse(code = e.code(), message = e.message()) ApiResponse(code = "${e.code()}", msg = e.message())
} }
is SocketTimeoutException -> { is SocketTimeoutException -> {
ApiResponse(code = -2, message = "请求超时: ${e.message}") ApiResponse(code = "-2", msg = "请求超时: ${e.message}")
} }
is ConnectException -> { is ConnectException -> {
ApiResponse(code = -3, message = "连接失败: ${e.message}") ApiResponse(code = "-3", msg = "连接失败: ${e.message}")
} }
is SSLHandshakeException -> { is SSLHandshakeException -> {
ApiResponse(code = -4, message = "SSL握手失败: ${e.message}") ApiResponse(code = "-4", msg = "SSL握手失败: ${e.message}")
} }
is JsonParseException -> { is JsonParseException -> {
ApiResponse(code = -5, message = "JSON解析错误: ${e.message}") ApiResponse(code = "-5", msg = "JSON解析错误: ${e.message}")
} }
is IOException -> { is IOException -> {
ApiResponse(code = -6, message = "网络IO错误: ${e.message}") ApiResponse(code = "-6", msg = "网络IO错误: ${e.message}")
} }
else -> { else -> {
ApiResponse(code = -1, message = "未知错误: ${e.message ?: "无错误信息"}") ApiResponse(code = "-1", msg = "未知错误: ${e.message ?: "无错误信息"}")
} }
} }
} }
@@ -5,15 +5,20 @@ import android.net.Uri
import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.model.request.UserNutritionParam import com.sw.dualscreen.model.request.UserNutritionParam
import com.sw.dualscreen.model.response.ApiResponse import com.sw.dualscreen.model.response.ApiResponse
import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.DinnerType
import com.sw.dualscreen.model.response.EquipmentInfo
import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.UserFaceInfo import com.sw.dualscreen.model.response.FoodSearchReq
import com.sw.dualscreen.model.response.UserFaceModel
import com.sw.dualscreen.model.response.UserNutritionData import com.sw.dualscreen.model.response.UserNutritionData
import com.sw.dualscreen.network.api.ApiService import com.sw.dualscreen.network.api.ApiService
import com.sw.dualscreen.objbox.CollectedFoodInfo
import com.sw.dualscreen.utils.ImageUtil import com.sw.dualscreen.utils.ImageUtil
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
/** /**
* 远程数据处理 * 远程数据处理
@@ -24,43 +29,65 @@ class RemoteRepository constructor(
/** /**
* 生成token * 生成token
*/ */
suspend fun getDeviceToken(qrcodeId: String): ApiResponse<String> { // suspend fun getDeviceToken(qrcodeId: String): ApiResponse<String> {
return safeApiCall { // return safeApiCall {
apiService.getDeviceToken( // apiService.getDeviceToken(
qrcodeId // qrcodeId
) // )
} // }
} // }
/** /**
* 获取设备信息 * 获取设备信息
*/ */
suspend fun getDeviceInfo(equipmentCode: String, token: String): ApiResponse<EquipmentInfo> { // suspend fun getDeviceInfo(equipmentCode: String, token: String): ApiResponse<EquipmentInfo> {
return safeApiCall { // return safeApiCall {
apiService.getDeviceInfo( // apiService.getDeviceInfo(
equipmentCode, // equipmentCode,
token = token // token = token
) // )
} // }
} // }
/** /**
* 获取业务服务器token * 获取业务服务器token
*/ */
suspend fun getEquipmentToken(qrcodeId: String): ApiResponse<String> { // suspend fun getEquipmentToken(qrcodeId: String): ApiResponse<String> {
return safeApiCall { // return safeApiCall {
apiService.getEquipmentToken(qrcodeId = qrcodeId) // apiService.getEquipmentToken(qrcodeId = qrcodeId)
} // }
} // }
/** /**
* 获取人脸数据 * 获取人脸数据
*/ */
suspend fun getUserFaceCache( suspend fun getUserFaceCache(
pageIndex: Int pageNum: Int,
): ApiResponse<UserFaceInfo> { pageSize: Int = 100,
): ApiResponse<List<UserFaceModel>> {
return safeApiCall { return safeApiCall {
apiService.getUserFaceCache(pageIndex = pageIndex) apiService.getUserFaceCache(
param = mapOf(
"pageNum" to pageNum,
"pageSize" to pageSize
)
)
}
}
/**
* 获取人脸数据
*/
suspend fun getCollectedFoodList(
pageNum: Int,
pageSize: Int = 50,
): ApiResponse<List<CollectedFoodInfo>> {
return safeApiCall {
apiService.getCollectedFoodList(
param = mapOf(
"pageNum" to pageNum,
"pageSize" to pageSize
)
)
} }
} }
@@ -75,7 +102,7 @@ class RemoteRepository constructor(
foodName: String, foodName: String,
): ApiResponse<List<FoodInfo>> { ): ApiResponse<List<FoodInfo>> {
return safeApiCall { return safeApiCall {
apiService.getRestInfoFoodsByType(restId = restId, type = type, foodName = foodName) apiService.getRestInfoFoodsByType(foodName = foodName)
} }
} }
@@ -93,10 +120,10 @@ class RemoteRepository constructor(
} }
suspend fun getDinnerType( suspend fun getDinnerType(
restId: String = GlobalData.restId, // restId: String = GlobalData.restId,
): ApiResponse<DinnerTypeInfo> { ): ApiResponse<DinnerType> {
return safeApiCall { return safeApiCall {
apiService.getDinnerType(restId = restId) apiService.getDinnerType()
} }
} }
@@ -118,29 +145,31 @@ class RemoteRepository constructor(
restId: String = GlobalData.restId, restId: String = GlobalData.restId,
foodName: String, foodName: String,
): ApiResponse<List<FoodInfo>> { ): ApiResponse<List<FoodInfo>> {
return safeApiCall { apiService.getFoodInfo(restId = restId, foodName = foodName) } return safeApiCall {
// val map = mutableMapOf<String, List<String>>()
// map["nameList"] = foodName.split(",")
apiService.getFoodInfo(req = FoodSearchReq(nameList = foodName.split(",")))
} }
}
/** /**
* 获取菜品信息 * 上传采集菜品信息
* @param restId 从device服务获取的canteenId字段
* @param foodName 菜品名称,多个使用逗号拼接
*/ */
suspend fun postImageData( suspend fun uploadCollectFoodPics(fileList: List<File>, params: HashMap<String, RequestBody>): ApiResponse<String> {
context: Context, // 准备文件参数
restId: String = GlobalData.restId, val fileParts = mutableListOf<MultipartBody.Part>()
foodId: String, fileList.forEachIndexed { index, file ->
foodName: String, val requestFile = file
foodVector: String, .asRequestBody("multipart/form-data".toMediaTypeOrNull())
uri: Uri, val filePart = MultipartBody.Part.createFormData(
): ApiResponse<String> { "foodPics",
file.name,
val params = HashMap<String, RequestBody>() requestFile
params["placeId"] = restId.toRequestBody() )
params["foodId"] = foodId.toRequestBody() fileParts.add(filePart)
params["foodName"] = foodName.toRequestBody() }
params["foodVector"] = foodVector.toRequestBody() return safeApiCall {
val imagePart = ImageUtil.uriToMultipart(context, uri, "foodPic") apiService.uploadCollectFoodPics(params = params, foodPics = fileParts)
}
return safeApiCall { apiService.postImageData(params = params, image = imagePart) }
} }
} }
@@ -15,6 +15,15 @@ object ImageUtil {
fun uriToBitmap(context: Context, uri: Uri): Bitmap? { fun uriToBitmap(context: Context, uri: Uri): Bitmap? {
return try { return try {
val options = BitmapFactory.Options()
//options.inSampleSize = 2; // 这会将图片的尺寸缩小到原来的1/2
options.inJustDecodeBounds = false
// options.inPreferredConfig = Bitmap.Config.ARGB_8888
options.inPreferredConfig = Bitmap.Config.RGB_565
context.contentResolver.openInputStream(uri)?.use { stream ->
BitmapFactory.decodeStream(stream, null, options)
// BitmapFactory.decodeStream(stream)
}
context.contentResolver.openInputStream(uri)?.use { stream -> context.contentResolver.openInputStream(uri)?.use { stream ->
BitmapFactory.decodeStream(stream) BitmapFactory.decodeStream(stream)
} }
@@ -52,25 +52,25 @@ abstract class BaseViewModel() : ViewModel() {
} }
protected open fun parseResponse(response: ApiResponse<*>): Boolean { protected open fun parseResponse(response: ApiResponse<*>): Boolean {
if (response.isSuccess() val code = response.code
|| response.code == 200 if (code == "00000" || code == "200" || code == "0") {
|| response.code == 0
) {
return true return true
} }
Timber.d("msg = ${response.message}, code = ${response.code}") val message = response.message?:response.msg
ToastUtils.showToast("${response.message}(${response.code})") Timber.d("msg = ${message}, code = $code")
ToastUtils.showToast("${message}(${code})")
return false return false
} }
fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) { // fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) {
GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!! // //GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!!
//GlobalData.appBaseUrl="http://192.168.1.210/gateway/local" // GlobalData.appBaseUrl = "http://192.168.1.201:14801"
GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!! // //GlobalData.appBaseUrl="http://192.168.1.210/gateway/local"
GlobalData.appId = equipmentInfo.arcsoftAppId!! // GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!!
// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!! // GlobalData.appId = equipmentInfo.arcsoftAppId!!
GlobalData.restId = equipmentInfo.canteenId!! //// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!!
} // GlobalData.restId = equipmentInfo.canteenId!!
// }
fun handleError(exception: Exception) { fun handleError(exception: Exception) {
Timber.d("handleError ${exception.message}") Timber.d("handleError ${exception.message}")
@@ -19,49 +19,49 @@ class DeviceViewModel : BaseViewModel() {
/** /**
* 获取token * 获取token
*/ */
fun getDeviceToken(deviceId: String = GlobalData.deviceId) { // fun getDeviceToken(deviceId: String = GlobalData.deviceId) {
launchWithLoading { // launchWithLoading {
val response = repository.getDeviceToken(deviceId) // val response = repository.getDeviceToken(deviceId)
if (parseResponse(response)) { // if (parseResponse(response)) {
val response1 = repository.getDeviceInfo(deviceId, response.result!!) // val response1 = repository.getDeviceInfo(deviceId, response.result!!)
//
if (parseResponse(response1)) { // if (parseResponse(response1)) {
val equipmentInfo = response1.result // val equipmentInfo = response1.result
if (equipmentInfo == null) return@launchWithLoading // if (equipmentInfo == null) return@launchWithLoading
try { // try {
parseEquipmentInfo(equipmentInfo) // parseEquipmentInfo(equipmentInfo)
SPUtil.getInstance() // SPUtil.getInstance()
.put(GlobalKey.KEY_EQUIPMENT_INFO, GsonUtils.toJson(equipmentInfo)) // .put(GlobalKey.KEY_EQUIPMENT_INFO, GsonUtils.toJson(equipmentInfo))
_deviceInfoResult.value = true // _deviceInfoResult.value = true
} catch (e: Exception) { // } catch (e: Exception) {
Timber.e(e) // Timber.e(e)
} // }
} // }
} // }
} // }
} // }
/** /**
* 检查缓存数据 * 检查缓存数据
*/ */
fun checkEquipmentInfo(): Boolean { // fun checkEquipmentInfo(): Boolean {
val equipmentInfoStr = SPUtil.getInstance().get(GlobalKey.KEY_EQUIPMENT_INFO, "") // val equipmentInfoStr = SPUtil.getInstance().get(GlobalKey.KEY_EQUIPMENT_INFO, "")
if (equipmentInfoStr == null) { // if (equipmentInfoStr == null) {
Timber.e("获取缓存设备信息失败") // Timber.e("获取缓存设备信息失败")
return false // return false
} // }
val equipmentInfo = // val equipmentInfo =
GsonUtils.fromJson<EquipmentInfo>(equipmentInfoStr, EquipmentInfo::class.java) // GsonUtils.fromJson<EquipmentInfo>(equipmentInfoStr, EquipmentInfo::class.java)
if (equipmentInfo == null) { // if (equipmentInfo == null) {
Timber.e("解析缓存设备信息失败") // Timber.e("解析缓存设备信息失败")
return false // return false
} // }
try { // try {
parseEquipmentInfo(equipmentInfo) // parseEquipmentInfo(equipmentInfo)
return true // return true
} catch (e: Exception) { // } catch (e: Exception) {
Timber.e(e) // Timber.e(e)
return false // return false
} // }
} // }
} }
@@ -1,16 +1,15 @@
package com.sw.dualscreen.viewmodel package com.sw.dualscreen.viewmodel
import android.content.Context
import android.net.Uri
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.arcsoft.face.ErrorInfo import com.arcsoft.face.ErrorInfo
import com.sw.dualscreen.GlobalData import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.GlobalKey import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.model.request.UserNutritionParam import com.sw.dualscreen.model.request.UserNutritionParam
import com.sw.dualscreen.model.response.DinnerTypeInfo import com.sw.dualscreen.model.response.DinnerType
import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.UserFaceModel import com.sw.dualscreen.model.response.UserFaceModel
import com.sw.dualscreen.model.response.UserNutritionData import com.sw.dualscreen.model.response.UserNutritionData
import com.sw.dualscreen.objbox.CollectedFoodInfo
import com.sw.dualscreen.utils.SPUtil import com.sw.dualscreen.utils.SPUtil
import com.sw.plate.App import com.sw.plate.App
import com.sw.plate.utils.Base64 import com.sw.plate.utils.Base64
@@ -22,10 +21,15 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.RequestBody
import timber.log.Timber import timber.log.Timber
import kotlin.math.atan import java.io.File
class UserViewModel : BaseViewModel() { class UserViewModel : BaseViewModel() {
companion object {
private const val TAG = "UserViewModel"
const val PAGE_SIZE = 100
}
private val faceApi: FaceApi = FaceApi() private val faceApi: FaceApi = FaceApi()
@@ -44,8 +48,8 @@ class UserViewModel : BaseViewModel() {
/** /**
* 饭点类型 早餐/午餐/晚餐 * 饭点类型 早餐/午餐/晚餐
*/ */
private val _dinnerTypeInfo = MutableStateFlow<DinnerTypeInfo?>(null) private val _dinnerTypeInfo = MutableStateFlow<DinnerType?>(null)
val dinnerTypeInfo: StateFlow<DinnerTypeInfo?> = _dinnerTypeInfo val dinnerTypeInfo: StateFlow<DinnerType?> = _dinnerTypeInfo
/** /**
* 人脸加载完成 * 人脸加载完成
@@ -59,47 +63,68 @@ class UserViewModel : BaseViewModel() {
* 获取token * 获取token
*/ */
fun getEquipmentToken(qrcodeId: String = GlobalData.deviceId) { fun getEquipmentToken(qrcodeId: String = GlobalData.deviceId) {
Timber.d("getEquipmentToken") // Timber.tag(TAG).d("getEquipmentToken")
launchWithLoading { // launchWithLoading {
val response = repository.getEquipmentToken(qrcodeId) // val response = repository.getEquipmentToken(qrcodeId)
if (parseResponse(response)) { // if (parseResponse(response)) {
// 缓存token // // 缓存token
SPUtil.getInstance().put(GlobalKey.KEY_TOKEN, response.result) // SPUtil.getInstance().put(GlobalKey.KEY_TOKEN, response.result)
// 首次运行获取人脸数据 // // 首次运行获取人脸数据
if (SPUtil.getInstance().get(GlobalKey.KEY_FIRST_RUN, false) != true) { // if (SPUtil.getInstance().get(GlobalKey.KEY_FIRST_RUN, false) != true) {
getUserFaceCache(index = 0) // getUserFaceCache(pageNo = 1)
} // }
} // }
} // }
} }
/** /**
* 获取人脸数据 * 获取人脸数据
*/ */
fun getUserFaceCache(index: Int = 0) { fun getUserFaceCache(pageNo: Int = 1, pageSize: Int = PAGE_SIZE) {
Timber.d("getUserFaceCache index = $index") var currentPageNo = pageNo
Timber.tag(TAG).d("getUserFaceCache index = $currentPageNo")
launch { launch {
_loadFaceResult.value = false _loadFaceResult.value = false
val response = repository.getUserFaceCache(index) val response = repository.getUserFaceCache(currentPageNo)
if (parseResponse(response)) { if (parseResponse(response)) {
// 获取成功一次后缓存状态 // 获取成功一次后缓存状态
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
val list: List<UserFaceModel> = response.result?.data ?: emptyList() val list: List<UserFaceModel> = response.result ?: emptyList()
val item = list.firstOrNull { it.userId == "1951105919342936066" } val item = list.firstOrNull { it.userId == "1951105919342936066" }
Timber.d("getUserFaceCache userId = ${item?.userId}") Timber.tag(TAG).d("getUserFaceCache userId = ${item?.userId}")
val faceEntity = list.map { val faceEntity = list.map {
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureString)) FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr))
} }
faceApi.updateFaceData(index, faceEntity) faceApi.updateFaceData(currentPageNo, faceEntity)
} if (list.size >= pageSize) {
val nextPageIndex = response.result?.nextPageIndex ?: -1 currentPageNo++
if (nextPageIndex > 0) { getUserFaceCache(currentPageNo)
getUserFaceCache(nextPageIndex)
} else { } else {
_loadFaceResult.value = true _loadFaceResult.value = true
} }
} }
// val nextPageIndex = response.result?.nextPageIndex ?: -1
// if (nextPageIndex > 0) {
// getUserFaceCache(nextPageIndex)
// } else {
// _loadFaceResult.value = true
// }
}
}
}
fun getCollectedFoodList(pageNo: Int = 1, pageSize: Int = 100, block:(List<CollectedFoodInfo>)-> Unit) {
Timber.tag(TAG).d("getCollectedFoodList index = $pageNo")
launch {
val response = repository.getCollectedFoodList(pageNo)
if (parseResponse(response)) {
withContext(Dispatchers.Default) {
val list: List<CollectedFoodInfo> = response.result ?: emptyList()
block(list)
}
}
} }
} }
@@ -107,7 +132,7 @@ class UserViewModel : BaseViewModel() {
* 激活人脸识别引擎 * 激活人脸识别引擎
*/ */
fun activeEngine() { fun activeEngine() {
Timber.d("activeEngine") Timber.tag(TAG).d("activeEngine")
faceApi.activeEngine( faceApi.activeEngine(
App.getContext(), App.getContext(),
@@ -116,7 +141,7 @@ class UserViewModel : BaseViewModel() {
GlobalData.activeKey, GlobalData.activeKey,
object : FaceApi.ActiveCallback { object : FaceApi.ActiveCallback {
override fun onSuccess(activeCode: Int) { override fun onSuccess(activeCode: Int) {
Timber.d("activeEngine activeCode = $activeCode") Timber.tag(TAG).d("activeEngine activeCode = $activeCode")
viewModelScope.launch(Dispatchers.Main) { viewModelScope.launch(Dispatchers.Main) {
when (activeCode) { when (activeCode) {
ErrorInfo.MOK -> { ErrorInfo.MOK -> {
@@ -142,18 +167,18 @@ class UserViewModel : BaseViewModel() {
}) })
} }
fun getIdentifiedFoodList() { // fun getIdentifiedFoodList() {
Timber.d("identifiedFoodList") // Timber.tag(TAG).d("identifiedFoodList")
launchWithLoading { // launchWithLoading {
val response = repository.getRestInfoFoodsByType(foodName = "") // val response = repository.getRestInfoFoodsByType(foodName = "")
if (parseResponse(response)) { // if (parseResponse(response)) {
_identifiedFoodInfoList.value = response.result ?: emptyList() // _identifiedFoodInfoList.value = response.result ?: emptyList()
} // }
} // }
} // }
fun cleanIdentifiedFoodInfoList() { fun cleanIdentifiedFoodInfoList() {
Timber.d("cleanIdentifiedFoodInfoList") Timber.tag(TAG).d("cleanIdentifiedFoodInfoList")
_identifiedFoodInfoList.value = emptyList<FoodInfo>() _identifiedFoodInfoList.value = emptyList<FoodInfo>()
} }
@@ -161,19 +186,19 @@ class UserViewModel : BaseViewModel() {
* 搜索食物 * 搜索食物
*/ */
fun searchByFoodName(foodName: String, action: (List<FoodInfo>) -> Unit = {}) { fun searchByFoodName(foodName: String, action: (List<FoodInfo>) -> Unit = {}) {
Timber.d("searchByFoodName foodName = $foodName") Timber.tag(TAG).d("searchByFoodName foodName = $foodName")
launchWithLoading { launchWithLoading {
val response = repository.getRestInfoFoodsByType(foodName = foodName) val response = repository.getRestInfoFoodsByType(foodName = foodName)
if (parseResponse(response)) { if (parseResponse(response)) {
val list = response.result ?: emptyList() val list = response.result ?: emptyList()
action(list) action(list)
_searchFoodInfoList.value = list _identifiedFoodInfoList.value = response.result ?: emptyList()
} }
} }
} }
fun cleanSearchFoodInfoList() { fun cleanSearchFoodInfoList() {
Timber.d("cleanSearchFoodInfoList") Timber.tag(TAG).d("cleanSearchFoodInfoList")
_searchFoodInfoList.value = emptyList<FoodInfo>() _searchFoodInfoList.value = emptyList<FoodInfo>()
} }
@@ -181,7 +206,7 @@ class UserViewModel : BaseViewModel() {
* 获取用户就餐数据 * 获取用户就餐数据
*/ */
fun getUserNutritionData(userId: String, foodId: String) { fun getUserNutritionData(userId: String, foodId: String) {
Timber.d("getUserNutritionData userId = ${userId}, foodId = $foodId") Timber.tag(TAG).d("getUserNutritionData userId = ${userId}, foodId = $foodId")
_nutritionData.value = null _nutritionData.value = null
launch { launch {
val response = repository.getUserNutritionData(userId = userId, foodId = foodId) val response = repository.getUserNutritionData(userId = userId, foodId = foodId)
@@ -192,7 +217,7 @@ class UserViewModel : BaseViewModel() {
} }
fun getDinnerType() { fun getDinnerType() {
Timber.d("getDinnerType") Timber.tag(TAG).d("getDinnerType")
_dinnerTypeInfo.value = null _dinnerTypeInfo.value = null
launch { launch {
val response = repository.getDinnerType() val response = repository.getDinnerType()
@@ -206,7 +231,7 @@ class UserViewModel : BaseViewModel() {
* 提交就餐数据 * 提交就餐数据
*/ */
fun postUserNutritionData(param: List<UserNutritionParam>) { fun postUserNutritionData(param: List<UserNutritionParam>) {
Timber.d("postUserNutritionData param = $param") Timber.tag(TAG).d("postUserNutritionData param = $param")
launch { launch {
val response = repository.postUserNutritionData(param) val response = repository.postUserNutritionData(param)
if (parseResponse(response)) { if (parseResponse(response)) {
@@ -215,13 +240,13 @@ class UserViewModel : BaseViewModel() {
} }
} }
fun getFoodInfo(foodName: String, action:(List<FoodInfo>)-> Unit = {}) { fun getFoodInfo(foodName: String, action: (List<FoodInfo>) -> Unit = {}) {
Timber.d("getFoodInfo") Timber.tag(TAG).d("getFoodInfo")
launchWithLoading { launchWithLoading {
val response = repository.getFoodInfo(foodName = foodName) val response = repository.getFoodInfo(foodName = foodName)
if (parseResponse(response)) { if (parseResponse(response)) {
val list = response.result ?: emptyList() val list = response.result ?: emptyList()
_identifiedFoodInfoList2.value = list _identifiedFoodInfoList.value = list
action(list) action(list)
} else { } else {
action(emptyList()) action(emptyList())
@@ -229,22 +254,22 @@ class UserViewModel : BaseViewModel() {
} }
} }
fun postImageData(
context: Context,
foodId: String, fun uploadCollectFoodPics(files: List<File?>, params: HashMap<String, RequestBody>, callback: (Boolean) -> Unit) {
foodName: String, Timber.tag(TAG).d("uploadCollectFoodPics")
foodVector: String,
uri: Uri
) {
Timber.d("postImageData")
launchWithLoading { launchWithLoading {
val response = repository.postImageData( val fileList = files.filterNotNull()
context, foodId = foodId, foodName = foodName, foodVector = foodVector, if (fileList.isEmpty()) {
uri = uri callback(false)
) return@launchWithLoading
if (parseResponse(response)) {
Timber.tag("mzf").d("code=${response.code}")
} }
val resp = repository.uploadCollectFoodPics(fileList, params)
if (!parseResponse(resp)) {
callback(false)
return@launchWithLoading
}
callback(resp.code == "00000")
} }
} }
} }
+1 -1
View File
@@ -3,5 +3,5 @@
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="#FFF5F6F8" /> <solid android:color="#FFF5F6F8" />
<corners <corners
android:radius="43dp" /> android:radius="50dp" />
</shape> </shape>
+4 -2
View File
@@ -63,7 +63,8 @@
android:text="设备初始化" android:text="设备初始化"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="30sp" android:textSize="30sp"
android:textStyle="bold" /> android:textStyle="bold"
android:visibility="invisible"/>
<TextView <TextView
android:id="@+id/activeArcsoft" android:id="@+id/activeArcsoft"
@@ -86,6 +87,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
tools:src="@mipmap/ic_launcher"/> tools:src="@mipmap/ic_launcher"
android:visibility="invisible"/>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
+33 -29
View File
@@ -104,37 +104,41 @@
android:layout_marginTop="42dp" android:layout_marginTop="42dp"
android:layout_weight="1" /> android:layout_weight="1" />
<LinearLayout <!-- <LinearLayout-->
android:id="@+id/layout_rescan" <!-- android:id="@+id/layoutRescan"-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_marginBottom="140dp" <!-- android:layout_marginBottom="140dp"-->
android:gravity="center" <!-- android:gravity="center"-->
android:orientation="vertical" <!-- android:orientation="vertical"-->
android:visibility="gone"> <!-- android:visibility="gone">-->
<!-- <TextView-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="未识别出菜品,请重试或手动搜索"-->
<!-- android:textColor="#FFFF3232"-->
<!-- android:textSize="24sp" />-->
<!-- <CheckedTextView-->
<!-- android:id="@+id/tv_rescan"-->
<!-- android:layout_width="360dp"-->
<!-- android:layout_height="90dp"-->
<!-- android:layout_marginTop="20dp"-->
<!-- android:background="@drawable/bg_search_food"-->
<!-- android:gravity="center"-->
<!-- android:padding="10dp"-->
<!-- android:text="重试"-->
<!-- android:paddingHorizontal="15dp"-->
<!-- android:textAlignment="center"-->
<!-- android:textColor="@color/color_search_food"-->
<!-- android:textStyle="bold"-->
<!-- android:checked="true"-->
<!-- android:textSize="32sp" />-->
<!-- </LinearLayout>-->
<TextView <TextView
android:layout_width="wrap_content" android:id="@+id/tvToSearch"
android:layout_height="wrap_content"
android:text="未识别出菜品,请重试或手动搜索"
android:textColor="#FFFF3232"
android:textSize="24sp" />
<TextView
android:id="@+id/tv_rescan"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/bg_border_red"
android:gravity="center"
android:padding="10dp"
android:text="重试"
android:textColor="#FFFF3232"
android:textSize="32sp" />
</LinearLayout>
<TextView
android:id="@+id/tv_to_search"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="38dp" android:layout_marginTop="38dp"
+12 -12
View File
@@ -4,31 +4,31 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottom_sheet_layout" android:id="@+id/bottom_sheet_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="900dp" android:layout_height="1000dp"
android:background="@drawable/bottom_sheet_background" android:background="@drawable/bottom_sheet_background"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:orientation="vertical"> android:orientation="vertical">
<View <View
android:id="@+id/view_close" android:id="@+id/view_close"
android:layout_width="78dp" android:layout_width="90dp"
android:layout_height="9dp" android:layout_height="10dp"
android:layout_marginTop="28dp" android:layout_marginTop="32dp"
android:background="@drawable/view_shape_point" /> android:background="@drawable/view_shape_point" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="41dp" android:layout_marginTop="47dp"
android:text="菜品检索" android:text="菜品检索"
android:textStyle="bold" android:textStyle="bold"
android:textColor="#FF0A1428" android:textColor="#FF0A1428"
android:textSize="31sp" /> android:textSize="36sp" />
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="87dp" android:layout_height="100dp"
android:layout_marginTop="56dp" android:layout_marginTop="64dp"
android:layout_marginHorizontal="28dp" android:layout_marginHorizontal="28dp"
android:background="@drawable/bg_search" android:background="@drawable/bg_search"
android:gravity="center_vertical" android:gravity="center_vertical"
@@ -47,14 +47,14 @@
android:inputType="text" android:inputType="text"
android:textColor="#FF0A1428" android:textColor="#FF0A1428"
android:textColorHint="#FFB1B1C0" android:textColorHint="#FFB1B1C0"
android:textSize="31sp" /> android:textSize="36sp" />
<ImageView <ImageView
android:id="@+id/iv_search" android:id="@+id/iv_search"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="85dp" android:layout_height="100dp"
android:paddingStart="25dp" android:paddingStart="25dp"
android:paddingEnd="40dp" android:paddingEnd="35dp"
android:layout_gravity="end|center_vertical" android:layout_gravity="end|center_vertical"
android:src="@drawable/ic_search2" /> android:src="@drawable/ic_search2" />
</FrameLayout> </FrameLayout>
@@ -64,7 +64,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:minHeight="500dp" android:minHeight="500dp"
android:layout_marginTop="42dp" android:layout_marginTop="48dp"
android:layout_marginBottom="20dp" android:layout_marginBottom="20dp"
android:layout_marginHorizontal="14dp" android:layout_marginHorizontal="14dp"
app:spanCount="2" app:spanCount="2"
@@ -44,6 +44,7 @@
android:layout_marginEnd="75dp" android:layout_marginEnd="75dp"
android:paddingHorizontal="10dp" android:paddingHorizontal="10dp"
android:src="@drawable/ic_close2" android:src="@drawable/ic_close2"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription"
android:visibility="gone"/>
</LinearLayout> </LinearLayout>
@@ -82,11 +82,11 @@
android:layout_height="456dp" android:layout_height="456dp"
tools:background="@mipmap/ic_launcher"/> tools:background="@mipmap/ic_launcher"/>
<ImageView <!-- <ImageView-->
android:id="@+id/ivRecImage" <!-- android:id="@+id/ivRecImage"-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="456dp" <!-- android:layout_height="456dp"-->
tools:background="@mipmap/ic_launcher"/> <!-- tools:background="@mipmap/ic_launcher"/>-->
<ImageView <ImageView
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -228,11 +228,11 @@
</LinearLayout> </LinearLayout>
<FrameLayout <FrameLayout
android:id="@+id/fl_recognize_ir" android:id="@+id/flRecognizeIr"
android:layout_width="1.3333dp" android:layout_width="1.3333dp"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:visibility="visible"> android:visibility="gone">
<TextureView <TextureView
android:id="@+id/dual_camera_texture_preview_ir" android:id="@+id/dual_camera_texture_preview_ir"
@@ -32,7 +32,7 @@ public class FaceApi {
public void updateFaceData(int index, List<FaceEntity> list) { public void updateFaceData(int index, List<FaceEntity> list) {
Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size()); Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size());
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
if (index == 0) { if (index == 1) {
faceDao.deleteAll(); faceDao.deleteAll();
faceDao.resetId(); faceDao.resetId();
} }