package com.shuwei.intelligent.shelves import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.widget.LinearLayout import androidx.activity.viewModels import androidx.core.view.updateLayoutParams import androidx.core.widget.addTextChangedListener import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager import com.chad.library.adapter4.util.setOnDebouncedItemClick import com.scwang.smart.refresh.layout.constant.RefreshState import com.shuwei.intelligent.shelves.HomeActivity.Companion.DEVICE_INFO_CMD import com.shuwei.intelligent.shelves.adapter.SearchAdapter import com.shuwei.intelligent.shelves.base.BaseActivity import com.shuwei.intelligent.shelves.databinding.ActivityShelfBinding import com.shuwei.intelligent.shelves.model.GoodsModel import com.shuwei.intelligent.shelves.model.GoodsRecord import com.shuwei.intelligent.shelves.model.SendWeightEvent import com.shuwei.intelligent.shelves.model.ShelfModel import com.shuwei.intelligent.shelves.net.Loading import com.shuwei.intelligent.shelves.net.NetViewModel import com.shuwei.intelligent.shelves.net.RespData import com.shuwei.intelligent.shelves.net.UiState import com.shuwei.intelligent.shelves.serial.SerialPortManager import com.shuwei.intelligent.shelves.task.TaskManager import com.shuwei.intelligent.shelves.utils.DateTimeUtil import com.shuwei.intelligent.shelves.utils.KeyboardUtil import com.shuwei.intelligent.shelves.utils.ext.addOnActionSearchListener import com.shuwei.intelligent.shelves.utils.ext.clickWithDebounce import com.shuwei.intelligent.shelves.utils.ext.dp import com.shuwei.intelligent.shelves.utils.ext.gone import com.shuwei.intelligent.shelves.utils.ext.toJsonString import com.shuwei.intelligent.shelves.utils.ext.toast import com.shuwei.intelligent.shelves.utils.ext.visible import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @SuppressLint("NotifyDataSetChanged") class ShelfActivity : BaseActivity() { companion object { private const val TAG = "ShelfActivity" private const val YYYY_MM_DD__EEEE_HH_MM_SS = "yyyy年MM月dd日 EEEE***HH:mm:ss" const val SHELF_MODEL = "shelfModel" const val RECEIVER_DEVICE_INFO = "receiverDeviceInfo" const val SHELF_WEIGHT = "shelfWeight" const val SHELF_INDEX = "shelfIndex" const val PAGE_SIZE = 100 } private lateinit var binding: ActivityShelfBinding private var shelfModel: ShelfModel? = null private var clickIndex: Int = -1 private var realWeight: Int = 0 private var pageNo: Int = 1 private val viewModel: NetViewModel by viewModels() @SuppressLint("UnspecifiedRegisterReceiverFlag") @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityShelfBinding.inflate(layoutInflater) setContentView(binding.root) EventBus.getDefault().register(this) // tvFoodWeight =binding.tvFoodWeight shelfModel = intent.getSerializableExtra(SHELF_MODEL) as ShelfModel? shelfModel?.let { binding.tvShelfName.text = it.shelfName binding.tvFoodName.text = if (it.goodsName.isNullOrBlank()) "-" else it.goodsName realWeight = ((it.weight ?: 0.0) * 1000).toInt() // realWeight = (HomeActivity.getRealWeight() * 1000).toInt() binding.tvFoodWeight.text = "${realWeight}克" } initRecyclerView() binding.etInputFood.run { addOnActionSearchListener { if (text.isNullOrBlank()) { toast(hint.toString()) return@addOnActionSearchListener } pageNo = 1 getGoodsList() KeyboardUtil.hideKeyboard(context, this) } addTextChangedListener(afterTextChanged = { editable -> if (editable.isNullOrBlank()) { pageNo = 1 getGoodsList() } }) } binding.btnConfirm.clickWithDebounce { if (clickIndex < 0) { toast("请选择食材") return@clickWithDebounce } val currentGoodsId = list[clickIndex].goodsId ?: "" val data = ShelfModel( shelfName = shelfModel?.shelfName, goodsId = currentGoodsId, goodsName = list[clickIndex].goodsName, weight = realWeight / 1000.0, overdueDay = list[clickIndex].overdueDay, createTime = if (shelfModel?.goodsId == currentGoodsId) null else DateTimeUtil.formatDateTime(dateTime = Date()) ) val intent = Intent().apply { putExtra(SHELF_MODEL, data) } setResult(RESULT_OK, intent) finish() } binding.root.setOnClickListener { v -> KeyboardUtil.hideKeyboard(v.context, v) } binding.btnClearZero.setOnClickListener { v -> lifecycleScope.launch { val shelfNo = shelfModel?.deviceNo ?: 0 val hex = shelfNo.toString(16).padStart(2, '0').uppercase() Log.d(TAG, "onCreate: hex=$hex") val zeroClearingCmd = "${HomeActivity.HEADER}0401${hex}${HomeActivity.FOOTER}" Log.d(TAG, "onCreate: zeroClearingCmd=$zeroClearingCmd") SerialPortManager.send(zeroClearingCmd) //清零 realWeight = 0 // binding.tvFoodWeight.text = "${realWeight}克" SerialPortManager.send(DEVICE_INFO_CMD) Loading.show(this@ShelfActivity) v.postDelayed({ Loading.dismiss() }, 5000) } KeyboardUtil.hideKeyboard(v.context, v) } lifecycleScope.launch { SerialPortManager.send(DEVICE_INFO_CMD) repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.getGoodsListUiState.collect { state -> when (state) { is UiState.Loading -> showProgress() is UiState.Success<*> -> updateUI(state.data) is UiState.Error -> showError(state.msg) else -> {} } } } } // registerReceiver(receiver, IntentFilter(RECEIVER_DEVICE_INFO + shelfModel?.deviceNo)) binding.ivBack?.setOnClickListener { finish() } binding.refreshLayout.let { it.setEnableRefresh(true) it.setEnableLoadMore(false) it.setOnRefreshListener { pageNo = 1 getGoodsList() } it.setOnLoadMoreListener { getGoodsList() } } getGoodsList() TaskManager.startDeviceTask() } private fun finishRefresh() { binding.refreshLayout.let { if (it.state == RefreshState.Refreshing) { it.finishRefresh(500) } else if (binding.refreshLayout.state == RefreshState.Loading) { it.finishLoadMore(500) } else { } } } private fun getGoodsList() { viewModel.getGoodsList( canteenId = App.getInstance().canteenId, goodsName = binding.etInputFood.text.trim().toString(), pageNo = pageNo, pageSize = PAGE_SIZE ) } private fun showProgress() { Loading.show(this) } @SuppressLint("NotifyDataSetChanged") private fun updateUI(data: RespData<*>) { binding.include?.root?.gone() finishRefresh() binding.root.postDelayed({ Loading.dismiss() }, 200) Log.d(TAG, "updateUI: ${data.toJsonString()}") if (data.result !is GoodsRecord) { if (pageNo == 1) { loadEmptyView() } return } if (data.result.records.isNullOrEmpty()) { if (pageNo == 1) { loadEmptyView() } return } var firstOne:GoodsModel?=null if (pageNo == 1) { if (shelfModel?.goodsId.isNullOrBlank().not()) { firstOne = list.firstOrNull { it.goodsId == shelfModel?.goodsId } if (firstOne == null) { firstOne = GoodsModel( goodsId = shelfModel?.goodsId, goodsName = shelfModel?.goodsName, isClicked = true ) } } list.clear() } val records = data.result.records if (pageNo == 1) { firstOne?.let { one -> val filterResult = records.firstOrNull{one.goodsId == it.goodsId } if (filterResult != null) { records.remove(filterResult) } clickIndex = 0 list.add(one) } } list.addAll(records) val enableLoadMore = records.size >= PAGE_SIZE binding.refreshLayout.setEnableLoadMore(enableLoadMore) if (enableLoadMore) { pageNo++ } searchAdapter.notifyDataSetChanged() } private fun showError(message: String) { finishRefresh() Loading.dismiss() toast(message) if (pageNo == 1) { loadEmptyView() } } // private val receiver = object : BroadcastReceiver() { // override fun onReceive(context: Context?, intent: Intent?) { // intent?.let { // if (it.action == RECEIVER_DEVICE_INFO + shelfModel?.deviceNo) { // val weight = it.getDoubleExtra(SHELF_WEIGHT, 0.0) // Log.d(TAG, "getDeviceInfo:onReceive: weight=$weight") // realWeight = (weight * 1000).toInt() // binding.tvFoodWeight.text = "${realWeight}克" // } // } // } // } override fun onDestroy() { // unregisterReceiver(receiver) EventBus.getDefault().unregister(this) TaskManager.cancelDeviceTask() super.onDestroy() } private val list: MutableList = mutableListOf() private val searchAdapter by lazy { SearchAdapter(list).apply { setOnDebouncedItemClick { adapter, v, position -> this@ShelfActivity.clickIndex = position list.forEach { it.isClicked = false } list[position].isClicked = true notifyDataSetChanged() binding.tvFoodName.text = list[position].goodsName KeyboardUtil.hideKeyboard(v.context, v) } } } private fun initRecyclerView() { binding.rvSearch.run { layoutManager = GridLayoutManager(this@ShelfActivity, 2) adapter = searchAdapter } } private fun updateDateTime() { val sdf = SimpleDateFormat(YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA) val dateTime = sdf.format(Date()) val arr = dateTime.split("***") updateLeftStatus(arr[0]) updateRightStatus(arr[1]) } private val handler = Handler(Looper.getMainLooper()) private val updateTask = object : Runnable { override fun run() { updateDateTime() handler.postDelayed(this, 1000) } } override fun onResume() { super.onResume() hideStatusBar() handler.post(updateTask) } override fun onPause() { super.onPause() handler.removeCallbacks(updateTask) } @SuppressLint("NotifyDataSetChanged") private fun loadEmptyView() { list.clear() searchAdapter.notifyDataSetChanged() binding.include?.let { it.root.visible() it.root.setOnClickListener { pageNo = 1 getGoodsList() } it.ivEmptyIcon.setImageResource(R.drawable.ic_empty_gray) it.ivEmptyIcon.updateLayoutParams { val swDpValue = resources?.configuration?.smallestScreenWidthDp ?: 0 width = if (swDpValue > 600) 200.dp else 120.dp } } binding.refreshLayout.run { setEnableRefresh(false) setEnableLoadMore(false) } } @Subscribe(threadMode = ThreadMode.MAIN) public fun receiveWeightEvent(event: SendWeightEvent) { if (event.shelfNo == (shelfModel?.deviceNo ?: 0)) { binding.tvFoodWeight.text = "${event.weight}克" } } }