调整了部分问题

This commit is contained in:
zxj
2025-07-23 14:22:11 +08:00
parent 5ad82eb224
commit 7fd2ccb960
28 changed files with 486 additions and 210 deletions
@@ -6,6 +6,11 @@ object GlobalData {
*/ */
var globalEquipmentCode: String = "202501171634" var globalEquipmentCode: String = "202501171634"
/**
* app版本号
*/
var appVersion: String = ""
/** /**
* 横排数量 * 横排数量
*/ */
@@ -17,9 +22,11 @@ object GlobalData {
var arrayVertical: Int = 11 var arrayVertical: Int = 11
/** /**
* 排列方式 * 排列方式 0 垂直 1 水平
*/ */
var arrayMode: Int = 0 var arrayMode: Int = 1
} }
/** /**
@@ -1,6 +1,7 @@
package com.sw.platecabinet package com.sw.platecabinet
import com.sw.plate.App import com.sw.plate.App
import com.sw.plate.utils.AppUtil
import timber.log.Timber import timber.log.Timber
class MyApp : App() { class MyApp : App() {
@@ -12,5 +13,14 @@ class MyApp : App() {
super.onCreate() super.onCreate()
Timber.plant(Timber.DebugTree()) Timber.plant(Timber.DebugTree())
Timber.d("初始化") Timber.d("初始化")
initGlobalData()
}
/**
* 初始化全局数据
*/
private fun initGlobalData() {
GlobalData.appVersion = AppUtil.getAppVersionName(this)
GlobalData.globalEquipmentCode = "202501171634"
} }
} }
@@ -5,24 +5,34 @@ import android.content.Context
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils import android.text.TextUtils
import android.view.KeyEvent
import android.view.View import android.view.View
import android.view.WindowInsetsController import android.view.WindowInsetsController
import android.view.WindowManager import android.view.WindowManager
import android.widget.TextView import android.widget.TextView
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.sw.inbound.utils.DateTimeUtils import com.sw.inbound.utils.DateTimeUtils
import com.sw.plate.utils.ScanGunKeyEventHelper
import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.comn.SerialApi
import com.sw.plate.utils.comn.SerialPortManager
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.ext.setClickListeners import com.sw.platecabinet.ext.setClickListeners
import com.sw.platecabinet.utils.PermissionHelper import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.view.CustomDialog import com.sw.platecabinet.view.CustomDialog
import com.sw.platecabinet.viewmodel.SettingViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber
/** /**
* activity 基类 * activity 基类
@@ -34,6 +44,8 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
private var timeJob: Job? = null private var timeJob: Job? = null
private var mDialogWaiting: CustomDialog? = null private var mDialogWaiting: CustomDialog? = null
private val permissionHelpers = mutableMapOf<Int, PermissionHelper>() private val permissionHelpers = mutableMapOf<Int, PermissionHelper>()
protected var keyEventHelper: ScanGunKeyEventHelper? = null
private val viewModel by viewModels<SettingViewModel>()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -49,6 +61,38 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
updateTime() updateTime()
registerDataChange() registerDataChange()
initialize() initialize()
registerKeyEvent()
}
/**
* 监听扫描枪扫描事件
*/
protected fun registerKeyEvent() {
keyEventHelper =
ScanGunKeyEventHelper(context, object : ScanGunKeyEventHelper.OnScanSuccessListener {
override fun onScanSuccess(barcode: String?) {
Timber.d("onScanSuccess barcode = $barcode")
if (barcode == null) return
handleScanKeyInfo(barcode)
}
})
}
/**
* 处理扫描枪数据
*/
protected open fun handleScanKeyInfo(scanInfo: String) {
viewModel.findByPlateNumber(plateNumber = scanInfo)
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (keyEventHelper != null) {
if (keyEventHelper!!.isScanGunEvent(event)) {
keyEventHelper!!.analysisKeyEvent(event)
return true
}
}
return super.dispatchKeyEvent(event)
} }
fun updateTime() { fun updateTime() {
@@ -74,10 +118,16 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
} }
} }
/**
* 左侧日期双击
*/
open fun onLeftDoubleClick() { open fun onLeftDoubleClick() {
} }
/**
* 右侧时间双击
*/
open fun onRightDoubleClick() { open fun onRightDoubleClick() {
MainActivity.start(context, pageType = PageType.SETTING_LIST) MainActivity.start(context, pageType = PageType.SETTING_LIST)
} }
@@ -139,6 +189,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
} }
private fun enforceImmersiveMode() { private fun enforceImmersiveMode() {
// 持续强制隐藏系统栏(防止手势触发) // 持续强制隐藏系统栏(防止手势触发)
window.decorView.postDelayed({ window.decorView.postDelayed({
@@ -177,10 +228,62 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
protected abstract fun initialize() protected abstract fun initialize()
protected open fun registerDataChange() {} /**
* 注册数据监听
*/
protected open fun registerDataChange() {
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
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("柜门打开失败")
}
})
} else {
viewModel.getEquipmentList()
}
}
}
lifecycleScope.launch {
viewModel.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
firstInfo.plateNumber = currentUserInfo?.plateNumber ?: ""
MainActivity.start(
context = context,
pageType = PageType.BIND_PLATE,
equipmentUserInfo = firstInfo
)
}
}
}
}
override fun onDestroy() { override fun onDestroy() {
timeJob?.cancel() timeJob?.cancel()
keyEventHelper?.onDestroy()
super.onDestroy() super.onDestroy()
} }
} }
@@ -32,6 +32,7 @@ import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.utils.PermissionHelper import com.sw.platecabinet.utils.PermissionHelper
import com.sw.platecabinet.viewmodel.UserViewModel import com.sw.platecabinet.viewmodel.UserViewModel
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@@ -73,8 +74,9 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
} }
override fun registerDataChange() { override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch { lifecycleScope.launch {
viewModel.currentUserInfo.collect { viewModel.currentUserInfo.drop(1).collect {
Timber.d("currentUserInfo it = $it") Timber.d("currentUserInfo it = $it")
if (it != null) { if (it != null) {
ToastUtils.showToast("登录成功") ToastUtils.showToast("登录成功")
@@ -83,15 +85,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
} }
} }
} }
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
} }
private fun checkCameraPermission() { private fun checkCameraPermission() {
@@ -314,7 +307,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
) )
) )
.rotation(windowManager.defaultDisplay.rotation) .rotation(windowManager.defaultDisplay.rotation)
.additionalRotation(90) // 角度 .additionalRotation(0) // 角度
.previewSize(recognizeViewModel.loadPreviewSize()) .previewSize(recognizeViewModel.loadPreviewSize())
.specificCameraId(previewConfig.rgbCameraId) .specificCameraId(previewConfig.rgbCameraId)
.isMirror(true) .isMirror(true)
@@ -7,6 +7,7 @@ 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.viewmodel.UserViewModel import com.sw.platecabinet.viewmodel.UserViewModel
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@@ -34,28 +35,23 @@ class LoginByPwdActivity : BaseActivity<ActivityLoginByPwdBinding>() {
binding.tvFaceRec.setOnClickListener { binding.tvFaceRec.setOnClickListener {
val intent = Intent(this, LoginByFaceActivity::class.java) val intent = Intent(this, LoginByFaceActivity::class.java)
startActivity(intent) startActivity(intent)
// handleScanKeyInfo(binding.etPwd.text.toString())
} }
} }
override fun registerDataChange() { override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch { lifecycleScope.launch {
viewModel.currentUserInfo.collect { viewModel.currentUserInfo
Timber.d("currentUserInfo it = $it") .drop(1)
if (it != null) { .collect {
ToastUtils.showToast("登录成功") Timber.d("currentUserInfo it = $it")
MainActivity.start(context, pageType = PageType.PLATE_CABINET_FULL) if (it != null) {
finish() // ToastUtils.showToast("登录成功")
MainActivity.start(context, pageType = PageType.PLATE_OPEN)
finish()
}
} }
}
}
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
} }
} }
@@ -13,9 +13,12 @@ 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
typealias Callback = (String) -> Unit
class MainActivity : BaseActivity<ActivityMainBinding>() { class MainActivity : BaseActivity<ActivityMainBinding>() {
private lateinit var fragmentHelper: FragmentHelper private lateinit var fragmentHelper: FragmentHelper
private var pageType = PageType.SETTING_LIST private var pageType = PageType.SETTING_LIST
private var callback: Callback? = null
override fun inflateViewBinding(): ActivityMainBinding { override fun inflateViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater) return ActivityMainBinding.inflate(layoutInflater)
@@ -65,8 +68,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun onRightDoubleClick() { override fun onRightDoubleClick() {
} }
override fun handleScanKeyInfo(scanInfo: String) {
if (callback != null) {
callback!!.invoke(scanInfo)
}
}
fun registerKeyEventInfo(callback: Callback) {
this.callback = callback
}
override fun registerDataChange() {
super.registerDataChange()
}
} }
/** /**
* 界面类型 * 界面类型
*/ */
@@ -25,7 +25,18 @@ class GenericPageAdapter<T, VB : ViewBinding>(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder {
val view = LayoutInflater.from(parent.context).inflate(pageLayoutId, parent, false) val view = LayoutInflater.from(parent.context).inflate(pageLayoutId, parent, false)
return PageViewHolder(view) val holder = PageViewHolder(view)
// 在创建ViewHolder时设置ItemDecoration,只设置一次
holder.childRecyclerView.addItemDecoration(
GridSpacingItemDecoration(
spanCount = 2,
spacing = view.context.dpToPx(12),
includeEdge = true // 包含边缘间距
)
)
return holder
} }
override fun onBindViewHolder(holder: PageViewHolder, position: Int) { override fun onBindViewHolder(holder: PageViewHolder, position: Int) {
@@ -35,19 +46,13 @@ class GenericPageAdapter<T, VB : ViewBinding>(
override fun getItemCount(): Int = pages.size override fun getItemCount(): Int = pages.size
inner class PageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class PageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val childRecyclerView: RecyclerView = itemView.findViewById(R.id.childRecyclerView) val childRecyclerView: RecyclerView = itemView.findViewById(R.id.childRecyclerView)
init {
childRecyclerView.layoutManager = GridLayoutManager(itemView.context, 2)
}
fun bind(items: List<T>) { fun bind(items: List<T>) {
childRecyclerView.layoutManager = GridLayoutManager(itemView.context, 2)
childRecyclerView.addItemDecoration(
GridSpacingItemDecoration(
spanCount = 2, // 2列
spacing = itemView.context.dpToPx(6), // 12dp
includeEdge = true // 包含边缘间距
)
)
childRecyclerView.adapter = childRecyclerView.adapter =
GenericItemAdapter(items, itemBindingInflater, itemBindCallback) GenericItemAdapter(items, itemBindingInflater, itemBindCallback)
} }
@@ -8,9 +8,13 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.sw.platecabinet.R import com.sw.platecabinet.R
import com.sw.platecabinet.view.CustomDialog import com.sw.platecabinet.view.CustomDialog
import com.sw.platecabinet.viewmodel.SettingViewModel
import kotlinx.coroutines.launch
abstract class BaseFragment<VB : ViewBinding>( abstract class BaseFragment<VB : ViewBinding>(
private val bindingInflater: (inflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean) -> VB private val bindingInflater: (inflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean) -> VB
@@ -18,6 +22,7 @@ abstract class BaseFragment<VB : ViewBinding>(
private var _binding: VB? = null private var _binding: VB? = null
protected val binding get() = _binding!! protected val binding get() = _binding!!
private var mDialogWaiting: CustomDialog? = null private var mDialogWaiting: CustomDialog? = null
protected val viewModel by viewModels<SettingViewModel>()
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@@ -33,7 +38,17 @@ abstract class BaseFragment<VB : ViewBinding>(
/** /**
* 注册数据变化监听 * 注册数据变化监听
*/ */
open fun registerDataChange() {} open fun registerDataChange() {
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
}
abstract fun initialize() abstract fun initialize()
@@ -4,14 +4,15 @@ import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.text.Editable import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher import android.text.TextWatcher
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.platecabinet.R import com.sw.platecabinet.R
import com.sw.platecabinet.activity.MainActivity
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
@@ -21,7 +22,7 @@ import com.sw.platecabinet.ext.maskName
import com.sw.platecabinet.ext.maskPhone import com.sw.platecabinet.ext.maskPhone
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.viewmodel.SettingViewModel import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@@ -32,7 +33,6 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
FragmentBindPlateBinding::inflate FragmentBindPlateBinding::inflate
) { ) {
private lateinit var adapter: GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding> private lateinit var adapter: GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding>
private val viewModel by viewModels<SettingViewModel>()
internal val ARG_PARAM1 = "param1" internal val ARG_PARAM1 = "param1"
private var info: EquipmentUserInfo? = null private var info: EquipmentUserInfo? = null
private var checkedItem: SearchResult.Member? = null private var checkedItem: SearchResult.Member? = null
@@ -53,6 +53,9 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
info = it.getParcelable(ARG_PARAM1) info = it.getParcelable(ARG_PARAM1)
info?.let { info?.let {
binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}" binding.tvNum.text = "${it.equipmentName}-${it.equipmentBoxCode}"
if (!TextUtils.isEmpty(it.plateNumber)) {
binding.etCode.text = Editable.Factory.getInstance().newEditable(it.plateNumber)
}
} }
} }
initView() initView()
@@ -88,6 +91,12 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
} }
} }
}) })
(activity as MainActivity).registerKeyEventInfo {
binding.etCode.text = Editable.Factory.getInstance().newEditable(it)
}
}
private fun initListener() {
binding.etUserInfo.addTextChangedListener(object : TextWatcher { binding.etUserInfo.addTextChangedListener(object : TextWatcher {
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
private val debounceDelay = 500L // 延迟 500 毫秒 private val debounceDelay = 500L // 延迟 500 毫秒
@@ -120,9 +129,6 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
}, debounceDelay) }, debounceDelay)
} }
}) })
}
private fun initListener() {
binding.llBind.setOnClickListener { binding.llBind.setOnClickListener {
if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) { if (info == null || info!!.equipmentCode?.isEmpty() == true || info!!.equipmentBoxCode?.isEmpty() == true) {
ToastUtils.showToast("传入的设备信息异常") ToastUtils.showToast("传入的设备信息异常")
@@ -156,13 +162,14 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
* 监听数据变化 * 监听数据变化
*/ */
override fun registerDataChange() { override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch { lifecycleScope.launch {
viewModel.searchMemberList.collect { viewModel.searchMemberList.drop(1).collect {
adapter.updateData(it) adapter.updateData(it)
} }
} }
lifecycleScope.launch { lifecycleScope.launch {
viewModel.bindStateChange.collect { viewModel.bindStateChange.drop(1).collect {
if (it.first == null) return@collect // 解绑状态过滤 if (it.first == null) return@collect // 解绑状态过滤
val errorInfo = it.second val errorInfo = it.second
if (errorInfo.isSuccess()) { if (errorInfo.isSuccess()) {
@@ -173,15 +180,6 @@ class BindPlateFragment : BaseFragment<FragmentBindPlateBinding>(
} }
} }
} }
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
} }
private fun createAdapter(): GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding> { private fun createAdapter(): GenericItemAdapter<SearchResult.Member, ItemSearchUserInfoBinding> {
@@ -1,24 +1,28 @@
package com.sw.platecabinet.fragment package com.sw.platecabinet.fragment
import android.view.View import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
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.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.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.GenericPageAdapter import com.sw.platecabinet.adapter.GenericPageAdapter
import com.sw.platecabinet.adapter.GridSpacingItemDecoration
import com.sw.platecabinet.adapter.dpToPx
import com.sw.platecabinet.databinding.FragmentSettingListBinding import com.sw.platecabinet.databinding.FragmentSettingListBinding
import com.sw.platecabinet.databinding.ItemBindViewBinding import com.sw.platecabinet.databinding.ItemBindViewBinding
import com.sw.platecabinet.ext.formatNumber 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.viewmodel.SettingViewModel import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import kotlin.math.ceil import kotlin.math.ceil
@@ -28,35 +32,47 @@ import kotlin.math.ceil
*/ */
class SettingListFragment : class SettingListFragment :
BaseFragment<FragmentSettingListBinding>(FragmentSettingListBinding::inflate) { BaseFragment<FragmentSettingListBinding>(FragmentSettingListBinding::inflate) {
private val viewModel: SettingViewModel by viewModels<SettingViewModel>()
private lateinit var pageAdapter: GenericPageAdapter<EquipmentUserInfo, ItemBindViewBinding> /**
private lateinit var itemAdapter: GenericItemAdapter<EquipmentUserInfo, ItemBindViewBinding> * 需要横向滚动的adapter
private val itemsPerPage = 22 // 每行2个,每列11个,共22个 */
private var pageAdapter: GenericPageAdapter<EquipmentUserInfo, ItemBindViewBinding>? = null
/**
* 垂直滚动的adapter
*/
private var itemAdapter: GenericItemAdapter<EquipmentUserInfo, ItemBindViewBinding>? = null
private val itemsPerPage = GlobalData.arrayCross * GlobalData.arrayVertical // 每行2个,每列11个,共22个
override fun registerDataChange() { override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch { lifecycleScope.launch {
viewModel.equipmentList.collect { it -> viewModel.equipmentList.drop(1).collect { it ->
Timber.d("registerDateChange updateAdapter it = $it") Timber.d("registerDateChange updateAdapter it = $it")
updateAdapter(it) updateAdapter(it)
} }
} }
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
} }
override fun initialize() { override fun initialize() {
binding.mainRecyclerView.apply { binding.mainRecyclerView.apply {
layoutManager = LinearLayoutManager(context) if (GlobalData.arrayCross > 2) {
layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
pageAdapter = createAdapter() pageAdapter = createPageAdapter()
adapter = pageAdapter adapter = pageAdapter
} else {
layoutManager = GridLayoutManager(context, 2)
// 添加间距装饰(12dp)
addItemDecoration(
GridSpacingItemDecoration(
spanCount = 2,
spacing = requireContext().dpToPx(12),
includeEdge = true // 包含边缘间距
)
)
itemAdapter = createItemAdapter()
adapter = itemAdapter
}
} }
} }
@@ -66,94 +82,115 @@ class SettingListFragment :
viewModel.getEquipmentList() viewModel.getEquipmentList()
} }
private fun createAdapter(): GenericPageAdapter<EquipmentUserInfo, ItemBindViewBinding> { private fun createItemAdapter(): GenericItemAdapter<EquipmentUserInfo, ItemBindViewBinding> {
return GenericItemAdapter(
items = emptyList(),
bindingInflater = ItemBindViewBinding::inflate,
bindCallback = { item, position ->
setItemInfo(item, position)
}
)
}
private fun createPageAdapter(): GenericPageAdapter<EquipmentUserInfo, ItemBindViewBinding> {
return GenericPageAdapter( return GenericPageAdapter(
pages = emptyList(), pages = emptyList(),
pageLayoutId = R.layout.page_item_layout, pageLayoutId = R.layout.page_item_layout,
itemBindingInflater = ItemBindViewBinding::inflate, itemBindingInflater = ItemBindViewBinding::inflate,
itemBindCallback = { item, position -> itemBindCallback = { item, position ->
this.tvNum.text = formatNumber(item.equipmentBoxCode ?: "") setItemInfo(item, position)
if (item.isBound()) {
val date = DateTimeUtils.parseDateTime(item.updateTime)
val timeInMillis = date?.time ?: 0L
val isOldTime = DateTimeUtils.isMoreThan36HoursFromNow(timeInMillis)
this.llRoot.setBackgroundResource(R.drawable.grid_item_bind)
this.tvNum.setTextColor(resources.getColor(R.color.bind_4E535D))
this.tvLastTime.setTextColor(
if (isOldTime) resources.getColor(R.color.bind_time_old) else resources.getColor(
R.color.bind_585868
)
)
this.llOpen.setBackgroundResource(R.drawable.grid_button_bind)
this.tvOpen.setTextColor(resources.getColor(R.color.bind_F0C8B4))
this.llBindInfo.visibility = View.VISIBLE
this.tvUnbind.visibility = View.GONE
this.tvName.text = item.name.maskName()
this.tvLastTime.text = DateTimeUtils.getTimeAgo(date)
} else {
this.llRoot.setBackgroundResource(R.drawable.grid_item_unbind)
this.tvNum.setTextColor(resources.getColor(R.color.bind_F0C8B4))
this.llOpen.setBackgroundResource(R.drawable.grid_button_unbind)
this.tvOpen.setTextColor(resources.getColor(R.color.unbind_32283C))
this.llBindInfo.visibility = View.GONE
this.tvUnbind.visibility = View.VISIBLE
}
this.llRoot.setOnClickListener {
Timber.d("itemClick llRoot ${item.name}, position = $position")
if (item.isBound()) {
MainActivity.start(
requireContext(),
pageType = PageType.UNBIND_PLATE,
equipmentUserInfo = item
)
} else {
MainActivity.start(
requireContext(),
pageType = PageType.BIND_PLATE,
equipmentUserInfo = item
)
}
}
this.llOpen.setOnClickListener {
Timber.d("itemClick llOpen equipmentBoxCode = ${item.equipmentBoxCode}")
val equipmentBoxCode: Int = item.equipmentBoxCode?.toInt() ?: -1
if (equipmentBoxCode < 0) {
ToastUtils.showToast("餐盘柜编号错误")
return@setOnClickListener
}
SerialApi.openPlate(equipmentBoxCode, object : SerialPortManager.SendCallback {
override fun onSuccess() {
MainActivity.start(requireContext(), pageType = PageType.PLATE_OPEN)
}
override fun onFail(e: Exception?) {
ToastUtils.showToast("柜门打开失败")
}
})
}
} }
) )
} }
fun updateAdapter(items: List<EquipmentUserInfo>) { private fun ItemBindViewBinding.setItemInfo(
// if (GlobalData.arrayCross > 2) { item: EquipmentUserInfo,
var pages = if (items.size > itemsPerPage) { position: Int
items.chunked(itemsPerPage) { ) {
convertToColumnFirst(it, 11) this.tvNum.text = formatNumber(item.equipmentBoxCode ?: "")
} if (item.isBound()) {
} else { val date = DateTimeUtils.parseDateTime(item.updateTime)
listOf( val timeInMillis = date?.time ?: 0L
// 根据条件判断是否需要重新排列 val isOldTime = DateTimeUtils.isMoreThan36HoursFromNow(timeInMillis)
// items
convertToColumnFirst(items, 11) this.llRoot.setBackgroundResource(R.drawable.grid_item_bind)
this.tvNum.setTextColor(resources.getColor(R.color.bind_4E535D))
this.tvLastTime.setTextColor(
if (isOldTime) resources.getColor(R.color.bind_time_old) else resources.getColor(
R.color.bind_585868
)
) )
this.llOpen.setBackgroundResource(R.drawable.grid_button_bind)
this.tvOpen.setTextColor(resources.getColor(R.color.bind_F0C8B4))
this.llBindInfo.visibility = View.VISIBLE
this.tvUnbind.visibility = View.GONE
this.tvName.text = item.name.maskName()
this.tvLastTime.text = DateTimeUtils.getTimeAgo(date)
} else {
this.llRoot.setBackgroundResource(R.drawable.grid_item_unbind)
this.tvNum.setTextColor(resources.getColor(R.color.bind_F0C8B4))
this.llOpen.setBackgroundResource(R.drawable.grid_button_unbind)
this.tvOpen.setTextColor(resources.getColor(R.color.unbind_32283C))
this.llBindInfo.visibility = View.GONE
this.tvUnbind.visibility = View.VISIBLE
} }
pageAdapter.updatePages(pages) this.llRoot.setOnClickListener {
// }else{ Timber.d("itemClick llRoot ${item.name}, position = $position")
// if (item.isBound()) {
// } MainActivity.start(
requireContext(),
pageType = PageType.UNBIND_PLATE,
equipmentUserInfo = item
)
} else {
MainActivity.start(
requireContext(),
pageType = PageType.BIND_PLATE,
equipmentUserInfo = item
)
}
}
this.llOpen.setOnClickListener {
Timber.d("itemClick llOpen equipmentBoxCode = ${item.equipmentBoxCode}")
val equipmentBoxCode: Int = item.equipmentBoxCode?.toInt() ?: -1
if (equipmentBoxCode < 0) {
ToastUtils.showToast("餐盘柜编号错误")
return@setOnClickListener
}
showWaitingDialog("请稍等")
SerialApi.openPlate(equipmentBoxCode, object : SerialPortManager.SendCallback {
override fun onSuccess() {
hideWaitingDialog()
MainActivity.start(requireContext(), pageType = PageType.PLATE_OPEN)
}
override fun onFail(e: Exception?) {
hideWaitingDialog()
ToastUtils.showToast("柜门打开失败")
}
})
}
}
fun updateAdapter(items: List<EquipmentUserInfo>) {
if (GlobalData.arrayCross > 2) {
var pages = if (items.size > itemsPerPage) {
items.chunked(itemsPerPage) {
convertToColumnFirst(it, 11)
}
} else {
listOf(
// 根据条件判断是否需要重新排列
// items
convertToColumnFirst(items, 11)
)
}
pageAdapter?.updatePages(pages)
} else {
itemAdapter?.updateData(items)
}
binding.mainRecyclerView.scrollToPosition(0)
} }
/** /**
@@ -1,7 +1,6 @@
package com.sw.platecabinet.fragment package com.sw.platecabinet.fragment
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.viewModels
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
@@ -9,7 +8,7 @@ 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.response.EquipmentUserInfo import com.sw.platecabinet.model.response.EquipmentUserInfo
import com.sw.platecabinet.viewmodel.SettingViewModel import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
/** /**
@@ -20,7 +19,6 @@ class UnBindPlateFragment private constructor() : BaseFragment<FragmentUnbindPla
) { ) {
internal val ARG_PARAM1 = "param1" internal val ARG_PARAM1 = "param1"
private var info: EquipmentUserInfo? = null private var info: EquipmentUserInfo? = null
private val viewModel by viewModels<SettingViewModel>()
companion object { companion object {
@JvmStatic @JvmStatic
@@ -58,8 +56,9 @@ class UnBindPlateFragment private constructor() : BaseFragment<FragmentUnbindPla
} }
override fun registerDataChange() { override fun registerDataChange() {
super.registerDataChange()
lifecycleScope.launch { lifecycleScope.launch {
viewModel.bindStateChange.collect { viewModel.bindStateChange.drop(1).collect {
if (it.first == null) return@collect // 绑定状态过滤 if (it.first == null) return@collect // 绑定状态过滤
val errorInfo = it.second val errorInfo = it.second
if (errorInfo.isSuccess()) { if (errorInfo.isSuccess()) {
@@ -70,14 +69,5 @@ class UnBindPlateFragment private constructor() : BaseFragment<FragmentUnbindPla
} }
} }
} }
lifecycleScope.launch {
viewModel.showLoading.collect {
if (it) {
showWaitingDialog("")
} else {
hideWaitingDialog()
}
}
}
} }
} }
@@ -11,16 +11,20 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class BindParam( data class BindParam(
/**
* app版本号
*/
var appVersion: String = "",
/**
* 设备ID
*/
@SerializedName("equipmentCode")
var equipmentCode: String = "",
/** /**
*设备盒子编号 *设备盒子编号
*/ */
@SerializedName("equipmentBoxCode") @SerializedName("equipmentBoxCode")
val equipmentBoxCode: String? = "", val equipmentBoxCode: String? = null,
/**
*设备编号
*/
@SerializedName("equipmentCode")
val equipmentCode: String? = "",
/** /**
* *
* 会员Id * 会员Id
@@ -1,6 +1,7 @@
package com.sw.platecabinet.model.request package com.sw.platecabinet.model.request
import android.os.Parcelable import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
/** /**
@@ -8,8 +9,13 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class EquipmentParam( data class EquipmentParam(
/**
* app版本号
*/
var appVersion: String = "",
/** /**
* 设备ID * 设备ID
*/ */
var equipmentCode: String = "" @SerializedName("equipmentCode")
var equipmentCode: String = "",
) : Parcelable ) : Parcelable
@@ -10,11 +10,15 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class LoginParam( data class LoginParam(
/**
* app版本号
*/
var appVersion: String = "",
/** /**
* 设备ID * 设备ID
*/ */
@SerializedName("equipmentCode") @SerializedName("equipmentCode")
val equipmentCode: String? = "", var equipmentCode: String = "",
/** /**
* 会员信息 * 会员信息
*/ */
@@ -10,6 +10,15 @@ import kotlinx.parcelize.Parcelize
*/ */
@Parcelize @Parcelize
data class SearchParam( data class SearchParam(
/**
* app版本号
*/
var appVersion: String = "",
/**
* 设备ID
*/
@SerializedName("equipmentCode")
var equipmentCode: String = "",
@SerializedName("consumptionTime") @SerializedName("consumptionTime")
val consumptionTime: List<String?>? = listOf(), val consumptionTime: List<String?>? = listOf(),
@SerializedName("createTime") @SerializedName("createTime")
@@ -3,6 +3,7 @@ package com.sw.platecabinet.model.response
import android.os.Parcelable import android.os.Parcelable
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import com.sw.platecabinet.GlobalData
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
/** /**
@@ -50,7 +51,7 @@ data class EquipmentUserInfo(
* 餐盘编号 * 餐盘编号
*/ */
@SerializedName("plateNumber") @SerializedName("plateNumber")
val plateNumber: String? = "", var plateNumber: String? = "",
/** /**
* *
* 更新时间 * 更新时间
@@ -59,7 +60,17 @@ data class EquipmentUserInfo(
val updateTime: String? = "" val updateTime: String? = ""
) : Parcelable { ) : Parcelable {
/**
* 是否已绑定
*/
fun isBound(): Boolean { fun isBound(): Boolean {
return memberId != null return memberId != null
} }
/**
* 是否是其他设备
*/
fun isOtherEquipment(): Boolean {
return GlobalData.globalEquipmentCode != equipmentCode
}
} }
@@ -5,6 +5,9 @@ import android.os.Parcelable
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
/**
* 搜索会员信息结果
*/
@Parcelize @Parcelize
data class SearchResult( data class SearchResult(
@SerializedName("endRow") @SerializedName("endRow")
@@ -19,13 +19,20 @@ interface ApiService {
* 生成token * 生成token
*/ */
@GET("/shuwei-zhct/scales/generateToken") @GET("/shuwei-zhct/scales/generateToken")
suspend fun generateToken(@Query("deviceId") deviceId: String): ApiResponse<String> suspend fun generateToken(
@Query("deviceId") deviceId: String,
@Query("appVersion") appVersion: String,
@Query("equipmentCode") equipmentCode: String
): ApiResponse<String>
/** /**
* 获取人脸数据 * 获取人脸数据
*/ */
@GET("/shuwei-zhct/scales/getUserFaceCache") @GET("/shuwei-zhct/scales/getUserFaceCache")
suspend fun getUserFaceCache(): ApiResponse<List<UserFaceModel>> suspend fun getUserFaceCache(
@Query("appVersion") appVersion: String,
@Query("equipmentCode") equipmentCode: String
): ApiResponse<List<UserFaceModel>>
/** /**
* 餐盘用户信息获取 * 餐盘用户信息获取
@@ -51,4 +58,9 @@ interface ApiService {
@POST("/shuwei-user/swclientUserInfoShop/selectList") @POST("/shuwei-user/swclientUserInfoShop/selectList")
suspend fun searchUser(@Body param: SearchParam): ApiResponse<SearchResult> suspend fun searchUser(@Body param: SearchParam): ApiResponse<SearchResult>
/**
* 通过餐盘号获取信息
*/
@POST("/shuwei-zhct/swEquipmentRelUser/findByPlateNumber")
suspend fun findByPlateNumber(@Body param: BindParam): ApiResponse<EquipmentUserInfo>
} }
@@ -1,5 +1,6 @@
package com.sw.platecabinet.repository package com.sw.platecabinet.repository
import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.model.request.BindParam import com.sw.platecabinet.model.request.BindParam
import com.sw.platecabinet.model.request.EquipmentParam import com.sw.platecabinet.model.request.EquipmentParam
import com.sw.platecabinet.model.request.LoginParam import com.sw.platecabinet.model.request.LoginParam
@@ -20,14 +21,25 @@ class RemoteRepository constructor(
* 生成token * 生成token
*/ */
suspend fun generateToken(deviceId: String): ApiResponse<String> { suspend fun generateToken(deviceId: String): ApiResponse<String> {
return safeApiCall { apiService.generateToken(deviceId) } return safeApiCall {
apiService.generateToken(
deviceId,
GlobalData.appVersion,
GlobalData.globalEquipmentCode
)
}
} }
/** /**
* 获取人脸数据 * 获取人脸数据
*/ */
suspend fun getUserFaceCache(): ApiResponse<List<UserFaceModel>> { suspend fun getUserFaceCache(): ApiResponse<List<UserFaceModel>> {
return safeApiCall { apiService.getUserFaceCache() } return safeApiCall {
apiService.getUserFaceCache(
GlobalData.appVersion,
GlobalData.globalEquipmentCode
)
}
} }
/** /**
@@ -57,4 +69,11 @@ class RemoteRepository constructor(
suspend fun searchUser(param: SearchParam): ApiResponse<SearchResult> { suspend fun searchUser(param: SearchParam): ApiResponse<SearchResult> {
return safeApiCall { apiService.searchUser(param) } return safeApiCall { apiService.searchUser(param) }
} }
/**
* 通过餐盘编号获取绑定信息
*/
suspend fun findByPlateNumber(param: BindParam): ApiResponse<EquipmentUserInfo> {
return safeApiCall { apiService.findByPlateNumber(param) }
}
} }
@@ -102,8 +102,6 @@ object DateTimeUtils {
return when { return when {
hours < 1 -> "刚刚" hours < 1 -> "刚刚"
hours < 24 -> "${hours}小时前" hours < 24 -> "${hours}小时前"
// hours < 48 -> "昨天"
// hours < 72 -> "前天"
else -> { else -> {
val days = hours / 24 val days = hours / 24
"${days}天前" "${days}天前"
@@ -1,5 +1,7 @@
package com.sw.platecabinet.viewmodel package com.sw.platecabinet.viewmodel
import com.sw.plate.utils.ToastUtils
import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.GlobalData.globalEquipmentCode import com.sw.platecabinet.GlobalData.globalEquipmentCode
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
@@ -18,6 +20,9 @@ class SettingViewModel : BaseViewModel() {
private val _searchMemberList = MutableStateFlow<List<SearchResult.Member>>(emptyList()) private val _searchMemberList = MutableStateFlow<List<SearchResult.Member>>(emptyList())
val searchMemberList: StateFlow<List<SearchResult.Member>> = _searchMemberList val searchMemberList: StateFlow<List<SearchResult.Member>> = _searchMemberList
private val _currentUserInfo = MutableStateFlow<EquipmentUserInfo?>(null)
val currentUserInfo: StateFlow<EquipmentUserInfo?> = _currentUserInfo
var currentPage = 1 var currentPage = 1
var isLoading = false var isLoading = false
var canLoadMore = true var canLoadMore = true
@@ -34,10 +39,11 @@ class SettingViewModel : BaseViewModel() {
*/ */
fun getEquipmentList(equipmentCode: String = globalEquipmentCode) { fun getEquipmentList(equipmentCode: String = globalEquipmentCode) {
launchWithLoading { launchWithLoading {
val param = EquipmentParam(equipmentCode = equipmentCode) val param =
EquipmentParam(appVersion = GlobalData.appVersion, equipmentCode = equipmentCode)
val response = repository.getEquipmentList(param) val response = repository.getEquipmentList(param)
if (parseResponse(response)) { if (parseResponse(response)) {
_equipmentList.value = response.data ?: emptyList() _equipmentList.value = response.data?.plus(response.data) ?: emptyList()
} }
} }
} }
@@ -49,6 +55,7 @@ class SettingViewModel : BaseViewModel() {
currentPage = pageNum currentPage = pageNum
launch { launch {
val param = SearchParam( val param = SearchParam(
appVersion = GlobalData.appVersion,
param = param, param = param,
pageNum = pageNum, pageNum = pageNum,
pageSize = pageSize pageSize = pageSize
@@ -79,6 +86,7 @@ class SettingViewModel : BaseViewModel() {
) { ) {
launchWithLoading { launchWithLoading {
val bindParam = BindParam( val bindParam = BindParam(
appVersion = GlobalData.appVersion,
equipmentBoxCode = equipmentBoxCode, equipmentBoxCode = equipmentBoxCode,
equipmentCode = equipmentCode, equipmentCode = equipmentCode,
memberId = memberId, memberId = memberId,
@@ -99,6 +107,7 @@ class SettingViewModel : BaseViewModel() {
) { ) {
launchWithLoading { launchWithLoading {
val bindParam = BindParam( val bindParam = BindParam(
appVersion = GlobalData.appVersion,
equipmentBoxCode = equipmentBoxCode, equipmentBoxCode = equipmentBoxCode,
equipmentCode = equipmentCode equipmentCode = equipmentCode
) )
@@ -110,4 +119,30 @@ class SettingViewModel : BaseViewModel() {
} }
} }
} }
fun findByPlateNumber(
plateNumber: String,
equipmentCode: String = globalEquipmentCode
) {
launchWithLoading {
val bindParam = BindParam(
appVersion = GlobalData.appVersion,
plateNumber = plateNumber,
equipmentCode = equipmentCode
)
val response = repository.findByPlateNumber(bindParam)
if (response.code == 200) {
if (response.data?.isOtherEquipment() == true) {
ToastUtils.showToast("")
return@launchWithLoading
}
_currentUserInfo.value = response.data
} else {
_currentUserInfo.value = EquipmentUserInfo(
plateNumber = plateNumber,
equipmentCode = equipmentCode
)
}
}
}
} }
@@ -7,6 +7,7 @@ import com.sw.plate.utils.Base64
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.FaceApi import com.sw.plate.utils.arcface.FaceApi
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
import com.sw.platecabinet.GlobalData
import com.sw.platecabinet.GlobalData.globalEquipmentCode import com.sw.platecabinet.GlobalData.globalEquipmentCode
import com.sw.platecabinet.GlobalKey import com.sw.platecabinet.GlobalKey
import com.sw.platecabinet.model.request.LoginParam import com.sw.platecabinet.model.request.LoginParam
@@ -101,6 +102,7 @@ class UserViewModel : BaseViewModel() {
fun loginWithPwd(equipmentCode: String = globalEquipmentCode, phone: String, password: String) { fun loginWithPwd(equipmentCode: String = globalEquipmentCode, phone: String, password: String) {
launchWithLoading { launchWithLoading {
val loginParam = LoginParam( val loginParam = LoginParam(
appVersion = GlobalData.appVersion,
equipmentCode = equipmentCode, equipmentCode = equipmentCode,
phone = phone, phone = phone,
password = password password = password
@@ -118,6 +120,7 @@ class UserViewModel : BaseViewModel() {
fun getUserInfoById(equipmentCode: String = globalEquipmentCode, memberId: Int) { fun getUserInfoById(equipmentCode: String = globalEquipmentCode, memberId: Int) {
launchWithLoading { launchWithLoading {
val loginParam = LoginParam( val loginParam = LoginParam(
appVersion = GlobalData.appVersion,
equipmentCode = equipmentCode, equipmentCode = equipmentCode,
memberId = memberId memberId = memberId
) )
@@ -86,7 +86,7 @@
android:layout_marginEnd="20dp" android:layout_marginEnd="20dp"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:hint="输入校验码" android:hint="输入校验码"
android:inputType="textPassword" android:inputType="numberPassword"
android:maxLines="1" android:maxLines="1"
android:textColor="#F3D2BD" android:textColor="#F3D2BD"
android:textColorHint="#7B6D6A" android:textColorHint="#7B6D6A"
@@ -12,7 +12,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="80dp" android:layout_marginTop="60dp"
android:text="柜体编号" android:text="柜体编号"
android:textColor="#ff7c6d6a" android:textColor="#ff7c6d6a"
android:textSize="20sp" /> android:textSize="20sp" />
@@ -36,7 +36,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="52dp" android:layout_marginTop="48dp"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
@@ -73,10 +73,13 @@
android:background="@color/transparent" android:background="@color/transparent"
android:gravity="center" android:gravity="center"
android:maxLines="1" android:maxLines="1"
android:hint="请录入餐盘码"
android:inputType="number"
android:textColor="#fff0c8b4" android:textColor="#fff0c8b4"
android:textColorHint="#ff7c6d6a"
android:textSize="26sp" android:textSize="26sp"
android:textStyle="bold" android:textStyle="bold"
tools:text="100888" /> tools:text="" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@@ -139,7 +142,7 @@
android:id="@+id/ll_bind" android:id="@+id/ll_bind"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_marginTop="28dp" android:layout_marginTop="24dp"
android:background="@drawable/shape_btn_bg" android:background="@drawable/shape_btn_bg"
android:gravity="center"> android:gravity="center">
@@ -12,7 +12,7 @@
<ImageView <ImageView
android:layout_width="280dp" android:layout_width="280dp"
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginTop="92dp" android:layout_marginTop="80dp"
android:src="@mipmap/ic_unbind_img" /> android:src="@mipmap/ic_unbind_img" />
<TextView <TextView
@@ -179,7 +179,7 @@
<LinearLayout <LinearLayout
android:id="@+id/ll_unbind" android:id="@+id/ll_unbind"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="80dp" android:layout_height="70dp"
android:layout_marginTop="187dp" android:layout_marginTop="187dp"
android:background="@drawable/shape_btn_bg" android:background="@drawable/shape_btn_bg"
android:gravity="center"> android:gravity="center">
@@ -155,12 +155,10 @@ public class ScanGunKeyEventHelper {
* @return * @return
*/ */
public boolean isScanGunEvent(KeyEvent event) { public boolean isScanGunEvent(KeyEvent event) {
// L.e("event===" + event.getDevice().getName() + L.e("event===" + event.getDevice().getName() +
// "===Char===" + event.getCharacters() + "===Char===" + event.getCharacters() +
// "===Action===" + event.getAction()); "===Action===" + event.getAction());
// return event.getDevice().getName().equals(mDeviceName); return event.getDevice().getName().equals(mDeviceName);
return true;
} }
@@ -8,9 +8,9 @@ import com.sw.plate.App;
import com.sw.plate.utils.L; import com.sw.plate.utils.L;
import com.sw.plate.utils.arcface.face.model.FacePreviewInfo; import com.sw.plate.utils.arcface.face.model.FacePreviewInfo;
import com.sw.plate.utils.arcface.facedb.FaceDatabase; import com.sw.plate.utils.arcface.facedb.FaceDatabase;
import com.sw.plate.utils.arcface.facedb.dao.FaceDao;
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity; import com.sw.plate.utils.arcface.facedb.entity.FaceEntity;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class FaceApi { public class FaceApi {
@@ -27,13 +27,13 @@ public class FaceApi {
* @param list * @param list
*/ */
public void updateFaceData(int index, List<FaceEntity> list) { public void updateFaceData(int index, List<FaceEntity> list) {
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
if (index == 0) { if (index == 0) {
FaceDatabase.getInstance(App.getContext()).faceDao().deleteAll(); faceDao.deleteAll();
FaceDatabase.getInstance(App.getContext()).faceDao().resetId(); faceDao.resetId();
} }
List<FaceEntity> faceEntities = new ArrayList<>(); faceDao.insert(list);
FaceDatabase.getInstance(App.getContext()).faceDao().insert(faceEntities);
} }
/** /**
@@ -4,8 +4,6 @@ import static com.sw.plate.utils.CabinetLockCommand.generateOpenCommand;
import android.serialport.SerialPort; import android.serialport.SerialPort;
import com.sw.plate.utils.ToastUtils;
public class SerialApi { public class SerialApi {
private static String path = "/dev/ttyS2"; private static String path = "/dev/ttyS2";
private static int speed = 19200; private static int speed = 19200;
@@ -15,9 +13,9 @@ public class SerialApi {
public static void init() { public static void init() {
serialPortManager = SerialPortManager.instance(); serialPortManager = SerialPortManager.instance();
serialPort = serialPortManager.open(new Device(path, String.valueOf(speed))); serialPort = serialPortManager.open(new Device(path, String.valueOf(speed)));
if (serialPort == null) { // if (serialPort == null) {
ToastUtils.showToast("打开串口失败"); // ToastUtils.showToast("打开串口失败");
} // }
} }
/** /**
@@ -31,6 +29,7 @@ public class SerialApi {
init(); init();
} }
if (serialPort == null) { if (serialPort == null) {
callback.onFail(new Exception("打开串口失败"));
return; return;
} }
serialPortManager.sendCommand(generateOpenCommand(boxNumber), callback); serialPortManager.sendCommand(generateOpenCommand(boxNumber), callback);