餐盘柜优化-绑定临时用户

This commit is contained in:
mazengfei
2026-01-16 16:14:38 +08:00
parent 8337b3fabb
commit cf2d2db42f
10 changed files with 267 additions and 176 deletions
@@ -127,14 +127,14 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
item.plateNumber = plateNumber
item.faceId = null
item.updateTime = null
PlateUtils.open(this, item.equipmentBoxCode)
PlateUtils.open(this, item.equipmentBoxCode, true)
return
}
//放入餐盘,清除已有id和时间
item.plateNumber = plateNumber
item.faceId = null
item.updateTime = null
PlateUtils.open(this, item.equipmentBoxCode)
PlateUtils.open(this, item.equipmentBoxCode, true)
SpTool.savePlateData(MyApp.plateList!!)
}
@@ -266,22 +266,25 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
/**
* 显示等待提示框
*/
fun showWaitingDialog(tip: String?): Dialog? {
hideWaitingDialog()
val view = View.inflate(this, R.layout.dialog_waiting, null)
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).setText(tip)
mDialogWaiting = CustomLoadingDialog(this, view, R.style.MyDialog)
mDialogWaiting!!.show()
mDialogWaiting!!.setCancelable(true)
return mDialogWaiting
fun showWaitingDialog(tip: String?) {
runOnUiThread {
hideWaitingDialog()
val view = View.inflate(this, R.layout.dialog_waiting, null)
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).setText(tip)
mDialogWaiting = CustomLoadingDialog(this, view, R.style.MyDialog)
mDialogWaiting!!.show()
mDialogWaiting!!.setCancelable(true)
}
}
/**
* 隐藏等待提示框
*/
fun hideWaitingDialog() {
mDialogWaiting?.dismiss()
mDialogWaiting = null
runOnUiThread {
mDialogWaiting?.dismiss()
mDialogWaiting = null
}
}
protected abstract fun inflateViewBinding(): VB
@@ -295,40 +298,40 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
*/
protected open fun registerDataChange() {
Timber.d("registerDataChange")
lifecycleScope.launch {
viewModel.showLoading.collect {
Timber.d("registerDataChange 用户 showLoading = $it")
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
lifecycleScope.launch {
viewModel.currentUserInfo.collect {
if (it == null) return@collect
// it.showBalanceNotEnoughDialog = true
handleLoginSuccess(it, false)
}
}
lifecycleScope.launch {
settingViewModel.showLoading.collect {
Timber.d("registerDataChange 管理员 showLoading = $it")
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
lifecycleScope.launch {
settingViewModel.searchUserInfo.collect {
Timber.d("registerDataChange 管理员 currentUserInfo = $it")
if (it == null) return@collect
handleLoginSuccess(it, true)
}
}
// lifecycleScope.launch {
// viewModel.showLoading.collect {
// Timber.d("registerDataChange 用户 showLoading = $it")
// if (it) {
// showWaitingDialog("")
// } else {
// hideWaitingDialog()
// }
// }
// }
// lifecycleScope.launch {
// viewModel.currentUserInfo.collect {
// if (it == null) return@collect
//// it.showBalanceNotEnoughDialog = true
// handleLoginSuccess(it, false)
// }
// }
// lifecycleScope.launch {
// settingViewModel.showLoading.collect {
// Timber.d("registerDataChange 管理员 showLoading = $it")
// if (it) {
// showWaitingDialog("")
// } else {
// hideWaitingDialog()
// }
// }
// }
// lifecycleScope.launch {
// settingViewModel.searchUserInfo.collect {
// Timber.d("registerDataChange 管理员 currentUserInfo = $it")
// if (it == null) return@collect
// handleLoginSuccess(it, true)
// }
// }
// lifecycleScope.launch {
// settingViewModel.equipmentList.collect {
// loadEquipmentList(it)
@@ -336,22 +339,22 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
// }
}
private fun loadEquipmentList(items: List<EquipmentUserInfo>) {
if (items.isEmpty()) return
val unbindList = items.filter { !it.isBound() }
if (unbindList.isEmpty()) {
MainActivity.start(context = context, pageType = PageType.PLATE_CABINET_FULL)
} else {
val firstInfo = unbindList[0]
val currentUserInfo = settingViewModel.searchUserInfo.value
firstInfo.plateNumber = currentUserInfo?.plateNumber ?: ""
MainActivity.start(
context = context,
pageType = PageType.BIND_PLATE,
equipmentUserInfo = firstInfo
)
}
}
// private fun loadEquipmentList(items: List<EquipmentUserInfo>) {
// if (items.isEmpty()) return
// val unbindList = items.filter { !it.isBound() }
// if (unbindList.isEmpty()) {
// MainActivity.start(context = context, pageType = PageType.PLATE_CABINET_FULL)
// } else {
// val firstInfo = unbindList[0]
// val currentUserInfo = settingViewModel.searchUserInfo.value
// firstInfo.plateNumber = currentUserInfo?.plateNumber ?: ""
// MainActivity.start(
// context = context,
// pageType = PageType.BIND_PLATE,
// equipmentUserInfo = firstInfo
// )
// }
// }
/**
* 处理登录成功操作
@@ -21,7 +21,7 @@ class InitActivity : BaseActivity<ActivityInitBinding>() {
}
override fun initialize() {
binding.main.setOnClickListener {
binding.takeButton.setOnClickListener {
finish()
}
// binding.takeButton.setOnClickListener {
@@ -63,13 +63,14 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import timber.log.Timber
import kotlin.math.log
/**
* 人脸识别
*/
class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
ViewTreeObserver.OnGlobalLayoutListener {
// private val recognizeViewModel by viewModels<RecognizeViewModel>()
// private val recognizeViewModel by viewModels<RecognizeViewModel>()
private var countDownTimer: CountDownTimer? = null
private val CAMERA_PERMISSION_REQUEST_CODE = 100
@@ -96,11 +97,11 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
}
override fun initialize() {
instance = this
viewModel.activeEngine()
addSocketListener()
initCountTime()
initArcViewModel()
initArcView()
@@ -120,7 +121,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
// binding.btnCollectFace.setOnClickListener { collectFace() }
checkFaceState()
}
private fun checkCameraPermission() {
@@ -157,12 +157,15 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
private var openRectInfoDraw = false
private fun initArcViewModel() {
recognizeViewModel.setLiveType(livenessType)
recognizeViewModel.prepareRegister()
recognizeViewModel.setOnRegisterFinishedCallback { facePreviewInfo, userFaceInfo ->
this.userFaceInfo = userFaceInfo
Log.d(TAG, "initArcViewModel: userFaceInfo == null : ${userFaceInfo == null}")
//Log.d(TAG, "initArcViewModel: userFaceInfo == null : ${userFaceInfo == null}")
if (this.userFaceInfo == null && userFaceInfo != null) {
recognizeViewModel.updateRegisterStatus(RecognizeViewModel.REGISTER_STATUS_DONE)
this.userFaceInfo = userFaceInfo
return@setOnRegisterFinishedCallback
}
}
recognizeViewModel.ftInitCode.observe(this, Observer { ftInitCode: Int? ->
if (ftInitCode != ErrorInfo.MOK) {
@@ -243,6 +246,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
* 打开餐盘柜
*/
private fun openPlate(userId: String?) {
Log.d(TAG, "openPlate: userId=$userId")
getPlateData { items ->
Log.d(TAG, "openPlate: items:${Gson().toJson(items)}")
var item = items.firstOrNull { it.faceId == userId }
@@ -253,7 +257,9 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
return@getPlateData
}
// 未查询到当前用户,查询第一个未绑定的餐盘
item = items.firstOrNull { it.plateNumber.isNullOrEmpty().not() && it.faceId.isNullOrBlank() }
item = items.firstOrNull {
it.plateNumber.isNullOrEmpty().not() && it.faceId.isNullOrBlank()
}
Log.d(TAG, "openPlate: item2:${item}")
if (item == null) {
//暂无餐盘
@@ -264,7 +270,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
item.faceId = userId
item.updateTime = DateTimeUtils.getDateTimeString()
//打开柜子
PlateUtils.open(this, item.equipmentBoxCode)
PlateUtils.open(this, item.equipmentBoxCode, false)
currentPlateInfo = item
MyApp.plateList = items
@@ -508,16 +514,32 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
}
/**
* 临时用户id
*/
private var tempUserId: String = ""
override fun onResume() {
super.onResume()
if (isFirstOpen) {
goInitActivity()
binding.root.postDelayed({
isFirstOpen = false
}, 1000)
return
}
tempUserId = "${System.currentTimeMillis()}"
resumeCamera()
viewModel.resetUserInfo()
countDownTimer?.let {
it.cancel()
it.start()
}
checkFaceState()
}
private var isFirstOpen = true
protected override fun onPause() {
pauseCamera()
super.onPause()
@@ -535,8 +557,8 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
// goInitActivity()
}
private val totalTimeInMillis = 30 * 1000L
fun initCountTime() {
val totalTimeInMillis = 30L * 1000
countDownTimer = object : CountDownTimer(totalTimeInMillis, 1000) {
override fun onTick(millisUntilFinished: Long) {
Timber.d("initCountTime onTick = ${(millisUntilFinished / 1000).toInt()}")
@@ -546,7 +568,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
override fun onFinish() {
goInitActivity()
}
}.start()
}
}
fun goInitActivity() {
@@ -556,19 +578,25 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
private fun collectFace() {
//toast("currentUserId=$currentUserId")
Log.d(TAG, "collectFace: -----------11111111----------")
if (isFirstOpen) return
Log.d(TAG, "collectFace: ----------22222222-----------")
if (facePreviewInfoList.isNullOrEmpty()) {
ToastUtils.showToast("未检测到人脸信息")
return
}
if (currentUserId != null) {
currentUserId = null
// ToastUtils.showToast("您已采集过人脸信息")
//ToastUtils.showToast("未检测到人脸信息")
Log.d(TAG, "collectFace: ----------33333333-----------")
Log.d(TAG, "collectFace: 未检测到人脸信息")
return
}
Log.d(TAG, "collectFace: ----------44444444-----------")
// if (currentUserId != null) {
// currentUserId = null
//// ToastUtils.showToast("您已采集过人脸信息")
// return
// }
currentUserId = null
userFaceInfo = null
recognizeViewModel.updateRegisterStatus(REGISTER_STATUS_READY)
//showWaitingDialog("人脸信息中……")
// showWaitingDialog("加载中……")
// binding.tvFaceTip.gone()
// binding.btnCollectFace.invisible()
@@ -576,14 +604,14 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
// binding.pbCollectLoading.visible()
// binding.tvCollectState.text = "采集中......"
getFaceData { faceData ->
Log.d("LoginByFaceActivity", "faceData: $faceData")
Log.d("LoginByFaceActivity", "collectFace,faceData: $faceData")
runOnUiThread {
//hideWaitingDialog()
// hideWaitingDialog()
//toast("人脸信息已采集")
// binding.pbCollectLoading.gone()
//binding.tvCollectState.text = "采集完成"
userFaceInfo = null
countDown()
// countDown()
}
// sendFaceData(faceData)
saveFaceInfo(faceData)
@@ -602,12 +630,14 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
val faceData = Base64.encode(userFaceInfo!!.faceFeature!!.featureData)
block(faceData)
checkFaceJob?.cancel()
job?.cancel()
}
}
}
private var facePreviewInfoList: MutableList<FacePreviewInfo>?=null
private var facePreviewInfoList: MutableList<FacePreviewInfo>? = null
private var userFaceInfo: UserFaceInfo? = null
private var countDownJob: Job? = null
private var job: Job? = null
@@ -634,18 +664,24 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
private fun saveFaceInfo(faceData: String) {
Log.d(TAG, "collectFace,saveFaceInfo: $faceData")
Thread {
try {
val tempId = "${System.currentTimeMillis()}"
val faceDao = FaceDatabase.getInstance(this).faceDao()
val entity = faceDao.queryByUserName(tempUserId)
if (entity != null) {
//已存在用户
return@Thread
}
val faceEntity = FaceEntity(
tempId,
tempUserId,
null,
Base64.decode(faceData)
).also {
it.userType = "2"
}
FaceDatabase.getInstance(this).faceDao().insert(faceEntity)
recognizeViewModel.refreshFaceList();
faceDao.insert(faceEntity)
recognizeViewModel.refreshFaceList()
// runOnUiThread {
// ToastUtils.showToast("你的人脸信息已采集")
// }
@@ -654,6 +690,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
}.start()
}
private var tcpClient: TcpClient? = null
private fun addSocketListener() {
@@ -688,10 +725,12 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
LanServer.TYPE_ADD_FACE_DATA -> {
//采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据
}
LanServer.TYPE_CLEAR_FACE_DATA -> {
clearFaceData()
}
else-> {}
else -> {}
}
}
})
@@ -719,16 +758,21 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
recognizeViewModel.refreshFaceList();
}.start()
}
private val WAITING_TIME = 5 * 1000L
private val WAITING_TIME = 3 * 1000L
private var checkStartTime = 0L
private var checkFaceJob: Job?=null
private var checkFaceJob: Job? = null
private fun checkFaceState() {
checkStartTime = System.currentTimeMillis()
checkFaceJob = executor.startIntervalTask(5) {
if (System.currentTimeMillis() - checkStartTime >= WAITING_TIME && currentUserId.isNullOrBlank()) {
Log.d("Login", "currentUserId=${currentUserId}")
if (currentUserId.isNullOrBlank().not()) {
checkFaceJob?.cancel()
return@startIntervalTask
}
if (System.currentTimeMillis() - checkStartTime >= WAITING_TIME) {
//超过5秒采集人脸并识别
collectFace()
return@startIntervalTask
}
}
}
@@ -33,33 +33,42 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
// 静态启动方法
companion object {
private const val PARAM_PAGE_TYPE = "pageType"
private const val PARAM_EQUIPMENT_INFO = "equipmentUserInfo"
private const val PARAM_IS_ADMIN = "isAdmin"
fun start(
context: Context,
pageType: PageType,
equipmentUserInfo: EquipmentUserInfo? = null,
isAdmin: Boolean = false,
block:()->Unit={}
) {
// private const val PARAM_EQUIPMENT_INFO = "equipmentUserInfo"
// private const val PARAM_IS_ADMIN = "isAdmin"
// fun start(
// context: Context,
// pageType: PageType,
// equipmentUserInfo: EquipmentUserInfo? = null,
// isAdmin: Boolean = false,
// block:()->Unit={}
// ) {
// val intent = Intent(context, MainActivity::class.java)
// intent.putExtra(PARAM_PAGE_TYPE, pageType.name)
// intent.putExtra(PARAM_EQUIPMENT_INFO, equipmentUserInfo)
// intent.putExtra(PARAM_IS_ADMIN, isAdmin)
// context.startActivity(intent)
// }
fun start(context: Context,pageType: PageType, isScanCode: Boolean = false) {
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(PARAM_PAGE_TYPE, pageType.name)
intent.putExtra(PARAM_EQUIPMENT_INFO, equipmentUserInfo)
intent.putExtra(PARAM_IS_ADMIN, isAdmin)
intent.putExtra(PlateOpenFragment.IS_SCAN_CODE, isScanCode)
context.startActivity(intent)
}
}
override fun initialize() {
val param = intent.getStringExtra(PARAM_PAGE_TYPE)
val isAdmin = intent.getBooleanExtra(PARAM_IS_ADMIN, false)
val equipmentUserInfo = intent.getParcelableExtra<EquipmentUserInfo>(PARAM_EQUIPMENT_INFO)
// val isAdmin = intent.getBooleanExtra(PARAM_IS_ADMIN, false)
val isScanCode = intent.getBooleanExtra(PlateOpenFragment.IS_SCAN_CODE, false)
// val equipmentUserInfo = intent.getParcelableExtra<EquipmentUserInfo>(PARAM_EQUIPMENT_INFO)
pageType = param?.let { PageType.valueOf(param) } ?: PageType.SETTING_LIST
fragmentHelper = FragmentHelper(supportFragmentManager, R.id.fragment_container)
val page = when (pageType) {
PageType.SETTING_LIST -> SettingListFragment()
// PageType.BIND_PLATE -> BindPlateFragment.newInstance(equipmentUserInfo)
PageType.PLATE_TIP -> PlateOpenFragment.newInstance(equipmentUserInfo, isAdmin)
// PageType.PLATE_TIP -> PlateOpenFragment.newInstance(equipmentUserInfo, isAdmin)
PageType.PLATE_TIP -> PlateOpenFragment.newInstance(isScanCode)
// PageType.UNBIND_PLATE -> UnBindPlateFragment.newInstance(equipmentUserInfo)
PageType.PLATE_CABINET_FULL -> PlateCabinetFullFragment()
else -> null