绑定解绑功能调试;其它优化

This commit is contained in:
马增飞
2026-01-05 18:38:10 +08:00
parent 17d47a876f
commit 582be4e9b7
16 changed files with 170 additions and 108 deletions
@@ -200,10 +200,10 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
private fun disableSystemUICompletely() { private fun disableSystemUICompletely() {
Timber.d("disableSystemUICompletely") Timber.d("disableSystemUICompletely")
// 禁用系统手势(Android 10+ // 禁用系统手势(Android 10+
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// window.insetsController?.systemBarsBehavior = window.insetsController?.systemBarsBehavior =
// WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
// } }
// 全屏+隐藏导航栏(所有版本通用) // 全屏+隐藏导航栏(所有版本通用)
@@ -307,7 +307,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
// } // }
} }
private fun loadEquipmentList(items:List<EquipmentUserInfo>) { private fun loadEquipmentList(items: List<EquipmentUserInfo>) {
if (items.isEmpty()) return if (items.isEmpty()) return
val unbindList = items.filter { !it.isBound() } val unbindList = items.filter { !it.isBound() }
if (unbindList.isEmpty()) { if (unbindList.isEmpty()) {
@@ -331,7 +331,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
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) {
//提示余额不足弹窗 //提示余额不足弹窗
@@ -340,15 +340,15 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
return return
} }
viewModel.resetUserInfo() viewModel.resetUserInfo()
if (equipmentUserInfo.isOtherEquipment()) { // if (equipmentUserInfo.isOtherEquipment()) {
MainActivity.start( // MainActivity.start(
context, // context,
pageType = PageType.PLATE_TIP, // pageType = PageType.PLATE_TIP,
equipmentUserInfo = equipmentUserInfo, // equipmentUserInfo = equipmentUserInfo,
isAdmin // isAdmin
) // )
return // return
} // }
if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) { if (equipmentUserInfo.equipmentBoxCode?.isNotEmpty() == true) {
SerialApi.openPlate( SerialApi.openPlate(
equipmentUserInfo.equipmentBoxCode!!.toInt(), equipmentUserInfo.equipmentBoxCode!!.toInt(),
@@ -367,7 +367,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
}) })
} else { } else {
if (isAdmin) { if (isAdmin) {
settingViewModel.getEquipmentList{ settingViewModel.getEquipmentList {
loadEquipmentList(it) loadEquipmentList(it)
} }
} else { } else {
@@ -394,27 +394,43 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
// private val initialDelay = 5 * 60 * 1000L // private val initialDelay = 5 * 60 * 1000L
// private val dealyMillis = 10 * 60 * 1000L // private val dealyMillis = 10 * 60 * 1000L
private val initialDelay = 60 * 1000L private val initialDelay = 1 * 60 * 1000L
private val dealyMillis = 30 * 1000L private val dealyMillis = 1 * 60 * 1000L
private var taskPageNo = 1 private var taskPageNo = 1
fun startFaceTask() { fun startFaceTask() {
faceTaskJob = faceTaskJob =
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) { intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) {
getFaceIncrementList()
}
}
private var faceTimestamp = 0L
private fun getFaceIncrementList() {
val timestamp = SpTool.getLastFaceTimestamp() val timestamp = SpTool.getLastFaceTimestamp()
if (timestamp == 0L) { if (timestamp == 0L) {
return@startIntervalTaskWithInitialDelay return
} }
settingViewModel.getFaceIncrementList( settingViewModel.getFaceIncrementList(
pageNo = taskPageNo, pageNo = taskPageNo,
timestamp = timestamp timestamp = timestamp
) { list -> ) { list ->
runOnUiThread { runOnUiThread {
if (list.isEmpty()) { if (taskPageNo == 1 && list.isEmpty()) {
//未查询到增量数据
return@runOnUiThread return@runOnUiThread
} }
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
updateFaceData(list) updateFaceData(list)
if (list.size >= settingViewModel.PAGE_SIZE) {
faceTimestamp = list.last().faceUpdateTimestamp?:0
taskPageNo++
getFaceIncrementList()
return@runOnUiThread
} }
if (list.isNotEmpty()) {
faceTimestamp = list.last().faceUpdateTimestamp?:0
}
SpTool.setLastFaceTimestamp(faceTimestamp)
} }
} }
} }
@@ -51,6 +51,8 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
if (deviceConfig == null) { if (deviceConfig == null) {
hideWaitingDialog() hideWaitingDialog()
ToastUtils.showToast("获取设备配置数据失败") ToastUtils.showToast("获取设备配置数据失败")
hideWaitingDialog()
goLoginActivity()
return@runOnUiThread return@runOnUiThread
} }
GlobalData.appId = deviceConfig.arcsoftAppId ?: "" GlobalData.appId = deviceConfig.arcsoftAppId ?: ""
@@ -1,5 +1,6 @@
package com.sw.platecabinet.fragment package com.sw.platecabinet.fragment
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
@@ -60,13 +61,18 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
} }
} }
@SuppressLint("SetTextI18n")
override fun initialize() { override fun initialize() {
arguments?.let { arguments?.let { args ->
info = it.getParcelable(KEY_ACTION_TYPE) info = args.getParcelable(KEY_ACTION_TYPE)
info?.let { info?.let {
binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}" binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}"
if (!TextUtils.isEmpty(it.plateNumber)) { if (!TextUtils.isEmpty(it.plateNumber)) {
binding.etCode.text = Editable.Factory.getInstance().newEditable(it.plateNumber) // binding.etCode.text = Editable.Factory.getInstance().newEditable(it.plateNumber)
binding.etCode.apply {
setText(it.plateNumber)
setSelection(length())
}
} }
} }
} }
@@ -104,13 +110,27 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
} }
}) })
(activity as MainActivity).registerKeyEventInfo { (activity as MainActivity).registerKeyEventInfo {
if (binding.etUserInfo.isFocused) return@registerKeyEventInfo // binding.etCode.text.clear()
binding.etCode.text.clear() // binding.etCode.postDelayed({
binding.etCode.postDelayed({ // binding.etCode.text.clear()
binding.etCode.text.clear() // binding.etCode.text = Editable.Factory.getInstance().newEditable(it)
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() binding.etUserInfo.requestFocus()
}, 50) }
// }, 50)
} }
} }
@@ -191,10 +211,10 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
return@setOnClickListener return@setOnClickListener
} }
val bindParam = BindParam( val bindParam = BindParam(
equipmentId = info!!.equipmentId, equipmentId = info?.equipmentId,
equipmentCode = info!!.equipmentCode!!, equipmentCode = info?.equipmentCode,
equipmentBoxCode = info!!.equipmentBoxCode!!, equipmentBoxCode = info?.equipmentBoxCode,
memberId = checkedItem!!.id!!, faceId = checkedItem?.faceId,
plateNumber = plateNumber plateNumber = plateNumber
) )
viewModel.bindPlate(bindParam) { pair -> viewModel.bindPlate(bindParam) { pair ->
@@ -242,7 +262,7 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
//TODO 调用接口查询用户是否已绑盘 //TODO 调用接口查询用户是否已绑盘
this@BindPlateFragment.equipmentBoxCode = null this@BindPlateFragment.equipmentBoxCode = null
(activity as? MainActivity)?.showWaitingDialog("查询中,请稍后……") (activity as? MainActivity)?.showWaitingDialog("查询中,请稍后……")
userViewModel.getUserInfoById(memberId = item.id) { userViewModel.getUserInfoById(memberId = item.faceId) {
(activity as? MainActivity)?.hideWaitingDialog() (activity as? MainActivity)?.hideWaitingDialog()
this@BindPlateFragment.equipmentBoxCode = it?.equipmentBoxCode this@BindPlateFragment.equipmentBoxCode = it?.equipmentBoxCode
} }
@@ -269,14 +289,14 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
ToastUtils.showToast("数据异常") ToastUtils.showToast("数据异常")
return return
} }
if (errorInfo.equipmentUserInfo.isOtherEquipment()) { // if (errorInfo.equipmentUserInfo.isOtherEquipment()) {
MainActivity.start( // MainActivity.start(
requireContext(), // requireContext(),
pageType = PageType.PLATE_TIP, // pageType = PageType.PLATE_TIP,
equipmentUserInfo = errorInfo.equipmentUserInfo, // equipmentUserInfo = errorInfo.equipmentUserInfo,
isAdmin = true // isAdmin = true
) // )
} else { // } else {
SerialApi.openPlate( SerialApi.openPlate(
errorInfo.equipmentUserInfo.equipmentBoxCode!!.toInt(), errorInfo.equipmentUserInfo.equipmentBoxCode!!.toInt(),
object : SerialPortManager.SendCallback { object : SerialPortManager.SendCallback {
@@ -289,7 +309,7 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
ToastUtils.showToast("绑定失败") ToastUtils.showToast("绑定失败")
} }
}) })
} // }
} else { } else {
ToastUtils.showToast(errorInfo.msg) ToastUtils.showToast(errorInfo.msg)
} }
@@ -39,7 +39,7 @@ class UnBindPlateFragment private constructor() : BaseFragment<FragmentUnbindPla
ActivityResultContracts.StartActivityForResult() ActivityResultContracts.StartActivityForResult()
) { result -> ) { result ->
if (result.resultCode == Activity.RESULT_OK) { if (result.resultCode == Activity.RESULT_OK) {
viewModel.unbindPlate(info!!.id!!) { pair -> viewModel.unbindPlate(info?.id) { pair ->
updateBindState(pair) updateBindState(pair)
} }
} }
@@ -6,7 +6,7 @@ import com.sw.platecabinet.model.response.EquipmentUserInfo
* 错误信息 code == 200 成功 * 错误信息 code == 200 成功
*/ */
data class ErrorInfo( data class ErrorInfo(
val code: String = "200", val code: String = "00000",
val msg: String = "", val msg: String = "",
val equipmentUserInfo: EquipmentUserInfo? = null val equipmentUserInfo: EquipmentUserInfo? = null
) { ) {
@@ -18,7 +18,7 @@ data class BindParam(
/** /**
* 设备编号 * 设备编号
*/ */
var equipmentCode: String = "", var equipmentCode: String? = "",
/** /**
*设备盒子编号 *设备盒子编号
*/ */
@@ -28,6 +28,7 @@ data class BindParam(
* 会员Id * 会员Id
*/ */
val memberId: String? = null, val memberId: String? = null,
val faceId: String? = null,
/** /**
*餐盘编号 *餐盘编号
*/ */
@@ -17,7 +17,8 @@ data class LoginParam(
/** /**
* 会员信息 * 会员信息
*/ */
val memberId: String? = null, // val memberId: String? = null,
val faceId: String? = null,
/** /**
* 密码 * 密码
*/ */
@@ -10,25 +10,27 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class SearchParam( data class SearchParam(
/** // /**
* app版本号 // * app版本号
*/ // */
var appVersion: String = "", // var appVersion: String = "",
/** // /**
* 设备ID // * 设备ID
*/ // */
@SerializedName("equipmentCode") // @SerializedName("equipmentCode")
var equipmentCode: String = "", // var equipmentCode: String = "",
@SerializedName("consumptionTime") // @SerializedName("consumptionTime")
val consumptionTime: List<String?>? = listOf(), // val consumptionTime: List<String?>? = listOf(),
@SerializedName("createTime") // @SerializedName("createTime")
val createTime: List<String?>? = listOf(), // val createTime: List<String?>? = listOf(),
@SerializedName("memberFrom") // @SerializedName("memberFrom")
val memberFrom: Int? = 0, // val memberFrom: Int? = 0,
@SerializedName("pageNum") // @SerializedName("pageNum")
val pageNum: Int? = 0, var pageNum: Int? = 0,
@SerializedName("pageSize") // @SerializedName("pageSize")
val pageSize: Int? = 0, var pageSize: Int? = 0,
@SerializedName("param") // @SerializedName("param")
val `param`: String? = "" // val `param`: String? = "",
var name:String?=null,
var phone:String?=null
) : Parcelable ) : Parcelable
@@ -31,7 +31,7 @@ data class EquipmentUserInfo(
/** /**
* 会员Id * 会员Id
*/ */
val memberId: String? = "", val faceId: String? = "",
/** /**
* 餐盘编号 * 餐盘编号
*/ */
@@ -70,7 +70,7 @@ data class EquipmentUserInfo(
* 是否已绑定 * 是否已绑定
*/ */
fun isBound(): Boolean { fun isBound(): Boolean {
return memberId != null return faceId != null
} }
/** /**
@@ -78,6 +78,7 @@ data class SearchResult(
// @SerializedName("topUpBalance") // @SerializedName("topUpBalance")
// val topUpBalance: String? = "" // val topUpBalance: String? = ""
val id: String? = "", val id: String? = "",
val faceId: String? = "",
val name: String? = "", val name: String? = "",
val phone: String? = "", val phone: String? = "",
) : Parcelable ) : Parcelable
@@ -25,6 +25,6 @@ data class UserFaceModel(
val userId: String? = "", val userId: String? = "",
val faceFeatureStr: String? = "", val faceFeatureStr: String? = "",
val faceUpdateTimestamp:Long?=null,
val faceDeleted: Boolean?=false val faceDeleted: Boolean?=false
) : Parcelable ) : Parcelable
@@ -13,6 +13,7 @@ import com.sw.platecabinet.model.response.SearchResult
import com.sw.platecabinet.model.response.UserFaceModel import com.sw.platecabinet.model.response.UserFaceModel
import retrofit2.http.Body import retrofit2.http.Body
import retrofit2.http.Field import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.http.Header import retrofit2.http.Header
import retrofit2.http.POST import retrofit2.http.POST
@@ -118,9 +119,10 @@ interface ApiService {
* 餐盘解绑 * 餐盘解绑
*/ */
@POST @POST
@FormUrlEncoded
suspend fun plateUnbind( suspend fun plateUnbind(
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/sideboard/app/plateUnbind", @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/sideboard/app/plateUnbind",
@Field("id") id: Long @Field("id") id: Long?
): ApiResponse<Any?> ): ApiResponse<Any?>
/** /**
@@ -128,9 +130,10 @@ interface ApiService {
*/ */
@POST//("/shuwei-user/swclientUserInfoShop/selectList") @POST//("/shuwei-user/swclientUserInfoShop/selectList")
suspend fun searchUser( suspend fun searchUser(
@Url url: String = "${GlobalData.appBaseUrl}/shuwei-user/swclientUserInfoShop/selectList", // @Url url: String = "${GlobalData.appBaseUrl}/shuwei-user/swclientUserInfoShop/selectList",
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/getUserInfoByNameOrPhone",
@Body param: SearchParam @Body param: SearchParam
): ApiResponse<SearchResult> ): ApiResponse<List<SearchResult.Member>?>
// /** // /**
// * 通过餐盘号获取信息 // * 通过餐盘号获取信息
@@ -98,14 +98,14 @@ class RemoteRepository constructor(
return safeApiCall { apiService.plateBind(param = param) } return safeApiCall { apiService.plateBind(param = param) }
} }
suspend fun plateUnbind(id: Long ): ApiResponse<Any?> { suspend fun plateUnbind(id: Long?): ApiResponse<Any?> {
return safeApiCall { apiService.plateUnbind(id = id) } return safeApiCall { apiService.plateUnbind(id = id) }
} }
/** /**
* 用户信息模糊搜索 * 用户信息模糊搜索
*/ */
suspend fun searchUser(param: SearchParam): ApiResponse<SearchResult> { suspend fun searchUser(param: SearchParam): ApiResponse<List<SearchResult.Member>?> {
return safeApiCall { apiService.searchUser(param = param) } return safeApiCall { apiService.searchUser(param = param) }
} }
@@ -1,5 +1,6 @@
package com.sw.platecabinet.viewmodel package com.sw.platecabinet.viewmodel
import android.text.TextUtils
import com.sw.inbound.utils.DateTimeUtils import com.sw.inbound.utils.DateTimeUtils
import com.sw.platecabinet.GlobalData import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.GlobalData.globalEquipmentCode import com.sw.platecabinet.GlobalData.globalEquipmentCode
@@ -73,28 +74,36 @@ class SettingViewModel : BaseViewModel() {
/** /**
* 搜索会员信息列表 * 搜索会员信息列表
*/ */
fun getSearchMemberList(param: String, pageNum: Int = 1, pageSize: Int = 50) { fun getSearchMemberList(param:String, pageNum: Int = 1, pageSize: Int = 50) {
if (TextUtils.isEmpty(param)) return
currentPage = pageNum currentPage = pageNum
var name =""
var phone =""
val num = param.toIntOrNull()
if (num != null) {
phone = param
} else {
name = param
}
launch { launch {
val param = SearchParam( val searchParam = SearchParam(
appVersion = GlobalData.appVersion, // appVersion = GlobalData.appVersion,
param = param, name = name,
phone = phone,
pageNum = pageNum, pageNum = pageNum,
pageSize = pageSize pageSize = pageSize
) )
isLoading = true isLoading = true
val response = repository.searchUser(param) val response = repository.searchUser(searchParam)
isLoading = false isLoading = false
if (parseResponse(response)) { if (parseResponse(response)) {
response.data?.let { response.data?.let { list ->
canLoadMore = it.hasNextPage != false
val newList = it.list ?: emptyList()
if (pageNum == 1) { if (pageNum == 1) {
_searchMemberList.value = newList _searchMemberList.value = list
} else { } else {
_searchMemberList.value = _searchMemberList.value.plus(newList) _searchMemberList.value = _searchMemberList.value.plus(list)
} }
currentPage++ if (list.size >= pageSize) currentPage++
} }
} }
} }
@@ -149,7 +158,7 @@ class SettingViewModel : BaseViewModel() {
// } // }
// } // }
fun unbindPlate(id: Long, block:(Pair<Boolean?, ErrorInfo>)-> Unit) { fun unbindPlate(id: Long?, block:(Pair<Boolean?, ErrorInfo>)-> Unit) {
block(null to ErrorInfo()) block(null to ErrorInfo())
launchWithLoading { launchWithLoading {
val response = repository.plateUnbind(id) val response = repository.plateUnbind(id)
@@ -66,26 +66,32 @@ class UserViewModel : BaseViewModel() {
// 获取成功一次后缓存状态 // 获取成功一次后缓存状态
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
val list: List<UserFaceModel> = response.data ?: emptyList() val list: List<UserFaceModel> = response.data ?: emptyList()
if (list.isEmpty()) { if (pageNo==1&&list.isEmpty()) {
return@launchWithLoading return@launchWithLoading
} }
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
val faceEntityList = list.map { val faceEntityList = list.map {
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr)) FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr))
} }
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
faceApi.updateFaceData(pageNo, faceEntityList) faceApi.updateFaceData(pageNo, faceEntityList)
if (list.size >= pageSize) { if (list.size >= pageSize) {
faceTimestamp = list.last().faceUpdateTimestamp?:0
currentPageNo++ currentPageNo++
getUserFaceCache(currentPageNo) getUserFaceCache(currentPageNo)
return@withContext
} }
if (list.isNotEmpty()) {
faceTimestamp = list.last().faceUpdateTimestamp?:0
}
SpTool.setLastFaceTimestamp(faceTimestamp)
//activeEngine() //activeEngine()
} }
} }
} }
} }
private var faceTimestamp = 0L
/** /**
* 激活人脸识别引擎 * 激活人脸识别引擎
*/ */
@@ -144,7 +150,7 @@ class UserViewModel : BaseViewModel() {
fun getUserInfoById(memberId: String?, action:(EquipmentUserInfo?)->Unit={}) { fun getUserInfoById(memberId: String?, action:(EquipmentUserInfo?)->Unit={}) {
_currentUserInfo.value = null _currentUserInfo.value = null
launchWithLoading { launchWithLoading {
val loginParam = LoginParam(memberId = memberId) val loginParam = LoginParam(faceId = memberId)
val response = repository.equipmentBoxLogin(loginParam) val response = repository.equipmentBoxLogin(loginParam)
if (parseResponse(response)) { if (parseResponse(response)) {
_currentUserInfo.value = response.data _currentUserInfo.value = response.data
@@ -7,7 +7,8 @@
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:orientation="vertical" android:orientation="vertical"
android:paddingHorizontal="60dp" android:paddingHorizontal="60dp"
tools:context=".fragment.BindPlateFragment"> tools:context=".fragment.BindPlateFragment"
tools:background="@color/black">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"