完善了功能

This commit is contained in:
zxj
2025-07-25 10:36:30 +08:00
parent 5b3773d277
commit c89efd2d6f
10 changed files with 134 additions and 86 deletions
@@ -13,6 +13,7 @@ import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.sw.inbound.utils.DateTimeUtils
@@ -23,9 +24,11 @@ import com.sw.plate.utils.comn.SerialPortManager
import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.ext.setClickListeners
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.view.CustomDialog
import com.sw.platecabinet.viewmodel.SettingViewModel
import com.sw.platecabinet.viewmodel.UserViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -44,15 +47,23 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
private var mDialogWaiting: CustomDialog? = null
private val permissionHelpers = mutableMapOf<Int, PermissionHelper>()
protected var keyEventHelper: ScanGunKeyEventHelper? = null
private val viewModel by viewModels<SettingViewModel>()
// 管理员对应的viewmodel
private val settingViewModel by viewModels<SettingViewModel>()
// 用户对应的viewModel
protected val viewModel by viewModels<UserViewModel>()
private var startTime: Long = 0
override fun onCreate(savedInstanceState: Bundle?) {
startTime = System.currentTimeMillis()
super.onCreate(savedInstanceState)
enableEdgeToEdge()
context = this
// disableSystemUICompletely()
// 确保内容延伸到导航栏区域
// WindowCompat.setDecorFitsSystemWindows(window, false)
disableSystemUICompletely()
// 确保内容延伸到导航栏区域
WindowCompat.setDecorFitsSystemWindows(window, false)
//保持亮屏
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
@@ -64,6 +75,8 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
registerDataChange()
initialize()
registerKeyEvent()
val durationTime = System.currentTimeMillis() - startTime
Timber.d("启动时间:$durationTime")
}
/**
@@ -84,7 +97,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
* 处理扫描枪数据
*/
protected open fun handleScanKeyInfo(scanInfo: String) {
viewModel.findByPlateNumber(plateNumber = scanInfo)
settingViewModel.findByPlateNumber(plateNumber = scanInfo)
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
@@ -234,8 +247,10 @@ 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 {
@@ -246,32 +261,35 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
lifecycleScope.launch {
viewModel.currentUserInfo.drop(1).collect {
if (it == null) return@collect
if (it.equipmentBoxCode?.isNotEmpty() == true) {
SerialApi.openPlate(
it.equipmentBoxCode.toInt(),
object : SerialPortManager.SendCallback {
override fun onSuccess() {
MainActivity.start(context, pageType = PageType.PLATE_OPEN)
}
override fun onFail(e: Exception?) {
ToastUtils.showToast("柜门打开失败")
}
})
handleLoginSuccess(it, false)
}
}
lifecycleScope.launch {
settingViewModel.showLoading.collect {
Timber.d("registerDataChange 管理员 showLoading = $it")
if (it) {
showWaitingDialog("")
} else {
viewModel.getEquipmentList()
hideWaitingDialog()
}
}
}
lifecycleScope.launch {
viewModel.equipmentList.drop(1).collect {
settingViewModel.searchUserInfo.drop(1).collect {
Timber.d("registerDataChange 管理员 currentUserInfo = $it")
if (it == null) return@collect
handleLoginSuccess(it, true)
}
}
lifecycleScope.launch {
settingViewModel.equipmentList.drop(1).collect {
if (it.isEmpty()) return@collect
val unbindList = it.filter { !it.isBound() }
if (unbindList.isEmpty()) {
MainActivity.start(context = context, pageType = PageType.PLATE_CABINET_FULL)
} else {
val firstInfo = unbindList[0]
val currentUserInfo = viewModel.currentUserInfo.value
val currentUserInfo = settingViewModel.searchUserInfo.value
firstInfo.plateNumber = currentUserInfo?.plateNumber ?: ""
MainActivity.start(
context = context,
@@ -283,6 +301,33 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
}
}
/**
* 处理登录成功操作
* @param isAdmin true 管理员 执行绑盘此操作 false 用户,提示错误
*/
fun handleLoginSuccess(equipmentUserInfo: EquipmentUserInfo, isAdmin: Boolean) {
viewModel.resetUserInfo()
if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) {
SerialApi.openPlate(
equipmentUserInfo.equipmentBoxCode.toInt(),
object : SerialPortManager.SendCallback {
override fun onSuccess() {
MainActivity.start(context, pageType = PageType.PLATE_OPEN)
}
override fun onFail(e: Exception?) {
ToastUtils.showToast("柜门打开失败")
}
})
} else {
if (isAdmin) {
settingViewModel.getEquipmentList()
} else {
ToastUtils.showToast("无餐盘信息")
}
}
}
override fun onDestroy() {
timeJob?.cancel()
keyEventHelper?.onDestroy()
@@ -12,7 +12,6 @@ import android.view.ViewTreeObserver
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import com.arcsoft.face.ErrorInfo
import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.ConfigUtil
@@ -31,9 +30,7 @@ import com.sw.platecabinet.R
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.viewmodel.UserViewModel
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch
import com.sw.platecabinet.utils.ThreadUtils
import timber.log.Timber
/**
@@ -41,7 +38,6 @@ import timber.log.Timber
*/
class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
ViewTreeObserver.OnGlobalLayoutListener {
private val viewModel by viewModels<UserViewModel>()
private val recognizeViewModel by viewModels<RecognizeViewModel>()
private val CAMERA_PERMISSION_REQUEST_CODE = 100
@@ -60,7 +56,10 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
override fun initialize() {
viewModel.activeEngine()
ThreadUtils.launch {
viewModel.activeEngine()
}
initArcViewModel()
initArcView()
openRectInfoDraw = true
@@ -72,20 +71,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
}
override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch {
viewModel.currentUserInfo.drop(1).collect {
Timber.d("currentUserInfo it = $it")
if (it != null) {
ToastUtils.showToast("登录成功")
MainActivity.start(context, pageType = PageType.PLATE_CABINET_FULL)
finish()
}
}
}
}
private fun checkCameraPermission() {
Timber.i("checkCameraPermission")
val permissionHelper =
@@ -355,12 +340,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
checkCameraPermission()
}
// @Override
// protected void onResume() {
// super.onResume();
// resumeCamera();
// }
private fun resumeCamera() {
isRecognition = true
if (rgbCameraHelper != null && rgbCameraHelper!!.isStopped) {
@@ -368,6 +347,12 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
}
}
override fun onResume() {
super.onResume()
resumeCamera()
viewModel.resetUserInfo()
}
protected override fun onPause() {
pauseCamera()
super.onPause()
@@ -1,19 +1,12 @@
package com.sw.platecabinet.activity
import android.content.Intent
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.face.Test
import com.sw.platecabinet.databinding.ActivityLoginByPwdBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.viewmodel.UserViewModel
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch
import timber.log.Timber
import com.sw.platecabinet.utils.KeyboardUtils
class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
private val viewModel by viewModels<UserViewModel>()
override fun inflateViewBinding(): ActivityLoginByPwdBinding {
return ActivityLoginByPwdBinding.inflate(layoutInflater)
@@ -24,41 +17,27 @@ class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
}
override fun initialize() {
binding.etPhone.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) KeyboardUtils.showKeyboard(v)
}
binding.btnLogin.setOnClickListener {
val phone = binding.etPhone.text.toString()
val pwd = binding.etPwd.text.toString()
if (phone.isEmpty() || pwd.isEmpty()) {
ToastUtils.showToast("手机或校验码不能为空")
val test = Test()
for (i in 1..1000) {
test.test1()
}
return@setOnClickListener
}
viewModel.loginWithPwd(phone = phone, password = pwd)
KeyboardUtils.hideKeyboard(this)
}
binding.tvFaceRec.setOnClickListener {
val intent = Intent(this, LoginByFaceActivity::class.java)
startActivity(intent)
// handleScanKeyInfo(binding.etPwd.text.toString())
}
}
override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch {
viewModel.currentUserInfo
.drop(1)
.collect {
Timber.d("currentUserInfo it = $it")
if (it != null) {
// ToastUtils.showToast("登录成功")
MainActivity.start(context, pageType = PageType.PLATE_OPEN)
finish()
}
}
}
override fun onResume() {
super.onResume()
viewModel.resetUserInfo()
}
}
@@ -22,6 +22,7 @@ import com.sw.platecabinet.ext.maskName
import com.sw.platecabinet.ext.maskPhone
import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.model.response.SearchResult
import com.sw.platecabinet.utils.KeyboardUtils
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch
import timber.log.Timber
@@ -154,6 +155,7 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
memberId = checkedItem!!.id!!,
plateNumber = plateNumber
)
KeyboardUtils.hideKeyboard(requireActivity())
}
binding.tvBack.setOnClickListener { activity?.finish() }
}
@@ -111,7 +111,7 @@ class SettingListFragment :
if (item.isBound()) {
val date = DateTimeUtils.parseDateTime(item.updateTime)
val timeInMillis = date?.time ?: 0L
val isOldTime = DateTimeUtils.isMoreThan36HoursFromNow(timeInMillis)
val isOldTime = DateTimeUtils.isMoreThanHoursFromNow(timeInMillis)
this.llRoot.setBackgroundResource(R.drawable.grid_item_bind)
this.tvNum.setTextColor(resources.getColor(R.color.bind_4E535D))
@@ -73,15 +73,15 @@ object DateTimeUtils {
}
/**
* 判断给定时间是否距离当前时间超过36小时
* 判断给定时间是否距离当前时间超过72小时
* @param timeInMillis 时间戳(毫秒)
* @return true 表示超过36小时,false 表示未超过
* @return true 表示超过72小时,false 表示未超过
*/
fun isMoreThan36HoursFromNow(timeInMillis: Long): Boolean {
fun isMoreThanHoursFromNow(timeInMillis: Long): Boolean {
val currentTime = System.currentTimeMillis()
val timeDifference = currentTime - timeInMillis
val hoursDifference = timeDifference / (1000 * 60 * 60) // 毫秒转小时
return hoursDifference >= 36
return hoursDifference >= 72
}
/**
@@ -0,0 +1,29 @@
package com.sw.platecabinet.utils
import android.app.Activity
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
/**
* 键盘工具类
*/
object KeyboardUtils {
/**
* 显示键盘
*/
fun showKeyboard(view: View) {
val imm = view.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
/**
* 隐藏键盘
*/
fun hideKeyboard(activity: Activity) {
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
val view = activity.currentFocus ?: View(activity)
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
}
@@ -21,8 +21,8 @@ class SettingViewModel : BaseViewModel() {
private val _searchMemberList = MutableStateFlow<List<SearchResult.Member>>(emptyList())
val searchMemberList: StateFlow<List<SearchResult.Member>> = _searchMemberList
private val _currentUserInfo = MutableStateFlow<EquipmentUserInfo?>(null)
val currentUserInfo: StateFlow<EquipmentUserInfo?> = _currentUserInfo
private val _searchUserInfo = MutableStateFlow<EquipmentUserInfo?>(null)
val searchUserInfo: StateFlow<EquipmentUserInfo?> = _searchUserInfo
var currentPage = 1
var isLoading = false
@@ -148,9 +148,9 @@ class SettingViewModel : BaseViewModel() {
}
}
_currentUserInfo.value = response.data
_searchUserInfo.value = response.data
} else {
_currentUserInfo.value = EquipmentUserInfo(
_searchUserInfo.value = EquipmentUserInfo(
plateNumber = plateNumber,
equipmentCode = equipmentCode,
updateTime = DateTimeUtils.getDateTimeString()
@@ -140,4 +140,13 @@ class UserViewModel : BaseViewModel() {
}
}
}
/**
* 重置用户信息
*/
fun resetUserInfo() {
Timber.d("resetUserInfo")
_currentUserInfo.value = null
}
}