接口联调

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,8 +106,19 @@ 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() {
if (emptyBinding == null) { if (emptyBinding == null) {
@@ -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 {
if (index == -1) { val index = foodCollectionList.indexOfFirst { it.imageFile == null }
ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据") if (index == -1) {
rerurn@cameraCallback ToastUtils.showToast("每次只允许保存${MAX_COUNT}条数据")
} rerurn@cameraCallback
ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
// val cropBitmap = BitmapCropper.cropCenter(
// original = bitmap,
// targetWidth = 1300, targetHeight = 900,
// //offsetX = 30, offsetY = 100
// )
val file = BitmapSaver.saveToAppFilesDir(
bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg"
)
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
foodCollectionList[index].let {
it.bitmap = bitmap
it.isShowCamera = false
it.imageUri = file?.toUri()
} }
collectionAdapter.notifyItemChanged(index) ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
// val cropBitmap = BitmapCropper.cropCenter(
// original = bitmap,
// targetWidth = 1300, targetHeight = 900,
// //offsetX = 30, offsetY = 100
// )
initBox()
val imageVector = try {
FoodModule.bitmap2FloatArray(bitmap)
} catch (e: Exception) {
e.printStackTrace()
ToastUtils.showToast("操作失败")
return@let
}
val file = BitmapSaver.saveToAppFilesDir(
bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg"
)
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
foodCollectionList[index].let {
it.imageVector = imageVector
it.bitmap = null
it.isShowCamera = false
it.imageFile = file
}
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 //餐次
val dinnerType: String? = "",
@Parcelize //餐次收费模式(0称重,1固定,2不收费)
data class DinnerTypeInfo( val chargeType: Int = 0,
@SerializedName("dinnerType") //固定收费(元) 仅charge_type = 1 时
val dinnerType: DinnerType? = DinnerType() val fixedAmount: Double?=null
) : Parcelable { )
@Parcelize //@Parcelize
data class DinnerType( //data class DinnerTypeInfo(
@SerializedName("createBy") // @SerializedName("dinnerType")
val createBy: String? = "", // val dinnerType: DinnerType? = DinnerType()
@SerializedName("createTime") //) : Parcelable
val createTime: String? = "", //
@SerializedName("delFlag") //@Parcelize
val delFlag: Int? = 0, //data class DinnerType(
@SerializedName("dinnerType") // @SerializedName("createBy")
val dinnerType: String? = "", // val createBy: String? = "",
@SerializedName("endTime") // @SerializedName("createTime")
val endTime: String? = "", // val createTime: String? = "",
@SerializedName("id") // @SerializedName("delFlag")
val id: Int? = 0, // val delFlag: Int? = 0,
@SerializedName("isSync") // @SerializedName("dinnerType")
val isSync: Int? = 0, // val dinnerType: String? = "",
@SerializedName("isSyncCopy") // @SerializedName("endTime")
val isSyncCopy: Int? = 0, // val endTime: String? = "",
@SerializedName("restId") // @SerializedName("id")
val restId: String? = "", // val id: Int? = 0,
@SerializedName("startTime") // @SerializedName("isSync")
val startTime: String? = "", // val isSync: Int? = 0,
@SerializedName("sysOrgCode") // @SerializedName("isSyncCopy")
val sysOrgCode: String? = "", // val isSyncCopy: Int? = 0,
@SerializedName("updateBy") // @SerializedName("restId")
val updateBy: String? = "", // val restId: String? = "",
@SerializedName("updateTime") // @SerializedName("startTime")
val updateTime: String? = "" // val startTime: String? = "",
) : Parcelable // @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,292 +11,296 @@ 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
//@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
data class StFoodInfoMaterial(
@SerializedName("ash")
val ash: Double? = 0.0,
@SerializedName("avitE")
val avitE: Double? = 0.0,
@SerializedName("ca")
val ca: Double? = 0.0,
@SerializedName("cho")
val cho: Double? = 0.0,
@SerializedName("cholesterol")
val cholesterol: Double? = 0.0,
@SerializedName("cu")
val cu: Double? = 0.0,
@SerializedName("delFlag")
val delFlag: String? = "",
@SerializedName("dietFiber")
val dietFiber: Double? = 0.0,
@SerializedName("elementI")
val elementI: Double? = 0.0,
@SerializedName("elementK")
val elementK: String? = "",
@SerializedName("elementP")
val elementP: String? = "",
@SerializedName("energyKcal")
val energyKcal: Double? = 0.0,
@SerializedName("energyKj")
val energyKj: Double? = 0.0,
@SerializedName("fat")
val fat: Double? = 0.0,
@SerializedName("fe")
val fe: Double? = 0.0,
@SerializedName("folate")
val folate: Double? = 0.0,
@SerializedName("foodId")
val foodId: String? = "",
@SerializedName("foodWeight")
val foodWeight: String? = "",
@SerializedName("historyStatus")
val historyStatus: String? = "",
@SerializedName("id")
val id: String? = "",
@SerializedName("isSync")
val isSync: String? = "",
@SerializedName("isSyncCopy")
val isSyncCopy: String? = "",
@SerializedName("mg")
val mg: Double? = 0.0,
@SerializedName("mn")
val mn: Double? = 0.0,
@SerializedName("na")
val na: Double? = 0.0,
@SerializedName("naicin")
val naicin: Double? = 0.0,
@SerializedName("protein")
val protein: Double? = 0.0,
@SerializedName("retionl")
val retionl: Double? = 0.0,
@SerializedName("riboflavin")
val riboflavin: Double? = 0.0,
@SerializedName("se")
val se: Double? = 0.0,
@SerializedName("thiamin")
val thiamin: Double? = 0.0,
@SerializedName("totCarotene")
val totCarotene: Double? = 0.0,
@SerializedName("vitA")
val vitA: Double? = 0.0,
@SerializedName("vitB12")
val vitB12: Double? = 0.0,
@SerializedName("vitB6")
val vitB6: Double? = 0.0,
@SerializedName("vitC")
val vitC: Double? = 0.0,
@SerializedName("vitE")
val vitE: Double? = 0.0,
@SerializedName("water")
val water: Double? = 0.0,
@SerializedName("zn")
val zn: Double? = 0.0
) : Parcelable
//@Parcelize
//data class StFoodInfoPagoda(
// @SerializedName("aquatic")
// val aquatic: String? = "",
// @SerializedName("birds")
// val birds: String? = "",
// @SerializedName("delFlag")
// val delFlag: String? = "",
// @SerializedName("egg")
// val egg: String? = "",
// @SerializedName("foodId")
// val foodId: String? = "",
// @SerializedName("fruits")
// val fruits: String? = "",
// @SerializedName("grain")
// val grain: String? = "",
// @SerializedName("id")
// val id: String? = "",
// @SerializedName("isSync")
// val isSync: String? = "",
// @SerializedName("isSyncCopy")
// val isSyncCopy: String? = "",
// @SerializedName("livestock")
// val livestock: String? = "",
// @SerializedName("milk")
// val milk: String? = "",
// @SerializedName("nuts")
// val nuts: String? = "",
// @SerializedName("oil")
// val oil: String? = "",
// @SerializedName("potato")
// val potato: String? = "",
// @SerializedName("salt")
// val salt: String? = "",
// @SerializedName("soya")
// val soya: String? = "",
// @SerializedName("sugar")
// val sugar: String? = "",
// @SerializedName("vegetable")
// val vegetable: String? = ""
//) : Parcelable
@Parcelize
data class StFoodInfoPagodaAPPVO(
@SerializedName("fruits")
val fruits: String? = "",
@SerializedName("fruitsRecommend")
val fruitsRecommend: String? = "",
@SerializedName("grain")
val grain: String? = "",
@SerializedName("grainRecommend")
val grainRecommend: String? = "",
@SerializedName("meat")
val meat: String? = "",
@SerializedName("meatRecommend")
val meatRecommend: String? = "",
@SerializedName("oil")
val oil: String? = "",
@SerializedName("salt")
val salt: String? = "",
@SerializedName("soya")
val soya: String? = "",
@SerializedName("soyaRecommend")
val soyaRecommend: String? = "",
@SerializedName("sugar")
val sugar: String? = "",
@SerializedName("vegetable")
val vegetable: String? = "",
@SerializedName("vegetableRecommend")
val vegetableRecommend: String? = ""
) : Parcelable { ) : 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 fun fruitsValue(): Double =
data class StFoodInfoMaterial( if (TextUtils.isEmpty(fruits))
@SerializedName("ash") 0.0
val ash: Double? = 0.0, else fruits!!.toDouble()
@SerializedName("avitE")
val avitE: Double? = 0.0,
@SerializedName("ca")
val ca: Double? = 0.0,
@SerializedName("cho")
val cho: Double? = 0.0,
@SerializedName("cholesterol")
val cholesterol: Double? = 0.0,
@SerializedName("cu")
val cu: Double? = 0.0,
@SerializedName("delFlag")
val delFlag: String? = "",
@SerializedName("dietFiber")
val dietFiber: Double? = 0.0,
@SerializedName("elementI")
val elementI: Double? = 0.0,
@SerializedName("elementK")
val elementK: String? = "",
@SerializedName("elementP")
val elementP: String? = "",
@SerializedName("energyKcal")
val energyKcal: Double? = 0.0,
@SerializedName("energyKj")
val energyKj: Double? = 0.0,
@SerializedName("fat")
val fat: Double? = 0.0,
@SerializedName("fe")
val fe: Double? = 0.0,
@SerializedName("folate")
val folate: Double? = 0.0,
@SerializedName("foodId")
val foodId: String? = "",
@SerializedName("foodWeight")
val foodWeight: String? = "",
@SerializedName("historyStatus")
val historyStatus: String? = "",
@SerializedName("id")
val id: String? = "",
@SerializedName("isSync")
val isSync: String? = "",
@SerializedName("isSyncCopy")
val isSyncCopy: String? = "",
@SerializedName("mg")
val mg: Double? = 0.0,
@SerializedName("mn")
val mn: Double? = 0.0,
@SerializedName("na")
val na: Double? = 0.0,
@SerializedName("naicin")
val naicin: Double? = 0.0,
@SerializedName("protein")
val protein: Double? = 0.0,
@SerializedName("retionl")
val retionl: Double? = 0.0,
@SerializedName("riboflavin")
val riboflavin: Double? = 0.0,
@SerializedName("se")
val se: Double? = 0.0,
@SerializedName("thiamin")
val thiamin: Double? = 0.0,
@SerializedName("totCarotene")
val totCarotene: Double? = 0.0,
@SerializedName("vitA")
val vitA: Double? = 0.0,
@SerializedName("vitB12")
val vitB12: Double? = 0.0,
@SerializedName("vitB6")
val vitB6: Double? = 0.0,
@SerializedName("vitC")
val vitC: Double? = 0.0,
@SerializedName("vitE")
val vitE: Double? = 0.0,
@SerializedName("water")
val water: Double? = 0.0,
@SerializedName("zn")
val zn: Double? = 0.0
) : Parcelable
@Parcelize fun grainValue(): Double =
data class StFoodInfoPagoda( if (TextUtils.isEmpty(grain))
@SerializedName("aquatic") 0.0
val aquatic: String? = "", else grain!!.toDouble()
@SerializedName("birds")
val birds: String? = "",
@SerializedName("delFlag")
val delFlag: String? = "",
@SerializedName("egg")
val egg: String? = "",
@SerializedName("foodId")
val foodId: String? = "",
@SerializedName("fruits")
val fruits: String? = "",
@SerializedName("grain")
val grain: String? = "",
@SerializedName("id")
val id: String? = "",
@SerializedName("isSync")
val isSync: String? = "",
@SerializedName("isSyncCopy")
val isSyncCopy: String? = "",
@SerializedName("livestock")
val livestock: String? = "",
@SerializedName("milk")
val milk: String? = "",
@SerializedName("nuts")
val nuts: String? = "",
@SerializedName("oil")
val oil: String? = "",
@SerializedName("potato")
val potato: String? = "",
@SerializedName("salt")
val salt: String? = "",
@SerializedName("soya")
val soya: String? = "",
@SerializedName("sugar")
val sugar: String? = "",
@SerializedName("vegetable")
val vegetable: String? = ""
) : Parcelable
@Parcelize fun vegetableValue(): Double =
data class StFoodInfoPagodaAPPVO( if (TextUtils.isEmpty(vegetable))
@SerializedName("fruits") 0.0
val fruits: String? = "", else vegetable!!.toDouble()
@SerializedName("fruitsRecommend")
val fruitsRecommend: String? = "",
@SerializedName("grain")
val grain: String? = "",
@SerializedName("grainRecommend")
val grainRecommend: String? = "",
@SerializedName("meat")
val meat: String? = "",
@SerializedName("meatRecommend")
val meatRecommend: String? = "",
@SerializedName("oil")
val oil: String? = "",
@SerializedName("salt")
val salt: String? = "",
@SerializedName("soya")
val soya: String? = "",
@SerializedName("soyaRecommend")
val soyaRecommend: String? = "",
@SerializedName("sugar")
val sugar: String? = "",
@SerializedName("vegetable")
val vegetable: String? = "",
@SerializedName("vegetableRecommend")
val vegetableRecommend: String? = ""
) : Parcelable {
fun fruitsValue(): Double = fun meatValue(): Double =
if (TextUtils.isEmpty(fruits)) if (TextUtils.isEmpty(meat))
0.0 0.0
else fruits!!.toDouble() else meat!!.toDouble()
}
fun grainValue(): Double = //@Parcelize
if (TextUtils.isEmpty(grain)) //data class StFoodInfoSetting(
0.0 // @SerializedName("addFoodWeight")
else grain!!.toDouble() // 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
fun vegetableValue(): Double = //@Parcelize
if (TextUtils.isEmpty(vegetable)) //data class StFoodInfoSpecification(
0.0 // @SerializedName("bowlPlateWeight")
else vegetable!!.toDouble() // val bowlPlateWeight: Double? = 0.0,
// @SerializedName("defaultStatus")
fun meatValue(): Double = // val defaultStatus: String? = "",
if (TextUtils.isEmpty(meat)) // @SerializedName("delFlag")
0.0 // val delFlag: String? = "",
else meat!!.toDouble() // @SerializedName("foodId")
} // val foodId: String? = "",
// @SerializedName("id")
@Parcelize // val id: String? = "",
data class StFoodInfoSetting( // @SerializedName("isSync")
@SerializedName("addFoodWeight") // val isSync: String? = "",
val addFoodWeight: String? = "", // @SerializedName("isSyncCopy")
@SerializedName("bowlPlateWeight") // val isSyncCopy: String? = "",
val bowlPlateWeight: String? = "", // @SerializedName("specId")
@SerializedName("delFlag") // val specId: String? = "",
val delFlag: String? = "", // @SerializedName("specName")
@SerializedName("foodId") // val specName: String? = "",
val foodId: String? = "", // @SerializedName("specPrice")
@SerializedName("foodStatus") // val specPrice: String? = "",
val foodStatus: String? = "", // @SerializedName("specWeight")
@SerializedName("id") // val specWeight: Double? = 0.0
val id: String? = "", //) : Parcelable
@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,45 +63,66 @@ 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(currentPageNo, faceEntity)
if (list.size >= pageSize) {
currentPageNo++
getUserFaceCache(currentPageNo)
} else {
_loadFaceResult.value = true
} }
faceApi.updateFaceData(index, faceEntity)
} }
val nextPageIndex = response.result?.nextPageIndex ?: -1
if (nextPageIndex > 0) { // val nextPageIndex = response.result?.nextPageIndex ?: -1
getUserFaceCache(nextPageIndex) // if (nextPageIndex > 0) {
} else { // getUserFaceCache(nextPageIndex)
_loadFaceResult.value = true // } 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>
+31 -27
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 <!-- <TextView-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:text="未识别出菜品,请重试或手动搜索" <!-- android:text="未识别出菜品,请重试或手动搜索"-->
android:textColor="#FFFF3232" <!-- android:textColor="#FFFF3232"-->
android:textSize="24sp" /> <!-- android:textSize="24sp" />-->
<TextView <!-- <CheckedTextView-->
android:id="@+id/tv_rescan" <!-- android:id="@+id/tv_rescan"-->
android:layout_width="180dp" <!-- android:layout_width="360dp"-->
android:layout_height="wrap_content" <!-- android:layout_height="90dp"-->
android:layout_marginTop="20dp" <!-- android:layout_marginTop="20dp"-->
android:background="@drawable/bg_border_red" <!-- android:background="@drawable/bg_search_food"-->
android:gravity="center" <!-- android:gravity="center"-->
android:padding="10dp" <!-- android:padding="10dp"-->
android:text="重试" <!-- android:text="重试"-->
android:textColor="#FFFF3232" <!-- android:paddingHorizontal="15dp"-->
android:textSize="32sp" /> <!-- android:textAlignment="center"-->
</LinearLayout> <!-- android:textColor="@color/color_search_food"-->
<!-- android:textStyle="bold"-->
<!-- android:checked="true"-->
<!-- android:textSize="32sp" />-->
<!-- </LinearLayout>-->
<TextView <TextView
android:id="@+id/tv_to_search" android:id="@+id/tvToSearch"
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();
} }