增加人脸采集功能;

识别人脸成功后打开有餐盘的第一个柜子;
扫码打开已绑定的柜子,无则打开第一个空柜子并放入餐盘;
设置页面问题优化;
This commit is contained in:
mazengfei
2026-01-14 19:00:20 +08:00
parent 11a0a41e3c
commit aadba7efd5
24 changed files with 1327 additions and 908 deletions
+1
View File
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="zulu-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="zulu-17" project-jdk-type="JavaSDK">
@@ -3,16 +3,20 @@ package com.sw.platecabinet
import android.util.Log import android.util.Log
import com.sw.plate.App import com.sw.plate.App
import com.sw.plate.utils.AppUtil import com.sw.plate.utils.AppUtil
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.CrashHandler import com.sw.platecabinet.utils.CrashHandler
import timber.log.Timber import timber.log.Timber
class MyApp : App() { class MyApp : App() {
companion object { companion object {
const val DEBUG: Boolean = true const val DEBUG: Boolean = true
var instance: MyApp? = null
var plateList: List<EquipmentUserInfo>? = null
} }
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
instance = this
Timber.plant(Timber.DebugTree()) Timber.plant(Timber.DebugTree())
Timber.d("初始化") Timber.d("初始化")
initGlobalData() initGlobalData()
@@ -25,6 +25,7 @@ import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import com.sw.plate.utils.comn.SerialApi import com.sw.plate.utils.comn.SerialApi
import com.sw.plate.utils.comn.SerialPortManager import com.sw.plate.utils.comn.SerialPortManager
import com.sw.platecabinet.MyApp
import com.sw.platecabinet.R import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.dialog.BalanceNotEnoughDialog import com.sw.platecabinet.dialog.BalanceNotEnoughDialog
@@ -33,6 +34,7 @@ import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.UserFaceModel import com.sw.platecabinet.model.response.UserFaceModel
import com.sw.platecabinet.utils.IntervalExecutor import com.sw.platecabinet.utils.IntervalExecutor
import com.sw.platecabinet.utils.PermissionHelper import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.utils.PlateUtils
import com.sw.platecabinet.utils.SpTool import com.sw.platecabinet.utils.SpTool
import com.sw.platecabinet.view.CustomLoadingDialog import com.sw.platecabinet.view.CustomLoadingDialog
import com.sw.platecabinet.viewmodel.SettingViewModel import com.sw.platecabinet.viewmodel.SettingViewModel
@@ -106,7 +108,34 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
* 处理扫描枪数据 * 处理扫描枪数据
*/ */
protected open fun handleScanKeyInfo(scanInfo: String) { protected open fun handleScanKeyInfo(scanInfo: String) {
settingViewModel.findByPlateNumber(plateNumber = scanInfo) // settingViewModel.findByPlateNumber(plateNumber = scanInfo)
var plateNumber = scanInfo
if (scanInfo.length > 6) {
plateNumber = scanInfo.take(6)
}
// ToastUtils.showToast(plateNumber)
var item = MyApp.plateList?.firstOrNull { it.plateNumber == plateNumber }
if (item == null) {
//柜子未关联该餐盘,直接找空位置放入盘子
item = MyApp.plateList?.firstOrNull { it.plateNumber.isNullOrBlank() }
if (item ==null) {
//柜子已满
MainActivity.start(context = context, pageType = PageType.PLATE_CABINET_FULL)
return
}
//找到位置,放入餐盘,清除已有id和时间
item.plateNumber = plateNumber
item.faceId = null
item.updateTime = null
PlateUtils.open(this, item.equipmentBoxCode)
return
}
//放入餐盘,清除已有id和时间
item.plateNumber = plateNumber
item.faceId = null
item.updateTime = null
PlateUtils.open(this, item.equipmentBoxCode)
SpTool.savePlateData(MyApp.plateList!!)
} }
override fun dispatchKeyEvent(event: KeyEvent): Boolean { override fun dispatchKeyEvent(event: KeyEvent): Boolean {
@@ -279,7 +308,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
lifecycleScope.launch { lifecycleScope.launch {
viewModel.currentUserInfo.collect { viewModel.currentUserInfo.collect {
if (it == null) return@collect if (it == null) return@collect
it.showBalanceNotEnoughDialog = true // it.showBalanceNotEnoughDialog = true
handleLoginSuccess(it, false) handleLoginSuccess(it, false)
} }
} }
@@ -329,57 +358,57 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
* @param isAdmin true 管理员 执行绑盘此操作 false 用户,提示错误 * @param isAdmin true 管理员 执行绑盘此操作 false 用户,提示错误
*/ */
open fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) { open fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) {
Timber.d("handleLoginSuccess isAdmin = $isAdmin") // Timber.d("handleLoginSuccess isAdmin = $isAdmin")
equipmentUserInfo.isIntercept = false // equipmentUserInfo.isIntercept = false
val cardBalance = equipmentUserInfo.cardBalance ?: 0.toDouble() // val cardBalance = equipmentUserInfo.cardBalance ?: 0.toDouble()
val balanceIsNotEnough = cardBalance <= 0.toDouble() // val balanceIsNotEnough = cardBalance <= 0.toDouble()
if (balanceIsNotEnough && equipmentUserInfo.showBalanceNotEnoughDialog) { // if (balanceIsNotEnough && equipmentUserInfo.showBalanceNotEnoughDialog) {
//提示余额不足弹窗 // //提示余额不足弹窗
equipmentUserInfo.isIntercept = true // equipmentUserInfo.isIntercept = true
BalanceNotEnoughDialog(this).show() // BalanceNotEnoughDialog(this).show()
return // return
} // }
viewModel.resetUserInfo() // viewModel.resetUserInfo()
// if (equipmentUserInfo.isOtherEquipment()) { //// if (equipmentUserInfo.isOtherEquipment()) {
//// MainActivity.start(
//// context,
//// pageType = PageType.PLATE_TIP,
//// equipmentUserInfo = equipmentUserInfo,
//// isAdmin
//// )
//// return
//// }
// if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) {
// SerialApi.openPlate(
// equipmentUserInfo.equipmentBoxCode!!.toInt(),
// object : SerialPortManager.SendCallback {
// override fun onSuccess() {
// MainActivity.start(
// context,
// pageType = PageType.PLATE_TIP,
// isAdmin = isAdmin
// )
// }
//
// override fun onFail(e: Exception?) {
// ToastUtils.showToast("柜门打开失败")
// }
// })
// } else {
// if (isAdmin) {
// settingViewModel.getEquipmentList {
// loadEquipmentList(it)
// }
// } else {
// Timber.d("无餐盘信息")
// MainActivity.start( // MainActivity.start(
// context, // context,
// pageType = PageType.PLATE_TIP, // pageType = PageType.PLATE_TIP,
// equipmentUserInfo = equipmentUserInfo, // equipmentUserInfo = equipmentUserInfo,
// isAdmin // isAdmin = isAdmin
// ) // )
// return
// } // }
if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) { // }
SerialApi.openPlate(
equipmentUserInfo.equipmentBoxCode!!.toInt(),
object : SerialPortManager.SendCallback {
override fun onSuccess() {
MainActivity.start(
context,
pageType = PageType.PLATE_TIP,
isAdmin = isAdmin
)
}
override fun onFail(e: Exception?) {
ToastUtils.showToast("柜门打开失败")
}
})
} else {
if (isAdmin) {
settingViewModel.getEquipmentList {
loadEquipmentList(it)
}
} else {
Timber.d("无餐盘信息")
MainActivity.start(
context,
pageType = PageType.PLATE_TIP,
equipmentUserInfo = equipmentUserInfo,
isAdmin = isAdmin
)
}
}
} }
override fun onDestroy() { override fun onDestroy() {
@@ -407,7 +436,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
private var faceTimestamp = 0L private var faceTimestamp = 0L
private fun getFaceIncrementList() { private fun getFaceIncrementList() {
val timestamp = SpTool.getLastFaceTimestamp() val timestamp = SpTool.lastFaceTimestamp
if (timestamp == 0L) { if (timestamp == 0L) {
return return
} }
@@ -422,15 +451,15 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
} }
updateFaceData(list) updateFaceData(list)
if (list.size >= settingViewModel.PAGE_SIZE) { if (list.size >= settingViewModel.PAGE_SIZE) {
faceTimestamp = list.last().faceUpdateTimestamp?:0 faceTimestamp = list.last().faceUpdateTimestamp ?: 0
taskPageNo++ taskPageNo++
getFaceIncrementList() getFaceIncrementList()
return@runOnUiThread return@runOnUiThread
} }
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
faceTimestamp = list.last().faceUpdateTimestamp?:0 faceTimestamp = list.last().faceUpdateTimestamp ?: 0
} }
SpTool.setLastFaceTimestamp(faceTimestamp) SpTool.lastFaceTimestamp = faceTimestamp
} }
} }
} }
@@ -6,10 +6,13 @@ import androidx.activity.viewModels
import com.sw.plate.utils.AppUtil import com.sw.plate.utils.AppUtil
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import com.sw.platecabinet.GlobalData import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.MyApp
import com.sw.platecabinet.databinding.ActivityDeviceInitBinding import com.sw.platecabinet.databinding.ActivityDeviceInitBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.ext.gone import com.sw.platecabinet.ext.gone
import com.sw.platecabinet.ext.invisible import com.sw.platecabinet.ext.invisible
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.SpTool
import com.sw.platecabinet.viewmodel.SettingViewModel import com.sw.platecabinet.viewmodel.SettingViewModel
/** /**
@@ -45,6 +48,7 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
// binding.root.postDelayed({ // binding.root.postDelayed({
// goLoginActivity() // goLoginActivity()
// }, 1000) // }, 1000)
initPlateList()
showWaitingDialog("加载中……") showWaitingDialog("加载中……")
viewModel.getDeviceConfig { deviceConfig -> viewModel.getDeviceConfig { deviceConfig ->
runOnUiThread { runOnUiThread {
@@ -88,4 +92,23 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
} }
private fun initPlateList() {
// SpTool.putString(SpTool.PLATE_BOX_DATA, "")
var list = SpTool.getPlateData()
if (list.isNullOrEmpty()) {
list = mutableListOf()
repeat(22) { index ->
list.add(
EquipmentUserInfo(
equipmentBoxCode = "${index + 1}",
// faceId = null,
// plateNumber = if (index == 4) "011075" else null,
// updateTime = null
)
)
}
}
MyApp.plateList = list
}
} }
@@ -7,13 +7,21 @@ import android.hardware.Camera
import android.os.Build import android.os.Build
import android.os.CountDownTimer import android.os.CountDownTimer
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.util.Log
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import com.arcsoft.face.ErrorInfo import com.arcsoft.face.ErrorInfo
import com.google.gson.Gson
import com.sw.inbound.utils.DateTimeUtils
import com.sw.inbound.utils.GsonUtils
import com.sw.plate.App
import com.sw.plate.utils.Base64
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.ConfigUtil import com.sw.plate.utils.arcface.ConfigUtil
import com.sw.plate.utils.arcface.ErrorCodeUtil import com.sw.plate.utils.arcface.ErrorCodeUtil
@@ -24,17 +32,31 @@ import com.sw.plate.utils.arcface.PreviewConfig
import com.sw.plate.utils.arcface.camera.CameraListener import com.sw.plate.utils.arcface.camera.CameraListener
import com.sw.plate.utils.arcface.camera.DualCameraHelper import com.sw.plate.utils.arcface.camera.DualCameraHelper
import com.sw.plate.utils.arcface.face.constants.LivenessType import com.sw.plate.utils.arcface.face.constants.LivenessType
import com.sw.plate.utils.arcface.face.model.CompareResult
import com.sw.plate.utils.arcface.face.model.FacePreviewInfo import com.sw.plate.utils.arcface.face.model.FacePreviewInfo
import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration
import com.sw.plate.utils.arcface.faceserver.FaceServer import com.sw.plate.utils.arcface.facedb.FaceDatabase
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
import com.sw.plate.utils.arcface.model.UserFaceInfo
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_READY
import com.sw.platecabinet.MyApp
import com.sw.platecabinet.R import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.ext.gone
import com.sw.platecabinet.ext.invisible
import com.sw.platecabinet.ext.visible
import com.sw.platecabinet.model.request.BindParam
import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.network.task.TaskManager import com.sw.platecabinet.utils.IntervalExecutor
import com.sw.platecabinet.utils.PermissionHelper import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.utils.PlateUtils
import com.sw.platecabinet.utils.SpTool
import com.sw.platecabinet.utils.countDownByFlow
import com.sw.platecabinet.viewmodel.SettingViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.runBlocking
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
@@ -64,6 +86,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
} }
companion object { companion object {
private const val TAG = "LoginByFaceActivity"
private var instance: LoginByFaceActivity? = null private var instance: LoginByFaceActivity? = null
fun goInitActivity() { fun goInitActivity() {
@@ -82,17 +105,26 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
recognizeViewModel.setDrawRectInfoTextValue(true) recognizeViewModel.setDrawRectInfoTextValue(true)
//viewModel.generateToken() //viewModel.generateToken()
// viewModel.activeEngine() // viewModel.activeEngine()
viewModel.getUserFaceCache()
binding.llToPwd.setOnClickListener { // TODO: 暂时注释人脸接口数据,测试本地采集
val intent = Intent(this, LoginByPwdActivity::class.java) // viewModel.getUserFaceCache()
startActivity(intent) // Thread {
} // val faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
// faceDao.deleteAll()
// faceDao.resetId()
// }.start()
// TODO: 测试请求
TaskManager.startTask() // binding.llToPwd.setOnClickListener {
// val intent = Intent(this, LoginByPwdActivity::class.java)
// startActivity(intent)
// }
// TaskManager.startTask()
EventBus.getDefault().register(this) EventBus.getDefault().register(this)
binding.btnCollectFace.setOnClickListener { collectFace() }
} }
private fun checkCameraPermission() { private fun checkCameraPermission() {
@@ -131,7 +163,11 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
private fun initArcViewModel() { private fun initArcViewModel() {
recognizeViewModel.setLiveType(livenessType) recognizeViewModel.setLiveType(livenessType)
recognizeViewModel.prepareRegister()
recognizeViewModel.setOnRegisterFinishedCallback { facePreviewInfo, userFaceInfo ->
this.userFaceInfo = userFaceInfo
Log.d(TAG, "initArcViewModel: userFaceInfo == null : ${userFaceInfo == null}")
}
recognizeViewModel.ftInitCode.observe(this, Observer { ftInitCode: Int? -> recognizeViewModel.ftInitCode.observe(this, Observer { ftInitCode: Int? ->
if (ftInitCode != ErrorInfo.MOK) { if (ftInitCode != ErrorInfo.MOK) {
val error: String? = getString( val error: String? = getString(
@@ -171,9 +207,19 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
Timber.i("recognizeNotice observe notice = $notice") Timber.i("recognizeNotice observe notice = $notice")
}) })
recognizeViewModel.recognizeUserId.observe(this, Observer { userId: String? -> recognizeViewModel.recognizeUserId.observe(this, Observer { result: CompareResult? ->
Timber.i("recognizeUserId observe userId = $userId") Timber.i("recognizeUserId observe userId = ${result?.faceEntity?.userName}")
viewModel.getUserInfoById(memberId = userId) currentUserId = result?.faceEntity?.userName
// viewModel.getUserInfoById(memberId = userId)
//ToastUtils.showToast(userId)
// if (!currentUserId.isNullOrBlank()) {
//// ToastUtils.showToast("您已采集过人脸信息")
// return@Observer
// }
if (currentPlateInfo?.faceId == currentUserId) {
return@Observer
}
openPlate(currentUserId)
}) })
recognizeViewModel.drawRectInfoText.observe(this, Observer { info -> recognizeViewModel.drawRectInfoText.observe(this, Observer { info ->
@@ -181,6 +227,69 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}) })
} }
// private val settingViewModel by viewModels<SettingViewModel>()
/**
* 查询餐盘数据
*/
private fun getPlateData(block: (List<EquipmentUserInfo>) -> Unit) {
MyApp.plateList?.let {
block(it)
}
// settingViewModel.getEquipmentList { items ->
// block(items)
// }
}
private var currentPlateInfo: EquipmentUserInfo? = null
/**
* 打开餐盘柜
*/
private fun openPlate(userId: String?) {
getPlateData { items ->
Log.d(TAG, "openPlate: ${Gson().toJson(items)}")
var item = items.firstOrNull { it.faceId == userId }
if (item != null) {
//餐盘已取
ToastUtils.showToast("您已拿过餐盘!")
return@getPlateData
}
// 未查询到当前用户
item = items.firstOrNull { it.plateNumber.isNullOrEmpty().not() }
if (item == null) {
//暂无餐盘
ToastUtils.showToast("暂无餐盘,请联系管理人员!")
return@getPlateData
}
// TODO: 待定如何在设置页面显示plateNumber,可以增加字段处理
item.faceId = userId
item.updateTime = DateTimeUtils.getDateTimeString()
//打开柜子
PlateUtils.open(this, item.equipmentBoxCode)
currentPlateInfo = item
MyApp.plateList = items
SpTool.savePlateData(items)
}
}
// /**
// * 绑定餐盘
// */
// private fun bindPlate(item: EquipmentUserInfo) {
// val bindParam = BindParam(
// equipmentId = item.equipmentId,
// equipmentCode = item.equipmentCode,
// equipmentBoxCode = item.equipmentBoxCode,
// faceId = item.faceId,
// plateNumber = item.plateNumber
// )
// settingViewModel.bindPlate(bindParam) { pair ->
// Log.d(TAG, "openPlate: state:${pair.first},msg:${pair.second.code},${pair.second.msg}")
// }
// }
private fun initArcView() { private fun initArcView() {
//在布局结束后才做初始化操作 //在布局结束后才做初始化操作
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this) binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this)
@@ -198,6 +307,8 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
recognizeViewModel.destroy() recognizeViewModel.destroy()
EventBus.getDefault().unregister(this) EventBus.getDefault().unregister(this)
countDownJob?.cancel()
super.onDestroy() super.onDestroy()
} }
@@ -320,6 +431,10 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
if (facePreviewInfoList != null && rgbFaceRectTransformer != null) { if (facePreviewInfoList != null && rgbFaceRectTransformer != null) {
drawPreviewInfo(facePreviewInfoList) drawPreviewInfo(facePreviewInfoList)
} }
if (facePreviewInfoList.isNullOrEmpty()) {
currentPlateInfo = null
currentUserId = null
}
recognizeViewModel.clearLeftFace(facePreviewInfoList) recognizeViewModel.clearLeftFace(facePreviewInfoList)
} }
@@ -444,5 +559,100 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
startActivity(intent) startActivity(intent)
} }
private fun collectFace() {
//toast("currentUserId=$currentUserId")
if (currentUserId != null) {
ToastUtils.showToast("您已采集过人脸信息")
return
}
currentUserId = null
userFaceInfo = null
recognizeViewModel.updateRegisterStatus(REGISTER_STATUS_READY)
//showWaitingDialog("人脸信息中……")
// binding.tvFaceTip.gone()
binding.btnCollectFace.invisible()
binding.layoutState.visible()
binding.pbCollectLoading.visible()
binding.tvCollectState.text = "采集中......"
getFaceData { faceData ->
Log.d("LoginByFaceActivity", "faceData: $faceData")
runOnUiThread {
//hideWaitingDialog()
//toast("人脸信息已采集")
binding.pbCollectLoading.gone()
//binding.tvCollectState.text = "采集完成"
userFaceInfo = null
countDown()
}
// sendFaceData(faceData)
saveFaceInfo(faceData)
}
}
private fun getFaceData(block: (String) -> Unit) {
runBlocking {
job = executor.startIntervalTask(5) {
// if (currentUserId != null && currentUserId!!.isNotBlank()) {
// toast("您已采集过人脸信息")
// return@startIntervalTask
// }
if (userFaceInfo == null) {
return@startIntervalTask
}
val faceData = Base64.encode(userFaceInfo!!.faceFeature!!.featureData)
block(faceData)
job?.cancel()
}
}
}
private var userFaceInfo: UserFaceInfo? = null
private var countDownJob: Job? = null
private var job: Job? = null
val executor = IntervalExecutor()
private var currentUserId: String? = null
private fun countDown() {
countDownJob = countDownByFlow(
total = 3,
scope = lifecycleScope,
onStart = {
binding.tvCollectState.text = "采集完成(3s"
},
onTick = { seconds ->
binding.tvCollectState.text = "采集完成(${seconds}s"
},
onFinish = {
//binding.tvCollectState.text = "采集完成"
currentUserId = null
binding.layoutState.invisible()
// binding.tvFaceTip.visible()
binding.btnCollectFace.visible()
}
)
}
private fun saveFaceInfo(faceData: String) {
Thread {
try {
val tempId = "${System.currentTimeMillis()}"
val faceEntity = FaceEntity(
tempId,
null,
Base64.decode(faceData)
).also {
it.userType = "2"
}
FaceDatabase.getInstance(this).faceDao().insert(faceEntity)
recognizeViewModel.refreshFaceList();
runOnUiThread {
ToastUtils.showToast("你的人脸信息已采集")
}
} catch (e: Exception) {
e.printStackTrace()
}
}.start()
}
} }
@@ -1,62 +1,62 @@
package com.sw.platecabinet.activity //package com.sw.platecabinet.activity
//
import android.content.Intent //import android.content.Intent
import com.sw.plate.utils.ToastUtils //import com.sw.plate.utils.ToastUtils
import com.sw.platecabinet.databinding.ActivityLoginByPwdBinding //import com.sw.platecabinet.databinding.ActivityLoginByPwdBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding //import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.dialog.BalanceNotEnoughDialog //import com.sw.platecabinet.dialog.BalanceNotEnoughDialog
import com.sw.platecabinet.model.request.LoginParam //import com.sw.platecabinet.model.request.LoginParam
import com.sw.platecabinet.model.response.EquipmentUserInfo //import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.KeyboardUtils //import com.sw.platecabinet.utils.KeyboardUtils
//
/** ///**
* 密码登录 // * 密码登录
*/ // */
class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() { //class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
//
override fun inflateViewBinding(): ActivityLoginByPwdBinding { // override fun inflateViewBinding(): ActivityLoginByPwdBinding {
return ActivityLoginByPwdBinding.inflate(layoutInflater) // return ActivityLoginByPwdBinding.inflate(layoutInflater)
} // }
//
override fun inflateTitleBinding(): ItemTitleTimeBinding { // override fun inflateTitleBinding(): ItemTitleTimeBinding {
return binding.includeHeader // return binding.includeHeader
} // }
//
override fun initialize() { // override fun initialize() {
binding.btnLogin.setOnClickListener { // binding.btnLogin.setOnClickListener {
val phone = binding.etPhone.text.toString() // val phone = binding.etPhone.text.toString()
val pwd = binding.etPwd.text.toString() // val pwd = binding.etPwd.text.toString()
if (phone.isEmpty() || pwd.isEmpty()) { // if (phone.isEmpty() || pwd.isEmpty()) {
ToastUtils.showToast("手机或校验码不能为空") // ToastUtils.showToast("手机或校验码不能为空")
return@setOnClickListener // return@setOnClickListener
} // }
val loginParam = LoginParam( // val loginParam = LoginParam(
//equipmentId = equipmentId, // //equipmentId = equipmentId,
phone = phone, // phone = phone,
password = pwd // password = pwd
) // )
viewModel.loginWithPwd(loginParam) // viewModel.loginWithPwd(loginParam)
KeyboardUtils.hideKeyboard(this) // KeyboardUtils.hideKeyboard(this)
} // }
binding.tvFaceRec.setOnClickListener { // binding.tvFaceRec.setOnClickListener {
val intent = Intent(this, LoginByFaceActivity::class.java) // val intent = Intent(this, LoginByFaceActivity::class.java)
startActivity(intent) // startActivity(intent)
} // }
} // }
//
override fun onResume() { // override fun onResume() {
super.onResume() // super.onResume()
viewModel.resetUserInfo() // viewModel.resetUserInfo()
} // }
//
override fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) { // override fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) {
super.handleLoginSuccess(equipmentUserInfo, isAdmin) // super.handleLoginSuccess(equipmentUserInfo, isAdmin)
// val cardBalance = equipmentUserInfo.cardBalance?:0.toDouble() //// val cardBalance = equipmentUserInfo.cardBalance?:0.toDouble()
// val balanceIsNotEnough = cardBalance <= 0.toDouble() //// val balanceIsNotEnough = cardBalance <= 0.toDouble()
if (equipmentUserInfo.isIntercept) { // if (equipmentUserInfo.isIntercept) {
return // return
} // }
LoginByFaceActivity.goInitActivity() // LoginByFaceActivity.goInitActivity()
finish() // finish()
} // }
} //}
@@ -2,14 +2,13 @@ package com.sw.platecabinet.activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import com.sw.platecabinet.MyApp
import com.sw.platecabinet.R import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ActivityMainBinding import com.sw.platecabinet.databinding.ActivityMainBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.fragment.BindPlateFragment
import com.sw.platecabinet.fragment.PlateCabinetFullFragment import com.sw.platecabinet.fragment.PlateCabinetFullFragment
import com.sw.platecabinet.fragment.PlateOpenFragment import com.sw.platecabinet.fragment.PlateOpenFragment
import com.sw.platecabinet.fragment.SettingListFragment import com.sw.platecabinet.fragment.SettingListFragment
import com.sw.platecabinet.fragment.UnBindPlateFragment
import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.FragmentHelper import com.sw.platecabinet.utils.FragmentHelper
@@ -58,12 +57,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
fragmentHelper = FragmentHelper(supportFragmentManager, R.id.fragment_container) fragmentHelper = FragmentHelper(supportFragmentManager, R.id.fragment_container)
val page = when (pageType) { val page = when (pageType) {
PageType.SETTING_LIST -> SettingListFragment() PageType.SETTING_LIST -> SettingListFragment()
PageType.BIND_PLATE -> BindPlateFragment.newInstance(equipmentUserInfo) // PageType.BIND_PLATE -> BindPlateFragment.newInstance(equipmentUserInfo)
PageType.PLATE_TIP -> PlateOpenFragment.newInstance(equipmentUserInfo, isAdmin) PageType.PLATE_TIP -> PlateOpenFragment.newInstance(equipmentUserInfo, isAdmin)
PageType.UNBIND_PLATE -> UnBindPlateFragment.newInstance(equipmentUserInfo) // PageType.UNBIND_PLATE -> UnBindPlateFragment.newInstance(equipmentUserInfo)
PageType.PLATE_CABINET_FULL -> PlateCabinetFullFragment() PageType.PLATE_CABINET_FULL -> PlateCabinetFullFragment()
else -> null
}
page?.let {
fragmentHelper.addFragment(it)
} }
fragmentHelper.addFragment(page)
} }
override fun onLeftDoubleClick() { override fun onLeftDoubleClick() {
@@ -1,57 +1,57 @@
package com.sw.platecabinet.activity //package com.sw.platecabinet.activity
//
import android.graphics.Color //import android.graphics.Color
import android.view.Gravity //import android.view.Gravity
import android.view.ViewGroup //import android.view.ViewGroup
import androidx.core.graphics.drawable.toDrawable //import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.WindowCompat //import androidx.core.view.WindowCompat
import com.sw.platecabinet.GlobalKey //import com.sw.platecabinet.GlobalKey
import com.sw.platecabinet.databinding.ActivityUnbindDialogBinding //import com.sw.platecabinet.databinding.ActivityUnbindDialogBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding //import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.ext.dp //import com.sw.platecabinet.ext.dp
import com.sw.platecabinet.model.response.EquipmentUserInfo //import com.sw.platecabinet.model.response.EquipmentUserInfo
//
/** ///**
* 解绑确认弹窗界面 // * 解绑确认弹窗界面
*/ // */
class UnBindDialogActivity : BaseActivity<ActivityUnbindDialogBinding>() { //class UnBindDialogActivity : BaseActivity<ActivityUnbindDialogBinding>() {
private var equipmentUserInfo: EquipmentUserInfo? = null // private var equipmentUserInfo: EquipmentUserInfo? = null
//
override fun inflateViewBinding(): ActivityUnbindDialogBinding { // override fun inflateViewBinding(): ActivityUnbindDialogBinding {
return ActivityUnbindDialogBinding.inflate(layoutInflater) // return ActivityUnbindDialogBinding.inflate(layoutInflater)
} // }
//
override fun inflateTitleBinding(): ItemTitleTimeBinding? { // override fun inflateTitleBinding(): ItemTitleTimeBinding? {
return null // return null
} // }
//
override fun initialize() { // override fun initialize() {
window?.apply { // window?.apply {
WindowCompat.setDecorFitsSystemWindows(this, false) // WindowCompat.setDecorFitsSystemWindows(this, false)
setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) // setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
//
attributes = attributes.apply { // attributes = attributes.apply {
y = 314.dp // y = 314.dp
width = (context.resources.displayMetrics.widthPixels * 0.8).toInt() // width = (context.resources.displayMetrics.widthPixels * 0.8).toInt()
height = ViewGroup.LayoutParams.MATCH_PARENT // height = ViewGroup.LayoutParams.MATCH_PARENT
gravity = Gravity.CENTER // gravity = Gravity.CENTER
} // }
} // }
equipmentUserInfo = // equipmentUserInfo =
intent.getParcelableExtra<EquipmentUserInfo>(GlobalKey.PARAM_EQUIPMENT_INFO) // intent.getParcelableExtra<EquipmentUserInfo>(GlobalKey.PARAM_EQUIPMENT_INFO)
if (equipmentUserInfo == null) return // if (equipmentUserInfo == null) return
binding.tvTipInfo.text = "即将解除【${equipmentUserInfo!!.name}】的餐盘" // binding.tvTipInfo.text = "即将解除【${equipmentUserInfo!!.name}】的餐盘"
binding.tvCancel.setOnClickListener { // binding.tvCancel.setOnClickListener {
finish() // finish()
} // }
binding.tvConfirm.setOnClickListener { // binding.tvConfirm.setOnClickListener {
setResult(RESULT_OK) // setResult(RESULT_OK)
finish() // finish()
} // }
} // }
//
override fun finish() { // override fun finish() {
super.finish() // super.finish()
overridePendingTransition(0, 0) // 确保退出也无动画 // overridePendingTransition(0, 0) // 确保退出也无动画
} // }
} //}
@@ -1,317 +1,317 @@
package com.sw.platecabinet.fragment //package com.sw.platecabinet.fragment
//
import android.annotation.SuppressLint //import android.annotation.SuppressLint
import android.os.Bundle //import android.os.Bundle
import android.text.Editable //import android.text.Editable
import android.text.TextUtils //import android.text.TextUtils
import android.text.TextWatcher //import android.text.TextWatcher
import android.view.inputmethod.EditorInfo //import android.view.inputmethod.EditorInfo
import androidx.fragment.app.viewModels //import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope //import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager //import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager //import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView //import androidx.recyclerview.widget.RecyclerView
import com.sw.plate.utils.ToastUtils //import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.comn.SerialApi //import com.sw.plate.utils.comn.SerialApi
import com.sw.plate.utils.comn.SerialPortManager //import com.sw.plate.utils.comn.SerialPortManager
import com.sw.platecabinet.R //import com.sw.platecabinet.R
import com.sw.platecabinet.activity.MainActivity //import com.sw.platecabinet.activity.MainActivity
import com.sw.platecabinet.activity.PageType //import com.sw.platecabinet.activity.PageType
import com.sw.platecabinet.adapter.GenericItemAdapter //import com.sw.platecabinet.adapter.GenericItemAdapter
import com.sw.platecabinet.adapter.GridSpacingItemDecoration //import com.sw.platecabinet.adapter.GridSpacingItemDecoration
import com.sw.platecabinet.adapter.dpToPx //import com.sw.platecabinet.adapter.dpToPx
import com.sw.platecabinet.databinding.FragmentBindPlateBinding //import com.sw.platecabinet.databinding.FragmentBindPlateBinding
import com.sw.platecabinet.databinding.ItemSearchUserInfoBinding //import com.sw.platecabinet.databinding.ItemSearchUserInfoBinding
import com.sw.platecabinet.dialog.UserBindRemindDialog //import com.sw.platecabinet.dialog.UserBindRemindDialog
import com.sw.platecabinet.ext.maskName //import com.sw.platecabinet.ext.maskName
import com.sw.platecabinet.ext.maskPhone //import com.sw.platecabinet.ext.maskPhone
import com.sw.platecabinet.model.ErrorInfo //import com.sw.platecabinet.model.ErrorInfo
import com.sw.platecabinet.model.request.BindParam //import com.sw.platecabinet.model.request.BindParam
import com.sw.platecabinet.model.response.EquipmentUserInfo //import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.SearchResult //import com.sw.platecabinet.model.response.SearchResult
import com.sw.platecabinet.utils.Debouncer //import com.sw.platecabinet.utils.Debouncer
import com.sw.platecabinet.utils.KeyboardUtils //import com.sw.platecabinet.utils.KeyboardUtils
import com.sw.platecabinet.viewmodel.SettingViewModel //import com.sw.platecabinet.viewmodel.SettingViewModel
import com.sw.platecabinet.viewmodel.UserViewModel //import com.sw.platecabinet.viewmodel.UserViewModel
import kotlinx.coroutines.launch //import kotlinx.coroutines.launch
import timber.log.Timber //import timber.log.Timber
//
/** ///**
* 餐盘柜绑定 // * 餐盘柜绑定
*/ // */
class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>( //class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
FragmentBindPlateBinding::inflate // FragmentBindPlateBinding::inflate
) { //) {
private lateinit var adapter: GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding> // private lateinit var adapter: GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding>
internal val KEY_ACTION_TYPE = "actionType" // internal val KEY_ACTION_TYPE = "actionType"
private var info: EquipmentUserInfo? = null // private var info: EquipmentUserInfo? = null
private var checkedItem: SearchResult.Member? = null // private var checkedItem: SearchResult.Member? = null
private var lastText = "" // private var lastText = ""
private val debouncer = Debouncer(2000) // private val debouncer = Debouncer(2000)
//
private val userViewModel by viewModels<UserViewModel>() // private val userViewModel by viewModels<UserViewModel>()
//
companion object { // companion object {
@JvmStatic // @JvmStatic
fun newInstance(userInfo: EquipmentUserInfo?) = // fun newInstance(userInfo: EquipmentUserInfo?) =
BindPlateFragment().apply { // BindPlateFragment().apply {
arguments = Bundle().apply { // arguments = Bundle().apply {
putParcelable(KEY_ACTION_TYPE, userInfo) // putParcelable(KEY_ACTION_TYPE, userInfo)
}
}
}
@SuppressLint("SetTextI18n")
override fun initialize() {
arguments?.let { args ->
info = args.getParcelable(KEY_ACTION_TYPE)
info?.let {
binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}"
if (!TextUtils.isEmpty(it.plateNumber)) {
// binding.etCode.text = Editable.Factory.getInstance().newEditable(it.plateNumber)
binding.etCode.apply {
setText(it.plateNumber)
setSelection(length())
}
}
}
}
initView()
initListener()
}
private fun initView() {
adapter = createAdapter()
binding.recyclerview.layoutManager = GridLayoutManager(context, 2)
// 添加间距装饰(12dp)
binding.recyclerview.addItemDecoration(
GridSpacingItemDecoration(
spanCount = 2,
spacing = requireContext().dpToPx(6),
includeEdge = false // 包含边缘间距
)
)
binding.recyclerview.adapter = adapter
binding.recyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
val lastVisibleItem = layoutManager.findLastVisibleItemPosition()
val totalItems = layoutManager.itemCount
if (!viewModel.isLoading && viewModel.canLoadMore
&& lastVisibleItem >= totalItems - 3
) {
viewModel.getSearchMemberList(
param = lastText,
pageNum = viewModel.currentPage
)
}
}
})
(activity as MainActivity).registerKeyEventInfo {
// binding.etCode.text.clear()
// binding.etCode.postDelayed({
// binding.etCode.text.clear()
// binding.etCode.text = Editable.Factory.getInstance().newEditable(it)
activity?.runOnUiThread {
if (binding.etUserInfo.isFocused) {
return@runOnUiThread
}
binding.etCode.apply {
if (it.length > 6) {
setText(it.substring(0, 6))
} else {
setText(it)
}
if (length() > 0) {
setSelection(length())
}
}
binding.etUserInfo.requestFocus()
}
// }, 50)
}
}
private fun initListener() {
binding.etCode.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
Timber.d("beforeTextChanged s = ${s.toString()}, start = $start, count = $count, after = $after")
}
override fun onTextChanged(
s: CharSequence?,
start: Int,
before: Int,
count: Int
) {
Timber.d("onTextChanged s = ${s.toString()}, start = $start, count = $count, before = $before")
}
override fun afterTextChanged(s: Editable?) {
Timber.d("afterTextChanged s = ${s.toString()}")
}
})
binding.etUserInfo.setOnEditorActionListener { _, actionId, keyEvent ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
val currentText = binding.etUserInfo.text.toString()
val containsNewlines = currentText.contains('\n') || currentText.contains('\r')
if (containsNewlines) {
Timber.d("非用户主动搜索")
true
}
debouncer.debounce {
// 执行搜索操作
viewModel.getSearchMemberList(param = currentText, pageNum = 1)
// 隐藏键盘
KeyboardUtils.hideKeyboard(requireActivity())
}
true // 表示已处理该事件
} else {
false // 未处理其他动作
}
}
binding.ivSearch.setOnClickListener {
debouncer.debounce {
// 执行搜索操作
viewModel.getSearchMemberList(
param = binding.etUserInfo.text.toString(),
pageNum = 1
)
// 隐藏键盘
KeyboardUtils.hideKeyboard(requireActivity())
}
}
binding.llBind.setOnClickListener {
if (equipmentBoxCode.isNullOrBlank().not()) {
showBindDialog()
return@setOnClickListener
}
if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) {
ToastUtils.showToast("传入的设备信息异常")
return@setOnClickListener
}
val plateNumber = binding.etCode.text.toString()
if (plateNumber.isEmpty()) {
ToastUtils.showToast("请输入餐盘号")
return@setOnClickListener
}
if (checkedItem == null) {
ToastUtils.showToast("请选择要绑定的会员")
return@setOnClickListener
}
if (checkedItem!!.id == null) {
ToastUtils.showToast("选中的会员信息异常")
return@setOnClickListener
}
val bindParam = BindParam(
equipmentId = info?.equipmentId,
equipmentCode = info?.equipmentCode,
equipmentBoxCode = info?.equipmentBoxCode,
faceId = checkedItem?.faceId,
plateNumber = plateNumber
)
viewModel.bindPlate(bindParam) { pair ->
updateBindState(pair)
}
KeyboardUtils.hideKeyboard(requireActivity())
}
binding.tvBack.setOnClickListener { activity?.finish() }
}
/**
* 监听数据变化
*/
override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch {
viewModel.searchMemberList.collect {
adapter.updateData(it)
}
}
// lifecycleScope.launch {
// viewModel.bindStateChange.collect {
// updateBindState(it)
// } // }
// } // }
} // }
//
private fun createAdapter(): GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding> { // @SuppressLint("SetTextI18n")
return GenericItemAdapter( // override fun initialize() {
items = emptyList(), // arguments?.let { args ->
bindingInflater = ItemSearchUserInfoBinding::inflate, // info = args.getParcelable(KEY_ACTION_TYPE)
bindCallback = { item, position -> // info?.let {
this.tvName.text = item.name.maskName() // binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}"
this.tvPhone.text = item.phone.maskPhone() // if (!TextUtils.isEmpty(it.plateNumber)) {
if (item.id != checkedItem?.id) { //// binding.etCode.text = Editable.Factory.getInstance().newEditable(it.plateNumber)
this.llRoot.setBackgroundResource(R.drawable.grid_item_bind) // binding.etCode.apply {
} else { // setText(it.plateNumber)
this.llRoot.setBackgroundResource(R.drawable.grid_item_unbind) // setSelection(length())
} // }
// }
this.llRoot.setOnClickListener { // }
Timber.d("itemClick ${item.name}, position = $position") // }
checkedItem = item // initView()
adapter.notifyDataSetChanged() // initListener()
//TODO 调用接口查询用户是否已绑盘 // }
this@BindPlateFragment.equipmentBoxCode = null //
(activity as? MainActivity)?.showWaitingDialog("查询中,请稍后……") // private fun initView() {
userViewModel.getUserInfoById(memberId = item.faceId) { // adapter = createAdapter()
(activity as? MainActivity)?.hideWaitingDialog() // binding.recyclerview.layoutManager = GridLayoutManager(context, 2)
this@BindPlateFragment.equipmentBoxCode = it?.equipmentBoxCode // // 添加间距装饰(12dp)
} // binding.recyclerview.addItemDecoration(
} // GridSpacingItemDecoration(
} // spanCount = 2,
) // spacing = requireContext().dpToPx(6),
} // includeEdge = false // 包含边缘间距
// )
private var equipmentBoxCode:String? = null // )
// binding.recyclerview.adapter = adapter
private fun showBindDialog() { // binding.recyclerview.addOnScrollListener(object : RecyclerView.OnScrollListener() {
UserBindRemindDialog( // override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
activity = requireActivity(), // super.onScrolled(recyclerView, dx, dy)
content = "您已绑定编号为${equipmentBoxCode}的柜子,请解绑后重试" // val layoutManager = recyclerView.layoutManager as LinearLayoutManager
) // val lastVisibleItem = layoutManager.findLastVisibleItemPosition()
.show() // val totalItems = layoutManager.itemCount
} //
// if (!viewModel.isLoading && viewModel.canLoadMore
private fun updateBindState(pair: Pair<Boolean?, ErrorInfo>){ // && lastVisibleItem >= totalItems - 3
if (pair.first == null) return // 解绑状态过滤 // ) {
val errorInfo = pair.second // viewModel.getSearchMemberList(
if (errorInfo.isSuccess()) { // param = lastText,
if (errorInfo.equipmentUserInfo == null) { // pageNum = viewModel.currentPage
ToastUtils.showToast("数据异常")
return
}
// if (errorInfo.equipmentUserInfo.isOtherEquipment()) {
// MainActivity.start(
// requireContext(),
// pageType = PageType.PLATE_TIP,
// equipmentUserInfo = errorInfo.equipmentUserInfo,
// isAdmin = true
// ) // )
// } else {
SerialApi.openPlate(
errorInfo.equipmentUserInfo.equipmentBoxCode!!.toInt(),
object : SerialPortManager.SendCallback {
override fun onSuccess() {
ToastUtils.showToast("绑定成功")
activity?.finish()
}
override fun onFail(e: Exception?) {
ToastUtils.showToast("绑定失败")
}
})
// } // }
} else { // }
ToastUtils.showToast(errorInfo.msg) // })
} // (activity as MainActivity).registerKeyEventInfo {
} //// binding.etCode.text.clear()
} //// binding.etCode.postDelayed({
//// binding.etCode.text.clear()
//// binding.etCode.text = Editable.Factory.getInstance().newEditable(it)
// activity?.runOnUiThread {
// if (binding.etUserInfo.isFocused) {
// return@runOnUiThread
// }
// binding.etCode.apply {
// if (it.length > 6) {
// setText(it.substring(0, 6))
// } else {
// setText(it)
// }
// if (length() > 0) {
// setSelection(length())
// }
// }
// binding.etUserInfo.requestFocus()
// }
//// }, 50)
// }
// }
//
// private fun initListener() {
// binding.etCode.addTextChangedListener(object : TextWatcher {
// override fun beforeTextChanged(
// s: CharSequence?,
// start: Int,
// count: Int,
// after: Int
// ) {
// Timber.d("beforeTextChanged s = ${s.toString()}, start = $start, count = $count, after = $after")
// }
//
// override fun onTextChanged(
// s: CharSequence?,
// start: Int,
// before: Int,
// count: Int
// ) {
// Timber.d("onTextChanged s = ${s.toString()}, start = $start, count = $count, before = $before")
// }
//
// override fun afterTextChanged(s: Editable?) {
// Timber.d("afterTextChanged s = ${s.toString()}")
// }
// })
// binding.etUserInfo.setOnEditorActionListener { _, actionId, keyEvent ->
// if (actionId == EditorInfo.IME_ACTION_SEARCH) {
// val currentText = binding.etUserInfo.text.toString()
// val containsNewlines = currentText.contains('\n') || currentText.contains('\r')
// if (containsNewlines) {
// Timber.d("非用户主动搜索")
// true
// }
// debouncer.debounce {
// // 执行搜索操作
// viewModel.getSearchMemberList(param = currentText, pageNum = 1)
// // 隐藏键盘
// KeyboardUtils.hideKeyboard(requireActivity())
// }
// true // 表示已处理该事件
// } else {
// false // 未处理其他动作
// }
// }
// binding.ivSearch.setOnClickListener {
// debouncer.debounce {
// // 执行搜索操作
// viewModel.getSearchMemberList(
// param = binding.etUserInfo.text.toString(),
// pageNum = 1
// )
// // 隐藏键盘
// KeyboardUtils.hideKeyboard(requireActivity())
// }
// }
// binding.llBind.setOnClickListener {
// if (equipmentBoxCode.isNullOrBlank().not()) {
// showBindDialog()
// return@setOnClickListener
// }
// if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) {
// ToastUtils.showToast("传入的设备信息异常")
// return@setOnClickListener
// }
// val plateNumber = binding.etCode.text.toString()
// if (plateNumber.isEmpty()) {
// ToastUtils.showToast("请输入餐盘号")
// return@setOnClickListener
// }
// if (checkedItem == null) {
// ToastUtils.showToast("请选择要绑定的会员")
// return@setOnClickListener
// }
// if (checkedItem!!.id == null) {
// ToastUtils.showToast("选中的会员信息异常")
// return@setOnClickListener
// }
// val bindParam = BindParam(
// equipmentId = info?.equipmentId,
// equipmentCode = info?.equipmentCode,
// equipmentBoxCode = info?.equipmentBoxCode,
// faceId = checkedItem?.faceId,
// plateNumber = plateNumber
// )
// viewModel.bindPlate(bindParam) { pair ->
// updateBindState(pair)
// }
// KeyboardUtils.hideKeyboard(requireActivity())
// }
// binding.tvBack.setOnClickListener { activity?.finish() }
// }
//
// /**
// * 监听数据变化
// */
// override fun registerDataChange() {
// super.registerDataChange()
// lifecycleScope.launch {
// viewModel.searchMemberList.collect {
// adapter.updateData(it)
// }
// }
//// lifecycleScope.launch {
//// viewModel.bindStateChange.collect {
//// updateBindState(it)
//// }
//// }
// }
//
// private fun createAdapter(): GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding> {
// return GenericItemAdapter(
// items = emptyList(),
// bindingInflater = ItemSearchUserInfoBinding::inflate,
// bindCallback = { item, position ->
// this.tvName.text = item.name.maskName()
// this.tvPhone.text = item.phone.maskPhone()
// if (item.id != checkedItem?.id) {
// this.llRoot.setBackgroundResource(R.drawable.grid_item_bind)
// } else {
// this.llRoot.setBackgroundResource(R.drawable.grid_item_unbind)
// }
//
// this.llRoot.setOnClickListener {
// Timber.d("itemClick ${item.name}, position = $position")
// checkedItem = item
// adapter.notifyDataSetChanged()
// //TODO 调用接口查询用户是否已绑盘
// this@BindPlateFragment.equipmentBoxCode = null
// (activity as? MainActivity)?.showWaitingDialog("查询中,请稍后……")
// userViewModel.getUserInfoById(memberId = item.faceId) {
// (activity as? MainActivity)?.hideWaitingDialog()
// this@BindPlateFragment.equipmentBoxCode = it?.equipmentBoxCode
// }
// }
// }
// )
// }
//
// private var equipmentBoxCode:String? = null
//
// private fun showBindDialog() {
// UserBindRemindDialog(
// activity = requireActivity(),
// content = "您已绑定编号为${equipmentBoxCode}的柜子,请解绑后重试"
// )
// .show()
// }
//
// private fun updateBindState(pair: Pair<Boolean?, ErrorInfo>){
// if (pair.first == null) return // 解绑状态过滤
// val errorInfo = pair.second
// if (errorInfo.isSuccess()) {
// if (errorInfo.equipmentUserInfo == null) {
// ToastUtils.showToast("数据异常")
// return
// }
//// if (errorInfo.equipmentUserInfo.isOtherEquipment()) {
//// MainActivity.start(
//// requireContext(),
//// pageType = PageType.PLATE_TIP,
//// equipmentUserInfo = errorInfo.equipmentUserInfo,
//// isAdmin = true
//// )
//// } else {
// SerialApi.openPlate(
// errorInfo.equipmentUserInfo.equipmentBoxCode!!.toInt(),
// object : SerialPortManager.SendCallback {
// override fun onSuccess() {
// ToastUtils.showToast("绑定成功")
// activity?.finish()
// }
//
// override fun onFail(e: Exception?) {
// ToastUtils.showToast("绑定失败")
// }
// })
//// }
// } else {
// ToastUtils.showToast(errorInfo.msg)
// }
// }
//}
@@ -41,12 +41,14 @@ class PlateOpenFragment :
binding.tvTitle.text = "暂无餐盘信息" binding.tvTitle.text = "暂无餐盘信息"
binding.tvSubTitle.text = "请联系管理员" binding.tvSubTitle.text = "请联系管理员"
binding.tvTitle.setTextColor(requireContext().getColor(R.color.tip_title_fail)) binding.tvTitle.setTextColor(requireContext().getColor(R.color.tip_title_fail))
} else if (it.isOtherEquipment()) { }
binding.ivType.setImageResource(R.drawable.ic_tip_warn) // else if (it.isOtherEquipment()) {
binding.tvTitle.text = "暂无餐盘信息" // binding.ivType.setImageResource(R.drawable.ic_tip_warn)
binding.tvSubTitle.text = "您的餐盘绑定在${it.equipmentName ?: " "}号柜上" // binding.tvTitle.text = "暂无餐盘信息"
binding.tvTitle.setTextColor(requireContext().getColor(R.color.tip_title_fail)) // binding.tvSubTitle.text = "您的餐盘绑定在${it.equipmentName ?: " "}号柜上"
} else { // binding.tvTitle.setTextColor(requireContext().getColor(R.color.tip_title_fail))
// }
else {
binding.ivType.setImageResource(R.drawable.ic_tip_success) binding.ivType.setImageResource(R.drawable.ic_tip_success)
binding.tvTitle.text = "柜门开启" binding.tvTitle.text = "柜门开启"
binding.tvSubTitle.text = "餐盘取出后请关闭柜门" binding.tvSubTitle.text = "餐盘取出后请关闭柜门"
@@ -11,7 +11,9 @@ import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.comn.SerialApi import com.sw.plate.utils.comn.SerialApi
import com.sw.plate.utils.comn.SerialPortManager import com.sw.plate.utils.comn.SerialPortManager
import com.sw.platecabinet.GlobalData import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.MyApp
import com.sw.platecabinet.R import com.sw.platecabinet.R
import com.sw.platecabinet.activity.BaseActivity
import com.sw.platecabinet.activity.MainActivity import com.sw.platecabinet.activity.MainActivity
import com.sw.platecabinet.activity.PageType import com.sw.platecabinet.activity.PageType
import com.sw.platecabinet.adapter.GenericItemAdapter import com.sw.platecabinet.adapter.GenericItemAdapter
@@ -24,6 +26,8 @@ import com.sw.platecabinet.ext.formatNumber
import com.sw.platecabinet.ext.maskName import com.sw.platecabinet.ext.maskName
import com.sw.platecabinet.model.response.EquipmentUserInfo import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.ListArrangementUtil import com.sw.platecabinet.utils.ListArrangementUtil
import com.sw.platecabinet.utils.PlateUtils
import com.sw.platecabinet.utils.SpTool
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -80,11 +84,23 @@ class SettingListFragment :
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
viewModel.getEquipmentList{ // viewModel.getEquipmentList{
// updateAdapter(it)
// }
MyApp.plateList?.let {
updateAdapter(it) updateAdapter(it)
} }
} }
// private fun getPlateData(block: (List<EquipmentUserInfo>) -> Unit) {
// MyApp.plateList?.let {
// block(it)
// }
//// viewModel.getEquipmentList { items ->
//// block(items)
//// }
// }
private fun createItemAdapter(): GenericItemAdapter<EquipmentUserInfo, ItemBindViewBinding> { private fun createItemAdapter(): GenericItemAdapter<EquipmentUserInfo, ItemBindViewBinding> {
return GenericItemAdapter( return GenericItemAdapter(
items = emptyList(), items = emptyList(),
@@ -110,7 +126,7 @@ class SettingListFragment :
item: EquipmentUserInfo, item: EquipmentUserInfo,
position: Int position: Int
) { ) {
if (item.isPlaceholder() == true) { if (item.isPlaceholder()) {
this.llRoot.isVisible = false this.llRoot.isVisible = false
return return
} }
@@ -133,7 +149,9 @@ class SettingListFragment :
this.llBindInfo.visibility = View.VISIBLE this.llBindInfo.visibility = View.VISIBLE
this.tvUnbind.visibility = View.GONE this.tvUnbind.visibility = View.GONE
this.tvName.text = item.name.maskName() // this.tvName.text = item.name.maskName()
this.tvName.text = item.plateNumber
this.tvLastTime.text = DateTimeUtils.getTimeAgo(date) this.tvLastTime.text = DateTimeUtils.getTimeAgo(date)
} else { } else {
this.llRoot.setBackgroundResource(R.drawable.grid_item_unbind) this.llRoot.setBackgroundResource(R.drawable.grid_item_unbind)
@@ -143,45 +161,25 @@ class SettingListFragment :
this.llBindInfo.visibility = View.GONE this.llBindInfo.visibility = View.GONE
this.tvUnbind.visibility = View.VISIBLE this.tvUnbind.visibility = View.VISIBLE
} }
this.llRoot.setOnClickListener { // this.llRoot.setOnClickListener {
Timber.d("itemClick llRoot ${item.name}, position = $position") //// Timber.d("itemClick llRoot ${item.name}, position = $position")
if (item.isBound()) { // if (item.isBound()) {
MainActivity.start( // MainActivity.start(
requireContext(), // requireContext(),
pageType = PageType.UNBIND_PLATE, // pageType = PageType.UNBIND_PLATE,
equipmentUserInfo = item // equipmentUserInfo = item
) // )
} else { // } else {
MainActivity.start( // MainActivity.start(
requireContext(), // requireContext(),
pageType = PageType.BIND_PLATE, // pageType = PageType.BIND_PLATE,
equipmentUserInfo = item // equipmentUserInfo = item
) // )
} // }
} // }
this.llOpen.setOnClickListener { this.llOpen.setOnClickListener {
Timber.d("itemClick llOpen equipmentBoxCode = ${item.equipmentBoxCode}") // item.faceId = null
val equipmentBoxCode: Int = item.equipmentBoxCode?.toInt() ?: -1 PlateUtils.open(requireActivity(), item.equipmentBoxCode)
if (equipmentBoxCode < 0) {
ToastUtils.showToast("餐盘柜编号错误")
return@setOnClickListener
}
showWaitingDialog("请稍等")
SerialApi.openPlate(equipmentBoxCode, object : SerialPortManager.SendCallback {
override fun onSuccess() {
hideWaitingDialog()
MainActivity.start(
requireContext(),
pageType = PageType.PLATE_TIP,
isAdmin = true
)
}
override fun onFail(e: Exception?) {
hideWaitingDialog()
ToastUtils.showToast("柜门打开失败")
}
})
} }
} }
@@ -1,95 +1,95 @@
package com.sw.platecabinet.fragment //package com.sw.platecabinet.fragment
//
import android.app.Activity //import android.app.Activity
import android.content.Intent //import android.content.Intent
import android.os.Bundle //import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts //import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope //import androidx.lifecycle.lifecycleScope
import com.sw.inbound.utils.DateTimeUtils //import com.sw.inbound.utils.DateTimeUtils
import com.sw.plate.utils.ToastUtils //import com.sw.plate.utils.ToastUtils
import com.sw.platecabinet.GlobalKey //import com.sw.platecabinet.GlobalKey
import com.sw.platecabinet.activity.UnBindDialogActivity //import com.sw.platecabinet.activity.UnBindDialogActivity
import com.sw.platecabinet.databinding.FragmentUnbindPlateBinding //import com.sw.platecabinet.databinding.FragmentUnbindPlateBinding
import com.sw.platecabinet.ext.maskName //import com.sw.platecabinet.ext.maskName
import com.sw.platecabinet.ext.maskPhone //import com.sw.platecabinet.ext.maskPhone
import com.sw.platecabinet.model.ErrorInfo //import com.sw.platecabinet.model.ErrorInfo
import com.sw.platecabinet.model.response.EquipmentUserInfo //import com.sw.platecabinet.model.response.EquipmentUserInfo
import kotlinx.coroutines.launch //import kotlinx.coroutines.launch
//
/** ///**
* 餐盘柜绑定 // * 餐盘柜绑定
*/ // */
class UnBindPlateFragment private constructor() : BaseFragment<FragmentUnbindPlateBinding>( //class UnBindPlateFragment private constructor() : BaseFragment<FragmentUnbindPlateBinding>(
FragmentUnbindPlateBinding::inflate // FragmentUnbindPlateBinding::inflate
) { //) {
internal val ARG_PARAM1 = "param1" // internal val ARG_PARAM1 = "param1"
private var info: EquipmentUserInfo? = null // private var info: EquipmentUserInfo? = null
//
companion object { // companion object {
@JvmStatic // @JvmStatic
fun newInstance(param1: EquipmentUserInfo?) = // fun newInstance(param1: EquipmentUserInfo?) =
UnBindPlateFragment().apply { // UnBindPlateFragment().apply {
arguments = Bundle().apply { // arguments = Bundle().apply {
putParcelable(ARG_PARAM1, param1) // putParcelable(ARG_PARAM1, param1)
}
}
}
private val dialogLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
viewModel.unbindPlate(info?.id) { pair ->
updateBindState(pair)
}
}
}
override fun initialize() {
arguments?.let { args ->
info = args.getParcelable(ARG_PARAM1)
info?.let {
binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}"
binding.tvPlateNumberValue.text = it.plateNumber
binding.tvNameValue.text = it.name.maskName()
binding.tvPhoneValue.text = it.phone.maskPhone()
val timeInfo = DateTimeUtils.parseDateTime(it.updateTime)
val timeAgo = DateTimeUtils.getTimeAgo(timeInfo)
binding.tvUpdateTimeValue.text = timeAgo
}
}
binding.llUnbind.setOnClickListener {
if (info == null) return@setOnClickListener
val intent = Intent(requireContext(), UnBindDialogActivity::class.java).apply {
putExtra(GlobalKey.PARAM_EQUIPMENT_INFO, info)
}
dialogLauncher.launch(intent)
requireActivity().overridePendingTransition(0, 0)
}
binding.tvBack.setOnClickListener {
activity?.finish()
}
}
override fun registerDataChange() {
super.registerDataChange()
// lifecycleScope.launch {
// viewModel.bindStateChange.collect {
// updateBindState(it)
// } // }
// } // }
} // }
private fun updateBindState(pair: Pair<Boolean?, ErrorInfo>){ //
if (pair.first == null) return // 绑定状态过滤 // private val dialogLauncher = registerForActivityResult(
val errorInfo = pair.second // ActivityResultContracts.StartActivityForResult()
if (errorInfo.isSuccess()) { // ) { result ->
ToastUtils.showToast("解绑成功") // if (result.resultCode == Activity.RESULT_OK) {
// viewModel.unbindPlate(info?.id) { pair ->
// updateBindState(pair)
// }
// }
// }
//
// override fun initialize() {
// arguments?.let { args ->
// info = args.getParcelable(ARG_PARAM1)
// info?.let {
// binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}"
// binding.tvPlateNumberValue.text = it.plateNumber
// binding.tvNameValue.text = it.name.maskName()
// binding.tvPhoneValue.text = it.phone.maskPhone()
// val timeInfo = DateTimeUtils.parseDateTime(it.updateTime)
// val timeAgo = DateTimeUtils.getTimeAgo(timeInfo)
// binding.tvUpdateTimeValue.text = timeAgo
// }
// }
// binding.llUnbind.setOnClickListener {
// if (info == null) return@setOnClickListener
// val intent = Intent(requireContext(), UnBindDialogActivity::class.java).apply {
// putExtra(GlobalKey.PARAM_EQUIPMENT_INFO, info)
// }
// dialogLauncher.launch(intent)
// requireActivity().overridePendingTransition(0, 0)
// }
// binding.tvBack.setOnClickListener {
// activity?.finish() // activity?.finish()
// 关闭宿主 Activity // }
requireActivity().finish() // }
requireActivity().overridePendingTransition(0, 0) //
} else { // override fun registerDataChange() {
ToastUtils.showToast(errorInfo.msg) // super.registerDataChange()
} //// lifecycleScope.launch {
} //// viewModel.bindStateChange.collect {
} //// updateBindState(it)
//// }
//// }
// }
// private fun updateBindState(pair: Pair<Boolean?, ErrorInfo>){
// if (pair.first == null) return // 绑定状态过滤
// val errorInfo = pair.second
// if (errorInfo.isSuccess()) {
// ToastUtils.showToast("解绑成功")
//// activity?.finish()
// // 关闭宿主 Activity
// requireActivity().finish()
// requireActivity().overridePendingTransition(0, 0)
// } else {
// ToastUtils.showToast(errorInfo.msg)
// }
// }
//}
@@ -11,19 +11,19 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class EquipmentUserInfo( data class EquipmentUserInfo(
/** // /**
* 主键 // * 主键
*/ // */
val id: Long? = 0, // val id: Long? = 0,
/** // /**
* // *
* 设备Id // * 设备Id
*/ // */
val equipmentId: String? = "", // val equipmentId: String? = "",
/** // /**
* 设备编号 // * 设备编号
*/ // */
var equipmentCode: String? = "", // var equipmentCode: String? = "",
/** /**
* 设备盒子编号 * 设备盒子编号
*/ */
@@ -31,60 +31,60 @@ data class EquipmentUserInfo(
/** /**
* 会员Id * 会员Id
*/ */
val faceId: String? = "", var faceId: String? = "",
/** /**
* 餐盘编号 * 餐盘编号
*/ */
var plateNumber: String? = "", var plateNumber: String? = "",
/** // /**
* 设备名称 // * 设备名称
*/ // */
val equipmentName: String? = "", // val equipmentName: String? = "",
val orderNo: String? = "", // val orderNo: String? = "",
/** /**
* *
* 更新时间 * 更新时间
*/ */
val updateTime: String? = "", var updateTime: String? = "",
val name: String? = "", // val name: String? = "",
val phone: String? = "", // val phone: String? = "",
val faceUrl: String? = "", // val faceUrl: String? = "",
val mealTime: String? = "", // val mealTime: String? = "",
val mealTimeInterval: String? = "", // val mealTimeInterval: String? = "",
val openTime: String? = "", // val openTime: String? = "",
val openTimeInterval: String? = "", // val openTimeInterval: String? = "",
val eatCount: Int? = 0, // val eatCount: Int? = 0,
//
// var cardBalance: Double? = 0.toDouble(),
var cardBalance: Double? = 0.toDouble(), // /**
// * 用于cardBalance后续拦截判断
/** // */
* 用于cardBalance后续拦截判断 // var showBalanceNotEnoughDialog: Boolean = false,
*/ // var isIntercept: Boolean = false
var showBalanceNotEnoughDialog: Boolean = false,
var isIntercept: Boolean = false
) : Parcelable { ) : Parcelable {
/** /**
* 是否已绑定 * 是否已绑定
*/ */
fun isBound(): Boolean { fun isBound(): Boolean {
return faceId != null return faceId.isNullOrBlank().not()
} }
/** // /**
* 是否是其他设备 // * 是否是其他设备
*/ // */
fun isOtherEquipment(): Boolean { // fun isOtherEquipment(): Boolean {
return equipmentCode != null && equipmentCode != "" && GlobalData.globalEquipmentCode != equipmentCode // return equipmentCode != null && equipmentCode != "" && GlobalData.globalEquipmentCode != equipmentCode
} // }
fun hasEquipmentBox(): Boolean { fun hasEquipmentBox(): Boolean {
return !TextUtils.isEmpty(equipmentBoxCode) return !TextUtils.isEmpty(equipmentBoxCode)
} }
fun isPlaceholder(): Boolean { fun isPlaceholder(): Boolean {
return equipmentBoxCode == null || equipmentBoxCode == "" return equipmentBoxCode.isNullOrBlank()
} }
} }
@@ -1,104 +1,104 @@
package com.sw.platecabinet.network.task //package com.sw.platecabinet.network.task
import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.arcsoft.face.FaceEngine
import com.sw.inbound.utils.GsonUtils
import com.sw.plate.App
import com.sw.plate.utils.Base64
import com.sw.plate.utils.PrefUtils
import com.sw.plate.utils.arcface.FaceApi
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
import com.sw.plate.utils.arcface.faceserver.FaceServer
import com.sw.platecabinet.network.ApiClient
import com.sw.platecabinet.repository.RemoteRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import timber.log.Timber
class HeartBeatTask(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) {
companion object {
private const val TAG = "HeartBeatTask"
}
override suspend fun doWork(): Result {
return try {
// 执行后台任务逻辑
performSync()
TaskManager.startTask()
Result.success()
} catch (e: Exception) {
e.printStackTrace()
Result.retry()
}
}
private val repository: RemoteRepository by lazy {
RemoteRepository(ApiClient.apiService)
}
private val faceApi: FaceApi = FaceApi()
private suspend fun performSync() {
// withContext(Dispatchers.IO) {
// val faceUpdateTimeStamp = PrefUtils.getLong(App.getContext(), "faceUpdateTimeStamp", 0)
// if (faceUpdateTimeStamp == 0L) {
// val timestamp = System.currentTimeMillis()
// PrefUtils.setLong(App.getContext(), "faceUpdateTimeStamp", timestamp)
// }
// val resp = repository.getHeartbeatInterface(
// PrefUtils.getLong(
// App.getContext(),
// "faceUpdateTimeStamp",
// 0
// )
// )
// Timber.tag(TAG).d("performSync: ${GsonUtils.toJson(resp)}")
// val list = resp.data
// if (list.isNullOrEmpty()) {
// return@withContext
// }
// val faceServer = FaceServer.getInstance()
// val faceEngine: FaceEngine? = faceServer.faceEngine
// //
// list.forEachIndexed { index, it -> //import android.content.Context
// try { //import android.util.Log
// if (index == list.size - 1) { //import androidx.work.CoroutineWorker
// PrefUtils.setLong( //import androidx.work.WorkerParameters
// App.getContext(), //import com.arcsoft.face.FaceEngine
// "faceUpdateTimeStamp", //import com.sw.inbound.utils.GsonUtils
// it.updateTimeStamp //import com.sw.plate.App
// ) //import com.sw.plate.utils.Base64
// } //import com.sw.plate.utils.PrefUtils
// if (it.faceType == "1") { //import com.sw.plate.utils.arcface.FaceApi
// if (it.userId.isNullOrBlank().not()) { //import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
// //userId非空,根据userId删除人脸数据 //import com.sw.plate.utils.arcface.faceserver.FaceServer
// faceApi.deleteByUserName(it.userId) //import com.sw.platecabinet.network.ApiClient
// faceEngine?.removeFaceFeature(it.userId.toInt()) //import com.sw.platecabinet.repository.RemoteRepository
// } //import kotlinx.coroutines.Dispatchers
// } else if (it.faceType == "0") { //import kotlinx.coroutines.withContext
// //新增人脸数据 //import org.greenrobot.eventbus.EventBus
// val featureData = Base64.decode(it.faceFeature) //import timber.log.Timber
// val insertEntity = FaceEntity(it.userId, null, featureData)
// val faceId = faceApi.insert(insertEntity)
// insertEntity.faceId = faceId
//// faceServer.registerFaceFeatureInfoFromDb(insertEntity, faceEngine)
// //
// EventBus.getDefault().post(insertEntity) //class HeartBeatTask(appContext: Context, workerParams: WorkerParameters) :
//// callback(insertEntity) // CoroutineWorker(appContext, workerParams) {
//
// companion object {
// private const val TAG = "HeartBeatTask"
// } // }
//
// override suspend fun doWork(): Result {
// return try {
// // 执行后台任务逻辑
// performSync()
//
// TaskManager.startTask()
//
// Result.success()
// } catch (e: Exception) { // } catch (e: Exception) {
// e.printStackTrace() // e.printStackTrace()
// Result.retry()
// } // }
// } // }
//
// private val repository: RemoteRepository by lazy {
// RemoteRepository(ApiClient.apiService)
// } // }
} //
// private val faceApi: FaceApi = FaceApi()
} //
// private suspend fun performSync() {
//// withContext(Dispatchers.IO) {
//// val faceUpdateTimeStamp = PrefUtils.getLong(App.getContext(), "faceUpdateTimeStamp", 0)
//// if (faceUpdateTimeStamp == 0L) {
//// val timestamp = System.currentTimeMillis()
//// PrefUtils.setLong(App.getContext(), "faceUpdateTimeStamp", timestamp)
//// }
//// val resp = repository.getHeartbeatInterface(
//// PrefUtils.getLong(
//// App.getContext(),
//// "faceUpdateTimeStamp",
//// 0
//// )
//// )
//// Timber.tag(TAG).d("performSync: ${GsonUtils.toJson(resp)}")
//// val list = resp.data
//// if (list.isNullOrEmpty()) {
//// return@withContext
//// }
//// val faceServer = FaceServer.getInstance()
//// val faceEngine: FaceEngine? = faceServer.faceEngine
////
//// list.forEachIndexed { index, it ->
//// try {
//// if (index == list.size - 1) {
//// PrefUtils.setLong(
//// App.getContext(),
//// "faceUpdateTimeStamp",
//// it.updateTimeStamp
//// )
//// }
//// if (it.faceType == "1") {
//// if (it.userId.isNullOrBlank().not()) {
//// //userId非空,根据userId删除人脸数据
//// faceApi.deleteByUserName(it.userId)
//// faceEngine?.removeFaceFeature(it.userId.toInt())
//// }
//// } else if (it.faceType == "0") {
//// //新增人脸数据
//// val featureData = Base64.decode(it.faceFeature)
//// val insertEntity = FaceEntity(it.userId, null, featureData)
//// val faceId = faceApi.insert(insertEntity)
//// insertEntity.faceId = faceId
////// faceServer.registerFaceFeatureInfoFromDb(insertEntity, faceEngine)
////
//// EventBus.getDefault().post(insertEntity)
////// callback(insertEntity)
//// }
//// } catch (e: Exception) {
//// e.printStackTrace()
//// }
//// }
//// }
// }
//
//}
@@ -1,40 +1,40 @@
package com.sw.platecabinet.network.task //package com.sw.platecabinet.network.task
//
import androidx.lifecycle.LifecycleOwner //import androidx.lifecycle.LifecycleOwner
import androidx.work.ExistingWorkPolicy //import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder //import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkInfo //import androidx.work.WorkInfo
import androidx.work.WorkManager //import androidx.work.WorkManager
import com.sw.plate.App //import com.sw.plate.App
import java.util.concurrent.TimeUnit //import java.util.concurrent.TimeUnit
//
object TaskManager { //object TaskManager {
private const val TASK_NAME = "SmartPlateCabinetTask" // private const val TASK_NAME = "SmartPlateCabinetTask"
// private var owner: LifecycleOwner?=null //// private var owner: LifecycleOwner?=null
// fun setOwner(owner: LifecycleOwner) { //// fun setOwner(owner: LifecycleOwner) {
// this.owner = owner //// this.owner = owner
//// }
// fun startTask() {
// val nextRequest = OneTimeWorkRequestBuilder<HeartBeatTask>()
// .setInitialDelay(1, TimeUnit.MINUTES)
//// .setInputData(inputData)
// .build()
// WorkManager.getInstance(App.getContext())
//// .apply{
//// getWorkInfoByIdLiveData(nextRequest.id)
//// .observe(owner) { workInfo ->
//// if (workInfo?.state == WorkInfo.State.SUCCEEDED) {
//// val result = workInfo.outputData.getString("RESULT_KEY")
//// // 使用返回的结果
//// }
//// }
//// }
// .enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
// } // }
fun startTask() { //
val nextRequest = OneTimeWorkRequestBuilder<HeartBeatTask>() // fun cancelTask() {
.setInitialDelay(1, TimeUnit.MINUTES) // WorkManager.getInstance(App.getContext())
// .setInputData(inputData) // .cancelUniqueWork(TASK_NAME)
.build()
WorkManager.getInstance(App.getContext())
// .apply{
// getWorkInfoByIdLiveData(nextRequest.id)
// .observe(owner) { workInfo ->
// if (workInfo?.state == WorkInfo.State.SUCCEEDED) {
// val result = workInfo.outputData.getString("RESULT_KEY")
// // 使用返回的结果
// } // }
// } //
// } //}
.enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
}
fun cancelTask() {
WorkManager.getInstance(App.getContext())
.cancelUniqueWork(TASK_NAME)
}
}
@@ -0,0 +1,33 @@
package com.sw.platecabinet.utils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlin.ranges.downTo
// 倒计时Flow扩展函数
fun countDownByFlow(
total: Int,
scope: CoroutineScope,
onTick: (Int) -> Unit,
onStart: (() -> Unit)? = null,
onFinish: (() -> Unit)? = null
): Job {
return flow {
for (i in total downTo 0) {
emit(i)
if (i != 0) delay(1000)
}
}.flowOn(Dispatchers.Main)
.onStart { onStart?.invoke() }
.onCompletion { onFinish?.invoke() }
.onEach { onTick.invoke(it) }
.launchIn(scope)
}
@@ -0,0 +1,41 @@
package com.sw.platecabinet.utils
import androidx.fragment.app.FragmentActivity
import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.comn.SerialApi
import com.sw.plate.utils.comn.SerialPortManager
import com.sw.platecabinet.activity.BaseActivity
import com.sw.platecabinet.activity.MainActivity
import com.sw.platecabinet.activity.PageType
import timber.log.Timber
object PlateUtils {
fun open(fragmentActivity: FragmentActivity, code: String?) {
val activity = fragmentActivity as BaseActivity<*>
Timber.d("itemClick llOpen equipmentBoxCode = ${code}")
val equipmentBoxCode: Int = code?.toInt() ?: -1
if (equipmentBoxCode < 0) {
ToastUtils.showToast("餐盘柜编号错误")
return
}
activity.showWaitingDialog("请稍等")
SerialApi.openPlate(equipmentBoxCode, object : SerialPortManager.SendCallback {
override fun onSuccess() {
activity.hideWaitingDialog()
MainActivity.start(
activity,
pageType = PageType.PLATE_TIP,
isAdmin = true
)
}
override fun onFail(e: Exception?) {
activity.hideWaitingDialog()
ToastUtils.showToast("柜门打开失败")
}
})
}
}
@@ -1,20 +1,42 @@
package com.sw.platecabinet.utils; package com.sw.platecabinet.utils
import com.sw.inbound.utils.SPUtil; import com.google.gson.Gson
import com.sw.platecabinet.MyApp; import com.sw.inbound.utils.GsonUtils
import com.sw.inbound.utils.SPUtil
import com.sw.inbound.utils.SPUtil.Companion.getInstance
import com.sw.platecabinet.MyApp
import com.sw.platecabinet.model.response.EquipmentUserInfo
public class SpTool { object SpTool {
const val LAST_FACE_TIMESTAMP: String = "faceTimestamp"
const val PLATE_BOX_DATA: String = "plateBoxBind"
private var spUtil: SPUtil? = null
public static final String LAST_FACE_TIMESTAMP = "faceTimestamp"; init {
spUtil = getInstance(MyApp.instance!!, "default_sp")
public static long getLastFaceTimestamp() {
return SPUtil.Companion.getInstance(MyApp.getContext(), "default_sp").get(LAST_FACE_TIMESTAMP, 0L);
} }
public static void setLastFaceTimestamp(long timestamp) { fun putString(key:String, value:String) {
SPUtil.Companion.getInstance(MyApp.getContext(), "default_sp").put(LAST_FACE_TIMESTAMP, timestamp); spUtil?.put(key, value)
} }
var lastFaceTimestamp: Long
get() = spUtil?.get<Long?>(SpTool.LAST_FACE_TIMESTAMP, 0L) ?: 0
set(timestamp) {
spUtil?.put(LAST_FACE_TIMESTAMP, timestamp)
}
fun savePlateData(items: List<EquipmentUserInfo>) {
val jsonData = Gson().toJson(items)
putString(PLATE_BOX_DATA, jsonData)
}
fun getPlateData(): List<EquipmentUserInfo>? {
val jsonData = spUtil?.get(PLATE_BOX_DATA, "")
if (jsonData.isNullOrBlank()) {
return null
}
return GsonUtils.fromJsonList(jsonData, EquipmentUserInfo::class.java)
}
} }
@@ -61,15 +61,15 @@ class SettingViewModel : BaseViewModel() {
//// } //// }
//// _equipmentList.value = list //// _equipmentList.value = list
// } // }
fun getEquipmentList(block: (List<EquipmentUserInfo>) -> Unit) { // fun getEquipmentList(block: (List<EquipmentUserInfo>) -> Unit) {
launchWithLoading { // launchWithLoading {
val response = repository.getEquipmentList() // val response = repository.getEquipmentList()
if (parseResponse(response)) { // if (parseResponse(response)) {
val list = response.data ?: emptyList() // val list = response.data ?: emptyList()
block(list) // block(list)
} // }
} // }
} // }
/** /**
* 搜索会员信息列表 * 搜索会员信息列表
@@ -172,19 +172,19 @@ class SettingViewModel : BaseViewModel() {
fun bindPlate(bindParam: BindParam, block:(Pair<Boolean?, ErrorInfo>)-> Unit) { fun bindPlate(bindParam: BindParam, block:(Pair<Boolean?, ErrorInfo>)-> Unit) {
launchWithLoading { launchWithLoading {
val response = repository.plateBind(bindParam) // val response = repository.plateBind(bindParam)
if (parseResponse(response)) { // if (parseResponse(response)) {
var userInfo = response.data // var userInfo = response.data
if (userInfo == null) { // if (userInfo == null) {
userInfo = EquipmentUserInfo() // userInfo = EquipmentUserInfo()
userInfo.equipmentBoxCode = bindParam.equipmentBoxCode // userInfo.equipmentBoxCode = bindParam.equipmentBoxCode
userInfo.plateNumber = bindParam.plateNumber // userInfo.plateNumber = bindParam.plateNumber
userInfo.equipmentCode = bindParam.equipmentCode // userInfo.equipmentCode = bindParam.equipmentCode
} // }
block(true to ErrorInfo(equipmentUserInfo = userInfo)) // block(true to ErrorInfo(equipmentUserInfo = userInfo))
} else { // } else {
block(true to ErrorInfo(response.code, response.msg.toString())) // block(true to ErrorInfo(response.code, response.msg.toString()))
} // }
} }
} }
@@ -192,20 +192,20 @@ class SettingViewModel : BaseViewModel() {
plateNumber: String, plateNumber: String,
equipmentCode: String = globalEquipmentCode equipmentCode: String = globalEquipmentCode
) { ) {
_searchUserInfo.value = null // _searchUserInfo.value = null
launchWithLoading { // launchWithLoading {
// val bindParam = BindParam(plateNumber = plateNumber) //// val bindParam = BindParam(plateNumber = plateNumber)
val response = repository.findByPlateNumber(plateNumber) // val response = repository.findByPlateNumber(plateNumber)
if (response.code == "00000") { // if (response.code == "00000") {
_searchUserInfo.value = response.data // _searchUserInfo.value = response.data
} else { // } else {
_searchUserInfo.value = EquipmentUserInfo( // _searchUserInfo.value = EquipmentUserInfo(
plateNumber = plateNumber, // plateNumber = plateNumber,
equipmentCode = equipmentCode, // equipmentCode = equipmentCode,
updateTime = DateTimeUtils.getDateTimeString() // updateTime = DateTimeUtils.getDateTimeString()
) // )
} // }
} // }
} }
val PAGE_SIZE = 100 val PAGE_SIZE = 100
@@ -83,7 +83,7 @@ class UserViewModel : BaseViewModel() {
if (list.isNotEmpty()) { if (list.isNotEmpty()) {
faceTimestamp = list.last().faceUpdateTimestamp?:0 faceTimestamp = list.last().faceUpdateTimestamp?:0
} }
SpTool.setLastFaceTimestamp(faceTimestamp) SpTool.lastFaceTimestamp = faceTimestamp
//activeEngine() //activeEngine()
} }
} }
+70 -23
View File
@@ -59,39 +59,86 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="129dp" android:layout_marginTop="129dp"
android:text="请正视屏幕" android:text="请正视屏幕"
android:textStyle="bold"
android:textColor="#FFCC99" android:textColor="#FFCC99"
android:textSize="36sp" /> android:textSize="36sp"
android:textStyle="bold" />
<LinearLayout <!-- <LinearLayout-->
android:id="@+id/ll_to_pwd" <!-- android:id="@+id/ll_to_pwd"-->
android:layout_width="wrap_content" <!-- android:layout_width="wrap_content"-->
android:layout_height="wrap_content" <!-- android:layout_height="wrap_content"-->
android:layout_marginStart="208dp" <!-- android:layout_marginStart="208dp"-->
android:layout_marginTop="730dp" <!-- android:layout_marginTop="730dp"-->
android:background="@drawable/btn_outline" <!-- android:background="@drawable/btn_outline"-->
android:gravity="center" <!-- android:gravity="center"-->
android:paddingHorizontal="45dp" <!-- android:paddingHorizontal="45dp"-->
android:paddingVertical="18dp"> <!-- android:paddingVertical="18dp"-->
<!-- 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="#FFCC99" <!-- android:textColor="#FFCC99"-->
android:textSize="24sp" /> <!-- android:textSize="24sp" />-->
</LinearLayout> <!-- </LinearLayout>-->
<TextView <TextView
android:id="@+id/tv_to_init" android:id="@+id/tv_to_init"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:text="30"
android:padding="12dp"
android:gravity="center"
android:layout_marginTop="185dp" android:layout_marginTop="185dp"
android:gravity="center"
android:padding="12dp"
android:textColor="#FFCC99" android:textColor="#FFCC99"
android:textSize="36sp" /> android:textSize="36sp"
tools:text="30" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="130dp"
android:orientation="vertical">
<LinearLayout
android:id="@+id/layoutState"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="invisible">
<ProgressBar
android:id="@+id/pbCollectLoading"
android:layout_width="32dp"
android:layout_height="32dp"
android:indeterminateTint="@color/white" />
<TextView
android:id="@+id/tvCollectState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="采集中......"
android:textColor="@color/white"
android:textSize="24sp" />
</LinearLayout>
<TextView
android:id="@+id/btnCollectFace"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:background="@drawable/btn_outline"
android:gravity="center"
android:layout_marginTop="10dp"
android:paddingHorizontal="45dp"
android:text="开始采集"
android:textColor="#FFCC99"
android:textSize="24sp"
tools:ignore="HardcodedText" />
</LinearLayout>
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>
@@ -1,16 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main" android:id="@+id/main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
tools:context=".fragment.SettingListFragment"> tools:context=".fragment.SettingListFragment"
tools:background="@color/black">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/mainRecyclerView" android:id="@+id/mainRecyclerView"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
app:spanCount="2"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
tools:listitem="@layout/item_bind_view"/>
</LinearLayout> </LinearLayout>
+4 -3
View File
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll_root" android:id="@+id/ll_root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -15,7 +16,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
android:text="02" tools:text="02"
android:textColor="#FFCC99" android:textColor="#FFCC99"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" /> android:textStyle="bold" />
@@ -44,10 +45,10 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
android:text="马*飞(8000)"
android:textColor="#585868" android:textColor="#585868"
android:textSize="18sp" android:textSize="18sp"
android:textStyle="bold" /> android:textStyle="bold"
tools:text="马*飞(8000)" />
<TextView <TextView
@@ -158,7 +158,7 @@ public class RecognizeViewModel extends ViewModel implements RecognizeCallback {
private MutableLiveData<String> drawRectInfoText = new MutableLiveData<>(); private MutableLiveData<String> drawRectInfoText = new MutableLiveData<>();
private MutableLiveData<String> recognizeUserId = new MutableLiveData<>(); private MutableLiveData<CompareResult> recognizeUserId = new MutableLiveData<>();
/** /**
* 检测ir活体前,是否需要更新faceData * 检测ir活体前,是否需要更新faceData
@@ -474,7 +474,7 @@ public class RecognizeViewModel extends ViewModel implements RecognizeCallback {
Disposable disposable = Observable.just(true).observeOn(AndroidSchedulers.mainThread()).subscribe(aBoolean -> { Disposable disposable = Observable.just(true).observeOn(AndroidSchedulers.mainThread()).subscribe(aBoolean -> {
if (similarPass) { if (similarPass) {
if (recognizeUserId != null) { if (recognizeUserId != null) {
recognizeUserId.postValue(compareResult.getFaceEntity().getUserName()); recognizeUserId.postValue(compareResult);
} }
boolean isAdded = false; boolean isAdded = false;
List<CompareResult> compareResults = compareResultList.getValue(); List<CompareResult> compareResults = compareResultList.getValue();
@@ -540,7 +540,7 @@ public class RecognizeViewModel extends ViewModel implements RecognizeCallback {
return recognizeNotice; return recognizeNotice;
} }
public MutableLiveData<String> getRecognizeUserId() { public MutableLiveData<CompareResult> getRecognizeUserId() {
return recognizeUserId; return recognizeUserId;
} }
@@ -561,7 +561,7 @@ public class RecognizeViewModel extends ViewModel implements RecognizeCallback {
} }
} }
private void updateRegisterStatus(int status) { public void updateRegisterStatus(int status) {
registerStatus = status; registerStatus = status;
} }