增加定时任务更新货柜数据过期状态

This commit is contained in:
2026-01-13 09:27:41 +08:00
parent 9a222037ea
commit 5d58cdc4cf
6 changed files with 227 additions and 173 deletions
@@ -32,8 +32,6 @@ import com.shuwei.intelligent.shelves.net.RespData
import com.shuwei.intelligent.shelves.net.UiState import com.shuwei.intelligent.shelves.net.UiState
import com.shuwei.intelligent.shelves.net.apiService import com.shuwei.intelligent.shelves.net.apiService
import com.shuwei.intelligent.shelves.serial.SerialPortManager import com.shuwei.intelligent.shelves.serial.SerialPortManager
import com.shuwei.intelligent.shelves.task.SyncTask
import com.shuwei.intelligent.shelves.task.TaskManager
import com.shuwei.intelligent.shelves.utils.HexUtils import com.shuwei.intelligent.shelves.utils.HexUtils
import com.shuwei.intelligent.shelves.utils.IntervalExecutor import com.shuwei.intelligent.shelves.utils.IntervalExecutor
import com.shuwei.intelligent.shelves.utils.binaryToHex import com.shuwei.intelligent.shelves.utils.binaryToHex
@@ -42,9 +40,8 @@ import com.shuwei.intelligent.shelves.utils.ext.gone
import com.shuwei.intelligent.shelves.utils.ext.toJsonString import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import com.shuwei.intelligent.shelves.utils.ext.toast import com.shuwei.intelligent.shelves.utils.ext.toast
import com.shuwei.intelligent.shelves.utils.ext.visible import com.shuwei.intelligent.shelves.utils.ext.visible
import com.shuwei.intelligent.shelves.utils.f2C
import com.shuwei.intelligent.shelves.utils.hexToBinary import com.shuwei.intelligent.shelves.utils.hexToBinary
import com.shuwei.intelligent.shelves.utils.hexToDec import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
@@ -85,7 +82,8 @@ class HomeActivity : BaseActivity() {
//410激活码 //410激活码
// const val ACTIVE_CMD = "${HEADER}000281C5D70A7D42894EA17650F5D0BB516838E7863C9ABD766C38958AFF0F3C062D${FOOTER}" // const val ACTIVE_CMD = "${HEADER}000281C5D70A7D42894EA17650F5D0BB516838E7863C9ABD766C38958AFF0F3C062D${FOOTER}"
//1楼餐厅 //1楼餐厅
const val ACTIVE_CMD = "${HEADER}000281C5D70A7D428B44A57454F5DACA241938938B4B9CBD73673E9C8E7FC0C4992D${FOOTER}" const val ACTIVE_CMD =
"${HEADER}000281C5D70A7D428B44A57454F5DACA241938938B4B9CBD73673E9C8E7FC0C4992D${FOOTER}"
//华氏温度单位 //华氏温度单位
const val F_TEMP_CMD = "${HEADER}0F01390000${FOOTER}" const val F_TEMP_CMD = "${HEADER}0F01390000${FOOTER}"
@@ -174,7 +172,8 @@ class HomeActivity : BaseActivity() {
// TaskManager.startTask() // TaskManager.startTask()
startTask() saveGoodsTask()
overdueTask()
// var androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) // var androidId = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
//// androidId = "d0e7a2d5f25c775c" //// androidId = "d0e7a2d5f25c775c"
@@ -598,7 +597,9 @@ class HomeActivity : BaseActivity() {
lifecycleScope.launch { lifecycleScope.launch {
SerialPortManager.close() SerialPortManager.close()
} }
TaskManager.cancelTask() // TaskManager.cancelTask()
saveTaskJob?.cancel()
overdueTaskJob?.cancel()
EventBus.getDefault().unregister(this) EventBus.getDefault().unregister(this)
super.onDestroy() super.onDestroy()
} }
@@ -736,15 +737,44 @@ class HomeActivity : BaseActivity() {
shelfAdapter.notifyItemChanged(list.indexOf(item)) shelfAdapter.notifyItemChanged(list.indexOf(item))
} }
private val intervalExecutor by lazy { IntervalExecutor() } private val taskExecutor by lazy { IntervalExecutor() }
private var saveTaskJob: Job?=null
private fun startTask() { /**
intervalExecutor.startIntervalTaskWithInitialDelay(2*1000L,2*1000L) { * 保存定时任务
*/
private fun saveGoodsTask() {
saveTaskJob = taskExecutor.startIntervalTaskWithInitialDelay(1 * 60 * 1000L, 5 * 60 * 1000L) {
saveShelfGoodsList() saveShelfGoodsList()
} }
} }
private suspend fun saveShelfGoodsList() { private var overdueTaskJob: Job?=null
/**
* 过期时间定时任务
*/
private fun overdueTask() {
overdueTaskJob = taskExecutor.startIntervalTaskWithInitialDelay(5 * 1000L, 10 * 1000L) {
updateOverdueState()
}
}
private fun updateOverdueState() {
viewModel.updateOverdueState { state, items ->
if (items.isNullOrEmpty()) return@updateOverdueState
list.forEachIndexed { index, model ->
//接口过期状态变化后更新状态
if (items[index].overdue != model.overdue) {
model.overdue = items[index].overdue
shelfAdapter.notifyItemChanged(index)
log("更新编号为${model.deviceNo}物品:${model.goodsName}的过期状态:${model.overdue}")
}
}
}
}
private fun saveShelfGoodsList() {
log("performSync: list:${list.toJsonString()}") log("performSync: list:${list.toJsonString()}")
val submitList = list.sortedBy { it.deviceNo } val submitList = list.sortedBy { it.deviceNo }
submitList.forEach { submitList.forEach {
@@ -764,14 +794,8 @@ class HomeActivity : BaseActivity() {
it.goodsList = submitList it.goodsList = submitList
} }
log("performSync: body:${body.toJsonString()}") log("performSync: body:${body.toJsonString()}")
try { viewModel.saveShelfGoodsList(body)
val resp = apiService.saveShelfGoodsList(body = body)
log("performSync: resp:${resp.toJsonString()}")
} catch (e: Exception) {
e.printStackTrace()
}
} }
} }
@@ -30,7 +30,6 @@ import com.shuwei.intelligent.shelves.net.Loading
import com.shuwei.intelligent.shelves.net.NetViewModel import com.shuwei.intelligent.shelves.net.NetViewModel
import com.shuwei.intelligent.shelves.net.RespData import com.shuwei.intelligent.shelves.net.RespData
import com.shuwei.intelligent.shelves.net.UiState import com.shuwei.intelligent.shelves.net.UiState
import com.shuwei.intelligent.shelves.task.TaskManager
import com.shuwei.intelligent.shelves.utils.DateTimeUtil import com.shuwei.intelligent.shelves.utils.DateTimeUtil
import com.shuwei.intelligent.shelves.utils.KeyboardUtil import com.shuwei.intelligent.shelves.utils.KeyboardUtil
import com.shuwei.intelligent.shelves.utils.ext.addOnActionSearchListener import com.shuwei.intelligent.shelves.utils.ext.addOnActionSearchListener
@@ -176,7 +175,7 @@ class ShelfActivity : BaseActivity() {
} }
getGoodsList() getGoodsList()
TaskManager.startDeviceTask() // TaskManager.startDeviceTask()
} }
private fun finishRefresh() { private fun finishRefresh() {
@@ -281,7 +280,7 @@ class ShelfActivity : BaseActivity() {
override fun onDestroy() { override fun onDestroy() {
// unregisterReceiver(receiver) // unregisterReceiver(receiver)
EventBus.getDefault().unregister(this) EventBus.getDefault().unregister(this)
TaskManager.cancelDeviceTask() // TaskManager.cancelDeviceTask()
super.onDestroy() super.onDestroy()
} }
@@ -1,10 +1,13 @@
package com.shuwei.intelligent.shelves.net package com.shuwei.intelligent.shelves.net
import android.util.Log
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.shuwei.intelligent.shelves.App import com.shuwei.intelligent.shelves.App
import com.shuwei.intelligent.shelves.model.ShelfBody import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.model.ShelfModel
import com.shuwei.intelligent.shelves.net.HttpManager.Companion.instance import com.shuwei.intelligent.shelves.net.HttpManager.Companion.instance
import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -105,6 +108,21 @@ class NetViewModel : ViewModel() {
} }
} }
fun updateOverdueState(block:(Boolean, List<ShelfModel>?)-> Unit) {
viewModelScope.launch {
runCatching {
val response = apiService.getShelfList(deviceId = App.deviceId)
if (response.isSuccess()) {
block(true, response.data?.containerGoodsList)
} else {
block(false, emptyList())
}
}.onFailure {
block(false, null)
}
}
}
// fun saveShelfGoodsList(body: ShelfBody) { // fun saveShelfGoodsList(body: ShelfBody) {
// viewModelScope.launch { // viewModelScope.launch {
// _saveShelfGoodsListUiState.value = UiState.Loading // _saveShelfGoodsListUiState.value = UiState.Loading
@@ -150,4 +168,17 @@ class NetViewModel : ViewModel() {
} }
} }
fun saveShelfGoodsList(body: ShelfBody) {
viewModelScope.launch {
runCatching {
val resp = apiService.saveShelfGoodsList(body = body)
Log.d("NetViewModel", "saveShelfGoodsList,performSync: resp:${resp.toJsonString()}")
}.onFailure {
it.printStackTrace()
Log.d("NetViewModel", "saveShelfGoodsList异常:${it.message}")
}
}
}
} }
@@ -1,32 +1,32 @@
package com.shuwei.intelligent.shelves.task //package com.shuwei.intelligent.shelves.task
//
import android.content.Context //import android.content.Context
import android.util.Log //import android.util.Log
import androidx.work.CoroutineWorker //import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters //import androidx.work.WorkerParameters
import com.shuwei.intelligent.shelves.activity.HomeActivity //import com.shuwei.intelligent.shelves.activity.HomeActivity
import com.shuwei.intelligent.shelves.serial.SerialPortManager //import com.shuwei.intelligent.shelves.serial.SerialPortManager
//
class SyncDeviceTask(appContext: Context, workerParams: WorkerParameters) : //class SyncDeviceTask(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) { // CoroutineWorker(appContext, workerParams) {
//
companion object { // companion object {
private const val TAG = "SyncDeviceTask" // private const val TAG = "SyncDeviceTask"
} // }
//
override suspend fun doWork(): Result { // override suspend fun doWork(): Result {
return try { // return try {
// 执行后台任务逻辑 // // 执行后台任务逻辑
Log.d(TAG, "doWork: ----------SyncDeviceTask----------") // Log.d(TAG, "doWork: ----------SyncDeviceTask----------")
SerialPortManager.send(HomeActivity.DEVICE_INFO_CMD) // SerialPortManager.send(HomeActivity.DEVICE_INFO_CMD)
//
TaskManager.startDeviceTask() // TaskManager.startDeviceTask()
//
Result.success() // Result.success()
} catch (e: Exception) { // } catch (e: Exception) {
e.printStackTrace() // e.printStackTrace()
Result.retry() // Result.retry()
} // }
} // }
//
} //}
@@ -1,67 +1,67 @@
package com.shuwei.intelligent.shelves.task //package com.shuwei.intelligent.shelves.task
//
import android.content.Context //import android.content.Context
import android.util.Log //import android.util.Log
import androidx.work.CoroutineWorker //import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters //import androidx.work.WorkerParameters
import com.shuwei.intelligent.shelves.App //import com.shuwei.intelligent.shelves.App
import com.shuwei.intelligent.shelves.activity.HomeActivity //import com.shuwei.intelligent.shelves.activity.HomeActivity
import com.shuwei.intelligent.shelves.model.ShelfBody //import com.shuwei.intelligent.shelves.model.ShelfBody
import com.shuwei.intelligent.shelves.net.apiService //import com.shuwei.intelligent.shelves.net.apiService
import com.shuwei.intelligent.shelves.utils.ext.toJsonString //import com.shuwei.intelligent.shelves.utils.ext.toJsonString
import kotlinx.coroutines.Dispatchers //import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext //import kotlinx.coroutines.withContext
//
class SyncTask(appContext: Context, workerParams: WorkerParameters) : //class SyncTask(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) { // CoroutineWorker(appContext, workerParams) {
//
companion object { // companion object {
private const val TAG = "SyncTask" // private const val TAG = "SyncTask"
} // }
//
override suspend fun doWork(): Result { // override suspend fun doWork(): Result {
return try { // return try {
// 执行后台任务逻辑 // // 执行后台任务逻辑
performSync() // performSync()
//
TaskManager.startTask() // TaskManager.startTask()
//
Result.success() // Result.success()
} catch (e: Exception) { // } catch (e: Exception) {
e.printStackTrace() // e.printStackTrace()
Result.retry() // Result.retry()
} // }
} // }
//
private suspend fun performSync() { // private suspend fun performSync() {
withContext(Dispatchers.IO) { // withContext(Dispatchers.IO) {
val list = HomeActivity.list // val list = HomeActivity.list
Log.d(TAG, "performSync: list:${list.toJsonString()}") // Log.d(TAG, "performSync: list:${list.toJsonString()}")
val submitList = list.sortedBy { it.deviceNo } // val submitList = list.sortedBy { it.deviceNo }
submitList.forEach {
if (it.goodsId.isNullOrBlank()) {
it.weight = it.weightBak
}
}
// submitList.forEach { // submitList.forEach {
// if (it.goodsId.isNullOrBlank()) {
// it.weight = it.weightBak
// }
// }
//// submitList.forEach {
//// it.temperature = HomeActivity.showTemperatureC
//// it.humidity = HomeActivity.showHumidity
//// }
// val body = ShelfBody().also {
// it.deviceId = App.deviceId
// it.canteenId = App.canteenId
// it.temperature = HomeActivity.showTemperatureC // it.temperature = HomeActivity.showTemperatureC
// it.humidity = HomeActivity.showHumidity // it.humidity = HomeActivity.showHumidity
// it.goodsList = submitList
// } // }
val body = ShelfBody().also { // Log.d(TAG, "performSync: body:${body.toJsonString()}")
it.deviceId = App.deviceId // try {
it.canteenId = App.canteenId // val resp = apiService.saveShelfGoodsList(body = body)
it.temperature = HomeActivity.showTemperatureC // Log.d(TAG, "performSync: resp:${resp.toJsonString()}")
it.humidity = HomeActivity.showHumidity // } catch (e: Exception) {
it.goodsList = submitList // e.printStackTrace()
} // }
Log.d(TAG, "performSync: body:${body.toJsonString()}") // }
try { // }
val resp = apiService.saveShelfGoodsList(body = body) //
Log.d(TAG, "performSync: resp:${resp.toJsonString()}") //}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
@@ -1,59 +1,59 @@
package com.shuwei.intelligent.shelves.task //package com.shuwei.intelligent.shelves.task
//
import androidx.work.ExistingWorkPolicy //import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequestBuilder //import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager //import androidx.work.WorkManager
import com.shuwei.intelligent.shelves.App //import com.shuwei.intelligent.shelves.App
import java.util.concurrent.TimeUnit //import java.util.concurrent.TimeUnit
//
object TaskManager { //object TaskManager {
const val TASK_NAME = "IntelligentShelvesSyncTask" // const val TASK_NAME = "IntelligentShelvesSyncTask"
const val DEVICE_TASK_NAME = "IntelligentShelvesDeviceTask" // const val DEVICE_TASK_NAME = "IntelligentShelvesDeviceTask"
//
fun startTask() { // fun startTask() {
val nextRequest = OneTimeWorkRequestBuilder<SyncTask>() // val nextRequest = OneTimeWorkRequestBuilder<SyncTask>()
.setInitialDelay(2, TimeUnit.MINUTES) // .setInitialDelay(2, TimeUnit.MINUTES)
// .setInitialDelay(30, TimeUnit.SECONDS) //// .setInitialDelay(30, TimeUnit.SECONDS)
// .setInitialDelay(10, TimeUnit.MINUTES) //// .setInitialDelay(10, TimeUnit.MINUTES)
// .setInputData(inputData) //// .setInputData(inputData)
.build()
WorkManager.getInstance(App.getInstance())
.enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
// val constraints = Constraints.Builder()
// .setRequiredNetworkType(NetworkType.CONNECTED)
// .setRequiresBatteryNotLow(true)
// .build() // .build()
// val syncRequest = PeriodicWorkRequestBuilder<SyncTask>( // WorkManager.getInstance(App.getInstance())
// 3L, TimeUnit.MINUTES, // 最小间隔15分钟 // .enqueueUniqueWork(TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
// 3L, TimeUnit.MINUTES // 弹性时间窗口 //
// ) //// val constraints = Constraints.Builder()
// .setConstraints(constraints) //// .setRequiredNetworkType(NetworkType.CONNECTED)
//// .setRequiresBatteryNotLow(true)
//// .build()
//// val syncRequest = PeriodicWorkRequestBuilder<SyncTask>(
//// 3L, TimeUnit.MINUTES, // 最小间隔15分钟
//// 3L, TimeUnit.MINUTES // 弹性时间窗口
//// )
//// .setConstraints(constraints)
//// .build()
//// WorkManager.getInstance(App.get())
//// .enqueueUniquePeriodicWork(
//// TASK_NAME,
//// ExistingPeriodicWorkPolicy.KEEP,
//// syncRequest
//// )
// }
//
// fun cancelTask() {
// WorkManager.getInstance(App.getInstance())
// .cancelUniqueWork(TASK_NAME)
// }
//
// fun startDeviceTask() {
// val nextRequest = OneTimeWorkRequestBuilder<SyncDeviceTask>()
// .setInitialDelay(2, TimeUnit.MINUTES)
// .build() // .build()
// WorkManager.getInstance(App.get()) // WorkManager.getInstance(App.getInstance())
// .enqueueUniquePeriodicWork( // .enqueueUniqueWork(DEVICE_TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
// TASK_NAME, // }
// ExistingPeriodicWorkPolicy.KEEP, //
// syncRequest // fun cancelDeviceTask() {
// ) // WorkManager.getInstance(App.getInstance())
} // .cancelUniqueWork(DEVICE_TASK_NAME)
// }
fun cancelTask() { //
WorkManager.getInstance(App.getInstance()) //}
.cancelUniqueWork(TASK_NAME)
}
fun startDeviceTask() {
val nextRequest = OneTimeWorkRequestBuilder<SyncDeviceTask>()
.setInitialDelay(2, TimeUnit.MINUTES)
.build()
WorkManager.getInstance(App.getInstance())
.enqueueUniqueWork(DEVICE_TASK_NAME, ExistingWorkPolicy.REPLACE, nextRequest)
}
fun cancelDeviceTask() {
WorkManager.getInstance(App.getInstance())
.cancelUniqueWork(DEVICE_TASK_NAME)
}
}