refactor(base): 重构基础组件和数据库访问层
- 修复 BaseActivity 中 rightIconActon 方法名拼写错误 - 重命名 appViewModel 为 dbViewModel 以统一数据库访问实例 - 优化 BaseApp 中的共享偏好设置获取逻辑 - 移除 GlobalData 中硬编码的应用ID和SDK密钥 - 重命名 NetworkUtils 为 NetworkUtil 并增强网络连接检测 - 重构 RemoteRepository 中的API调用方法结构 - 在多个Activity和Fragment中统一使用dbViewModel替代appViewModel - 优化食品列表合并烹饪中条目的逻辑处理 - 调整文件上传时的媒体类型定义 - 清理注释和代码结构以提高可维护性
This commit is contained in:
@@ -92,13 +92,13 @@ open class BaseActivity : AppCompatActivity() {
|
|||||||
titleBarAction: ((FrameLayout) -> Unit)? = null,
|
titleBarAction: ((FrameLayout) -> Unit)? = null,
|
||||||
backAction: ((ImageView) -> Unit)? = null,
|
backAction: ((ImageView) -> Unit)? = null,
|
||||||
titleAction: ((TextView) -> Unit)? = null,
|
titleAction: ((TextView) -> Unit)? = null,
|
||||||
rightIconActon: ((ImageView) -> Unit)? = null
|
rightIconAction: ((ImageView) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
binding.llTitleBar.visible()
|
binding.llTitleBar.visible()
|
||||||
titleBarAction?.invoke(binding.llTitleBar)
|
titleBarAction?.invoke(binding.llTitleBar)
|
||||||
backAction?.invoke(binding.ivBack)
|
backAction?.invoke(binding.ivBack)
|
||||||
titleAction?.invoke(binding.tvTitle)
|
titleAction?.invoke(binding.tvTitle)
|
||||||
rightIconActon?.invoke(binding.ivRightIcon)
|
rightIconAction?.invoke(binding.ivRightIcon)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setHeaderBgVisible(show: Boolean) {
|
fun setHeaderBgVisible(show: Boolean) {
|
||||||
@@ -182,7 +182,7 @@ open class BaseActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
|
|
||||||
val netViewModel: NetViewModel by viewModels()
|
val netViewModel: NetViewModel by viewModels()
|
||||||
val appViewModel: DbViewModel by viewModels()
|
val dbViewModel: DbViewModel by viewModels()
|
||||||
|
|
||||||
private var singlePermissionCallback: ((isGranted: Boolean) -> Unit)? = null
|
private var singlePermissionCallback: ((isGranted: Boolean) -> Unit)? = null
|
||||||
private var multiplePermissionsCallback: ((isGranted: Boolean) -> Unit)? = null
|
private var multiplePermissionsCallback: ((isGranted: Boolean) -> Unit)? = null
|
||||||
|
|||||||
@@ -20,29 +20,19 @@ import com.shuwei.dish.match.utils.CrashHandler
|
|||||||
import com.shuwei.dish.match.utils.WeightUtil
|
import com.shuwei.dish.match.utils.WeightUtil
|
||||||
import com.shuwei.dish.match.utils.Weigher2
|
import com.shuwei.dish.match.utils.Weigher2
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BaseApp is the main application class that extends Android's Application class.
|
|
||||||
* It handles initialization of core components, device role determination,
|
|
||||||
* and service management for the weighing system.
|
|
||||||
*/
|
|
||||||
class BaseApp : Application() {
|
class BaseApp : Application() {
|
||||||
|
|
||||||
// Lazy initialization of the database instance
|
|
||||||
val database by lazy { DatabaseProvider(this).instance }
|
val database by lazy { DatabaseProvider(this).instance }
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
// Set the application instance
|
|
||||||
instance = this
|
instance = this
|
||||||
// 读取本地保存的环境地址,覆盖默认值
|
// 读取本地保存的环境地址,覆盖默认值
|
||||||
val savedBaseUrl = SpTool.baseUrl
|
val savedBaseUrl = SpTool.baseUrl
|
||||||
if (savedBaseUrl.isNotEmpty()) {
|
if (savedBaseUrl.isNotEmpty()) {
|
||||||
GlobalData.appBaseUrl = savedBaseUrl
|
GlobalData.appBaseUrl = savedBaseUrl
|
||||||
}
|
}
|
||||||
// Initialize crash handler for error tracking
|
|
||||||
CrashHandler.init(this)
|
CrashHandler.init(this)
|
||||||
// Get and store the unique device ID
|
|
||||||
val deviceId = AppUtil.getUDID(this)
|
val deviceId = AppUtil.getUDID(this)
|
||||||
Log.d(TAG, "onCreate: deviceId=$deviceId")
|
Log.d(TAG, "onCreate: deviceId=$deviceId")
|
||||||
GlobalData.deviceId = deviceId
|
GlobalData.deviceId = deviceId
|
||||||
@@ -88,24 +78,21 @@ class BaseApp : Application() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = "BaseApp"
|
private val TAG = "BaseApp"
|
||||||
// const val canteenId = "1678234139391512577"
|
|
||||||
var canteenId = "0"
|
var canteenId = "0"
|
||||||
// var configUrl = ""
|
|
||||||
|
|
||||||
// var token: String? = null
|
|
||||||
// var deviceId: String? = null
|
|
||||||
var appVersion: String = "1"
|
var appVersion: String = "1"
|
||||||
@Volatile
|
@Volatile
|
||||||
private var sharedPref: SharedPreferences? = null
|
private var sharedPref: SharedPreferences? = null
|
||||||
|
|
||||||
public var instance: BaseApp? = null
|
lateinit var instance: BaseApp
|
||||||
fun getSharedPref(): SharedPreferences? {
|
|
||||||
if (sharedPref != null) {
|
/** 双重检查锁,保证多线程下只初始化一次 */
|
||||||
return sharedPref
|
fun getSharedPref(): SharedPreferences {
|
||||||
|
return sharedPref ?: synchronized(this) {
|
||||||
|
sharedPref ?: instance.getSharedPreferences(
|
||||||
|
instance.getString(R.string.sp_save_name),
|
||||||
|
Context.MODE_PRIVATE
|
||||||
|
).also { sharedPref = it }
|
||||||
}
|
}
|
||||||
val saveName = instance?.getString(R.string.sp_save_name)
|
|
||||||
sharedPref = instance?.getSharedPreferences(saveName, Context.MODE_PRIVATE)
|
|
||||||
return sharedPref
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ object GlobalData {
|
|||||||
* 当前设备角色,启动时从 SpTool 读取,默认为 SLAVE
|
* 当前设备角色,启动时从 SpTool 读取,默认为 SLAVE
|
||||||
*/
|
*/
|
||||||
var deviceRole: DeviceRole = DeviceRole.SLAVE
|
var deviceRole: DeviceRole = DeviceRole.SLAVE
|
||||||
var appId = "Hkz1rBk6PZXbS8KwKr67K2eZtsz8bRoMHLg64bUdgCZj"
|
|
||||||
var sdkKey = "AabXs3sHM8UhhE7oCGf4LVMLrdkGb1nJNksbjjTdVt7k"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ class NetViewModel(
|
|||||||
params: MutableMap<String, RequestBody>
|
params: MutableMap<String, RequestBody>
|
||||||
) {
|
) {
|
||||||
val fileParts = fileList.map { file ->
|
val fileParts = fileList.map { file ->
|
||||||
file.asRequestBody("image/jpeg".toMediaTypeOrNull())
|
file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
|
||||||
.let { MultipartBody.Part.createFormData("foodPics", file.name, it) }
|
.let { MultipartBody.Part.createFormData("foodPics", file.name, it) }
|
||||||
}
|
}
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.shuwei.dish.match.entity.FoodRecord
|
|||||||
import com.shuwei.dish.match.entity.GoodsItem
|
import com.shuwei.dish.match.entity.GoodsItem
|
||||||
import okhttp3.MultipartBody
|
import okhttp3.MultipartBody
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网络数据仓库,封装所有 ApiService 调用
|
* 网络数据仓库,封装所有 ApiService 调用
|
||||||
@@ -13,104 +12,42 @@ import java.io.File
|
|||||||
*/
|
*/
|
||||||
class RemoteRepository {
|
class RemoteRepository {
|
||||||
|
|
||||||
/**
|
/** 统一封装 API 调用:处理响应映射和异常转换,返回 UiState */
|
||||||
* 提交制作菜品
|
private suspend fun <T> safeApiCall(call: suspend () -> ApiResponse<T>): UiState<T?> {
|
||||||
* @param entity 菜品实体
|
|
||||||
* @return UiState 包装的结果,Success 表示提交成功,Error 携带错误信息
|
|
||||||
*/
|
|
||||||
suspend fun submitCookFood(entity: CookFoodDTO): UiState<Any?> {
|
|
||||||
return try {
|
return try {
|
||||||
val resp = apiService.submitCookFood(param = entity)
|
val resp = call()
|
||||||
if (resp.isSuccess()) UiState.Success(resp.data)
|
if (resp.isSuccess()) UiState.Success(resp.data)
|
||||||
else UiState.Error(resp.code, resp.msg ?: "")
|
else UiState.Error(resp.code, resp.msg ?: "")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
val ex = getApiException(e)
|
UiState.Error("-1", getApiException(e).errorMsg)
|
||||||
UiState.Error("-1", ex.errorMsg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** 提交制作菜品 */
|
||||||
* 查询菜品详情
|
suspend fun submitCookFood(entity: CookFoodDTO): UiState<Any?> =
|
||||||
* @param foodId 菜品 ID
|
safeApiCall { apiService.submitCookFood(param = entity) }
|
||||||
* @return UiState 包装的结果,Success 携带详情数据,Error 携带错误信息
|
|
||||||
*/
|
|
||||||
suspend fun getFoodDetail(foodId: String): UiState<CookFoodDTO?> {
|
|
||||||
return try {
|
|
||||||
val resp = apiService.getFoodDetail(foodId = foodId)
|
|
||||||
if (resp.isSuccess()) UiState.Success(resp.data)
|
|
||||||
else UiState.Error(resp.code, resp.msg ?: "")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
val ex = getApiException(e)
|
|
||||||
UiState.Error("-1", ex.errorMsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/** 查询菜品详情 */
|
||||||
* 搜索菜品列表
|
suspend fun getFoodDetail(foodId: String): UiState<CookFoodDTO?> =
|
||||||
* @param param 查询参数
|
safeApiCall { apiService.getFoodDetail(foodId = foodId) }
|
||||||
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
|
|
||||||
*/
|
|
||||||
suspend fun searchFoodList(param: MutableMap<String, Any>): UiState<MutableList<FoodRecord>?> {
|
|
||||||
return try {
|
|
||||||
val resp = apiService.searchFoodList(param = param)
|
|
||||||
if (resp.isSuccess()) UiState.Success(resp.data)
|
|
||||||
else UiState.Error(resp.code, resp.msg ?: "")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
val ex = getApiException(e)
|
|
||||||
UiState.Error("-1", ex.errorMsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/** 搜索菜品列表 */
|
||||||
* 查询采样数据列表
|
suspend fun searchFoodList(param: MutableMap<String, Any>): UiState<MutableList<FoodRecord>?> =
|
||||||
* @param param 查询参数
|
safeApiCall { apiService.searchFoodList(param = param) }
|
||||||
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
|
|
||||||
*/
|
|
||||||
suspend fun getSamplingList(param: MutableMap<String, Any>): UiState<MutableList<FoodRecord>?> {
|
|
||||||
return try {
|
|
||||||
val resp = apiService.getSamplingList(param = param)
|
|
||||||
if (resp.isSuccess()) UiState.Success(resp.data)
|
|
||||||
else UiState.Error(resp.code, resp.msg ?: "")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
val ex = getApiException(e)
|
|
||||||
UiState.Error("-1", ex.errorMsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/** 查询采样数据列表 */
|
||||||
* 查询物品信息列表(食材 goodsType=0,调料 goodsType=1 共用)
|
suspend fun getSamplingList(param: MutableMap<String, Any>): UiState<MutableList<FoodRecord>?> =
|
||||||
* @param param 查询参数
|
safeApiCall { apiService.getSamplingList(param = param) }
|
||||||
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
|
|
||||||
*/
|
|
||||||
suspend fun queryGoodsList(param: MutableMap<String, Any>): UiState<MutableList<GoodsItem>?> {
|
|
||||||
return try {
|
|
||||||
val resp = apiService.queryGoodsList(param = param)
|
|
||||||
if (resp.isSuccess()) UiState.Success(resp.data)
|
|
||||||
else UiState.Error(resp.code, resp.msg ?: "")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
val ex = getApiException(e)
|
|
||||||
UiState.Error("-1", ex.errorMsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/** 查询物品信息列表(食材 goodsType=0,调料 goodsType=1 共用) */
|
||||||
* 上次采集数据
|
suspend fun queryGoodsList(param: MutableMap<String, Any>): UiState<MutableList<GoodsItem>?> =
|
||||||
* @param params 参数
|
safeApiCall { apiService.queryGoodsList(param = param) }
|
||||||
* @param foodPics 图片
|
|
||||||
* @return UiState 包装的结果,Success 携带列表数据,Error 携带错误信息
|
/** 上传采集数据 */
|
||||||
*/
|
|
||||||
suspend fun uploadFoodVectorData(
|
suspend fun uploadFoodVectorData(
|
||||||
params: MutableMap<String, RequestBody>,
|
params: MutableMap<String, RequestBody>,
|
||||||
foodPics: List<MultipartBody.Part>
|
foodPics: List<MultipartBody.Part>
|
||||||
): UiState<List<String>?> {
|
): UiState<List<String>?> =
|
||||||
return try {
|
safeApiCall { apiService.uploadFoodVectorData(params = params, foodPics = foodPics) }
|
||||||
val resp = apiService.uploadFoodVectorData(params = params, foodPics = foodPics)
|
|
||||||
if (resp.isSuccess()) UiState.Success(resp.data)
|
|
||||||
else UiState.Error(resp.code, resp.msg ?: "")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
val ex = getApiException(e)
|
|
||||||
UiState.Error("-1", ex.errorMsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class CollectedFoodActivity : BaseActivity() {
|
|||||||
.setContent(content)
|
.setContent(content)
|
||||||
.setNegativeButton("取消")
|
.setNegativeButton("取消")
|
||||||
.setPositiveButton("确认") {
|
.setPositiveButton("确认") {
|
||||||
appViewModel.removeCollectedFood(
|
dbViewModel.removeCollectedFood(
|
||||||
foodName = foodName,
|
foodName = foodName,
|
||||||
nameFilter = binding.editSearch.text.toString()
|
nameFilter = binding.editSearch.text.toString()
|
||||||
)
|
)
|
||||||
@@ -95,7 +95,7 @@ class CollectedFoodActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = "已采集食材"
|
it.text = "已采集食材"
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.gone()
|
it.gone()
|
||||||
}, backAction = {
|
}, backAction = {
|
||||||
it.visible()
|
it.visible()
|
||||||
@@ -110,7 +110,7 @@ class CollectedFoodActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCollectedFoodList(name: String = "") {
|
private fun loadCollectedFoodList(name: String = "") {
|
||||||
appViewModel.loadCollectedFoodList(nameFilter = name)
|
dbViewModel.loadCollectedFoodList(nameFilter = name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,7 +120,7 @@ class CollectedFoodActivity : BaseActivity() {
|
|||||||
private fun initObserver() {
|
private fun initObserver() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
appViewModel.collectedFoodListState.collect { items ->
|
dbViewModel.collectedFoodListState.collect { items ->
|
||||||
foodList.clear()
|
foodList.clear()
|
||||||
foodList.addAll(items)
|
foodList.addAll(items)
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class CookingModeActivity : BaseActivity() {
|
|||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = "选择菜品"
|
it.text = "选择菜品"
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.visible()
|
it.visible()
|
||||||
it.setImageResource(R.drawable.ic_setting)
|
it.setImageResource(R.drawable.ic_setting)
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
@@ -63,7 +63,7 @@ class CookingModeActivity : BaseActivity() {
|
|||||||
|
|
||||||
|
|
||||||
fun getCookFoodList() {
|
fun getCookFoodList() {
|
||||||
appViewModel.getCookFoodList(cookMode = 0, dinnerType = dinnerType)
|
dbViewModel.getCookFoodList(cookMode = 0, dinnerType = dinnerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var configFinished = false
|
private var configFinished = false
|
||||||
@@ -73,7 +73,7 @@ class CookingModeActivity : BaseActivity() {
|
|||||||
// block()
|
// block()
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// appViewModel.loadSeasoning {
|
// dbViewModel.loadSeasoning {
|
||||||
// if (it.isEmpty()) {
|
// if (it.isEmpty()) {
|
||||||
// showDeviceConfigDialog()
|
// showDeviceConfigDialog()
|
||||||
// return@loadSeasoning
|
// return@loadSeasoning
|
||||||
@@ -96,7 +96,7 @@ class CookingModeActivity : BaseActivity() {
|
|||||||
/** 切换餐次时清空输入框,用此标志跳过 afterTextChanged 的查询触发 */
|
/** 切换餐次时清空输入框,用此标志跳过 afterTextChanged 的查询触发 */
|
||||||
private var isClearingByTabSwitch = false
|
private var isClearingByTabSwitch = false
|
||||||
|
|
||||||
fun addViewListener() {
|
private fun addViewListener() {
|
||||||
binding.dishRadioGroup.setOnCheckedChangeListener { _, checkedId ->
|
binding.dishRadioGroup.setOnCheckedChangeListener { _, checkedId ->
|
||||||
dinnerType = when (checkedId) {
|
dinnerType = when (checkedId) {
|
||||||
R.id.rbBreakfast -> "1"
|
R.id.rbBreakfast -> "1"
|
||||||
@@ -157,7 +157,7 @@ class CookingModeActivity : BaseActivity() {
|
|||||||
|
|
||||||
fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) {
|
fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
appViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId, dinnerType = dinnerType)
|
dbViewModel.deleteCookFoodAndGoods(cookMode = 0, foodId = foodId, dinnerType = dinnerType)
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
// it.visible()
|
// it.visible()
|
||||||
// }, titleAction = {
|
// }, titleAction = {
|
||||||
// it.text = "设备配置"
|
// it.text = "设备配置"
|
||||||
// }, rightIconActon = {
|
// }, rightIconAction = {
|
||||||
// it.gone()
|
// it.gone()
|
||||||
//// it.alpha = 0.0F
|
//// it.alpha = 0.0F
|
||||||
//// it.setImageResource(R.drawable.ic_setting)
|
//// it.setImageResource(R.drawable.ic_setting)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class FoodSearchActivity : BaseActivity() {
|
|||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = "菜品搜索"
|
it.text = "菜品搜索"
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.gone()
|
it.gone()
|
||||||
it.setImageResource(R.drawable.ic_setting)
|
it.setImageResource(R.drawable.ic_setting)
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
|
|||||||
@@ -66,18 +66,18 @@ class HomeActivity : BaseActivity() {
|
|||||||
// startActivity<SamplingListActivity>()
|
// startActivity<SamplingListActivity>()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// appViewModel.deleteSeasoningBySort(12)
|
// dbViewModel.deleteSeasoningBySort(12)
|
||||||
// appViewModel.deleteSeasoningBySort(11)
|
// dbViewModel.deleteSeasoningBySort(11)
|
||||||
// appViewModel.deleteSeasoningBySort(13)
|
// dbViewModel.deleteSeasoningBySort(13)
|
||||||
// appViewModel.deleteSeasoningBySort(14)
|
// dbViewModel.deleteSeasoningBySort(14)
|
||||||
// appViewModel.deleteCookFoodAndGoods(0,"") {}
|
// dbViewModel.deleteCookFoodAndGoods(0,"") {}
|
||||||
// appViewModel.getCookFoodGoodsList("") {goodsList->
|
// dbViewModel.getCookFoodGoodsList("") {goodsList->
|
||||||
// goodsList.forEach {
|
// goodsList.forEach {
|
||||||
// it.foodId = "1594990392084779010"
|
// it.foodId = "1594990392084779010"
|
||||||
// appViewModel.updateGoods(it)
|
// dbViewModel.updateGoods(it)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// appViewModel.clearAllSeasoning(){}
|
// dbViewModel.clearAllSeasoning(){}
|
||||||
|
|
||||||
|
|
||||||
// binding.btnDeviceConfig.setOnClickListener {
|
// binding.btnDeviceConfig.setOnClickListener {
|
||||||
@@ -141,14 +141,14 @@ class HomeActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun goSampling() {
|
private fun goSampling() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots = appViewModel.loadSeasoningSlot()
|
val slots = dbViewModel.loadSeasoningSlot()
|
||||||
if (slots.isEmpty()) {
|
if (slots.isEmpty()) {
|
||||||
// 无调料信息,打开采样历史列表页面,点击设置配置调料信息
|
// 无调料信息,打开采样历史列表页面,点击设置配置调料信息
|
||||||
startActivity<SamplingModeActivity>()
|
startActivity<SamplingModeActivity>()
|
||||||
finish()
|
finish()
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
val count = appViewModel.countCookFood(cookMode = 1)
|
val count = dbViewModel.countCookFood(cookMode = 1)
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// 有烹饪中数据,打开采样历史列表页面
|
// 有烹饪中数据,打开采样历史列表页面
|
||||||
startActivity<SamplingModeActivity>()
|
startActivity<SamplingModeActivity>()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import com.shuwei.dish.match.objbox.FoodModule
|
|||||||
import com.shuwei.dish.match.scale.ScaleServiceManager
|
import com.shuwei.dish.match.scale.ScaleServiceManager
|
||||||
import com.shuwei.dish.match.utils.AddressUtil
|
import com.shuwei.dish.match.utils.AddressUtil
|
||||||
import com.shuwei.dish.match.utils.AppUtil
|
import com.shuwei.dish.match.utils.AppUtil
|
||||||
import com.shuwei.dish.match.utils.NetworkUtils
|
import com.shuwei.dish.match.utils.NetworkUtil
|
||||||
import com.shuwei.dish.match.utils.SpTool
|
import com.shuwei.dish.match.utils.SpTool
|
||||||
import com.shuwei.dish.match.utils.ext.gone
|
import com.shuwei.dish.match.utils.ext.gone
|
||||||
import com.shuwei.dish.match.utils.ext.startActivity
|
import com.shuwei.dish.match.utils.ext.startActivity
|
||||||
@@ -54,7 +54,7 @@ class InitActivity : BaseActivity() {
|
|||||||
countdownHandler.postDelayed(this, 100)
|
countdownHandler.postDelayed(this, 100)
|
||||||
} else {
|
} else {
|
||||||
// 倒计时结束,最后检测一次网络
|
// 倒计时结束,最后检测一次网络
|
||||||
if (NetworkUtils.isNetworkConnected(this@InitActivity)) {
|
if (NetworkUtil.isNetworkConnected(this@InitActivity)) {
|
||||||
startNextPage()
|
startNextPage()
|
||||||
} else {
|
} else {
|
||||||
// 网络未连接,显示"连接网络"按钮
|
// 网络未连接,显示"连接网络"按钮
|
||||||
@@ -116,13 +116,13 @@ class InitActivity : BaseActivity() {
|
|||||||
|
|
||||||
private fun goSampling() {
|
private fun goSampling() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots = appViewModel.loadSeasoningSlot()
|
val slots = dbViewModel.loadSeasoningSlot()
|
||||||
if (slots.isEmpty()) {
|
if (slots.isEmpty()) {
|
||||||
// 无调料信息,打开采样历史列表页面,点击设置配置调料信息
|
// 无调料信息,打开采样历史列表页面,点击设置配置调料信息
|
||||||
startActivity<SamplingModeActivity>()
|
startActivity<SamplingModeActivity>()
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
val count = appViewModel.countCookFood(cookMode = 1)
|
val count = dbViewModel.countCookFood(cookMode = 1)
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// 有烹饪中数据,打开采样历史列表页面
|
// 有烹饪中数据,打开采样历史列表页面
|
||||||
startActivity<SamplingModeActivity>()
|
startActivity<SamplingModeActivity>()
|
||||||
@@ -169,7 +169,7 @@ class InitActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (NetworkUtils.isNetworkConnected(this)) {
|
if (NetworkUtil.isNetworkConnected(this)) {
|
||||||
// 有网络时隐藏网络检测区域,直接跳转
|
// 有网络时隐藏网络检测区域,直接跳转
|
||||||
binding.llNetwork.gone()
|
binding.llNetwork.gone()
|
||||||
startNextPage(withDelay = false)
|
startNextPage(withDelay = false)
|
||||||
@@ -213,7 +213,7 @@ class InitActivity : BaseActivity() {
|
|||||||
* 检测网络连接
|
* 检测网络连接
|
||||||
*/
|
*/
|
||||||
private fun checkNetworkConnection() {
|
private fun checkNetworkConnection() {
|
||||||
if (NetworkUtils.isNetworkConnected(this)) {
|
if (NetworkUtil.isNetworkConnected(this)) {
|
||||||
// 网络连接成功,停止倒计时并跳转到 HomeActivity
|
// 网络连接成功,停止倒计时并跳转到 HomeActivity
|
||||||
countdownHandler.removeCallbacks(countdownTask)
|
countdownHandler.removeCallbacks(countdownTask)
|
||||||
startNextPage()
|
startNextPage()
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class MasterScaleActivity : BaseActivity() {
|
|||||||
/** 从 Room 加载槽位配置到 slotNameMap,加载完成后启动数据观测 */
|
/** 从 Room 加载槽位配置到 slotNameMap,加载完成后启动数据观测 */
|
||||||
private fun loadSlotNames() {
|
private fun loadSlotNames() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots = appViewModel.loadSeasoningSlot()
|
val slots = dbViewModel.loadSeasoningSlot()
|
||||||
slots.forEach { slot ->
|
slots.forEach { slot ->
|
||||||
slotNameMap["${slot.deviceId}#${slot.address}"] = slot.goodsName
|
slotNameMap["${slot.deviceId}#${slot.address}"] = slot.goodsName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class PrepareFoodActivity : BaseActivity() {
|
|||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = titleText
|
it.text = titleText
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.gone()
|
it.gone()
|
||||||
}, backAction = {
|
}, backAction = {
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = "采样历史"
|
it.text = "采样历史"
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.visible()
|
it.visible()
|
||||||
it.setImageResource(R.drawable.ic_setting)
|
it.setImageResource(R.drawable.ic_setting)
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
@@ -70,7 +70,7 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
fun getCookFoodList() {
|
fun getCookFoodList() {
|
||||||
appViewModel.getCookFoodListWithCallback(cookMode = 1) { cookFoodEntities ->
|
dbViewModel.getCookFoodListWithCallback(cookMode = 1) { cookFoodEntities ->
|
||||||
// 回调期间用户可能已切换 Tab,需再次校验
|
// 回调期间用户可能已切换 Tab,需再次校验
|
||||||
if (binding.rbSamplingCooking.isChecked.not()) return@getCookFoodListWithCallback
|
if (binding.rbSamplingCooking.isChecked.not()) return@getCookFoodListWithCallback
|
||||||
delayDismissLoading()
|
delayDismissLoading()
|
||||||
@@ -103,7 +103,7 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
|
|
||||||
fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) {
|
fun deleteCookFoodAndGoods(foodId: String, dinnerType: String, action: () -> Unit) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
appViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId, dinnerType = dinnerType)
|
dbViewModel.deleteCookFoodAndGoods(cookMode = 1, foodId = foodId, dinnerType = dinnerType)
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -399,7 +399,7 @@ class SamplingModeActivity : BaseActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots = appViewModel.loadSeasoningSlot()
|
val slots = dbViewModel.loadSeasoningSlot()
|
||||||
if (slots.isEmpty()) {
|
if (slots.isEmpty()) {
|
||||||
showDeviceConfigDialog()
|
showDeviceConfigDialog()
|
||||||
return@launch
|
return@launch
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class SettingActivity : BaseActivity() {
|
|||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = "设备设置"
|
it.text = "设备设置"
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.visible()
|
it.visible()
|
||||||
it.clickWithDebounce {
|
it.clickWithDebounce {
|
||||||
binding.llDbInspect.visible()
|
binding.llDbInspect.visible()
|
||||||
@@ -107,7 +107,7 @@ class SettingActivity : BaseActivity() {
|
|||||||
.setContent("将物理删除全部 4 张表数据(菜品、食材、调料、槽位),此操作不可恢复,同时重置菜品模式和食堂id,确认继续?")
|
.setContent("将物理删除全部 4 张表数据(菜品、食材、调料、槽位),此操作不可恢复,同时重置菜品模式和食堂id,确认继续?")
|
||||||
.setNegativeButton("取消")
|
.setNegativeButton("取消")
|
||||||
.setPositiveButton("确认") {
|
.setPositiveButton("确认") {
|
||||||
appViewModel.clearAllData {
|
dbViewModel.clearAllData {
|
||||||
SpTool.cookMode = -1
|
SpTool.cookMode = -1
|
||||||
SpTool.canteenId = "0"
|
SpTool.canteenId = "0"
|
||||||
// 通知所有已连接子设备同步清除数据
|
// 通知所有已连接子设备同步清除数据
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class SingleFragmentActivity : BaseActivity() {
|
|||||||
setTitleBar(
|
setTitleBar(
|
||||||
titleBarAction = { it.visible() },
|
titleBarAction = { it.visible() },
|
||||||
titleAction = { it.text = getTitleForPage(pageType) },
|
titleAction = { it.text = getTitleForPage(pageType) },
|
||||||
rightIconActon = { it.gone() }
|
rightIconAction = { it.gone() }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 首次创建时加载 Fragment,避免屏幕旋转重复添加
|
// 首次创建时加载 Fragment,避免屏幕旋转重复添加
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ class SlaveActivity : BaseActivity() {
|
|||||||
*/
|
*/
|
||||||
private fun loadSlotsFromDb() {
|
private fun loadSlotsFromDb() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots = appViewModel.getSeasoningSlotsByDeviceId(GlobalData.deviceId)
|
val slots = dbViewModel.getSeasoningSlotsByDeviceId(GlobalData.deviceId)
|
||||||
applySlots(slots)
|
applySlots(slots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,8 +179,8 @@ class SlaveActivity : BaseActivity() {
|
|||||||
?: return@onSeasoningConfig
|
?: return@onSeasoningConfig
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
// 全量替换:先删除本机所有旧槽位,再写入最新配置
|
// 全量替换:先删除本机所有旧槽位,再写入最新配置
|
||||||
appViewModel.deleteAllSlotsByDeviceId(GlobalData.deviceId)
|
dbViewModel.deleteAllSlotsByDeviceId(GlobalData.deviceId)
|
||||||
appViewModel.upsertAllSeasoningSlots(mySlots)
|
dbViewModel.upsertAllSeasoningSlots(mySlots)
|
||||||
applySlots(mySlots)
|
applySlots(mySlots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ class SlaveActivity : BaseActivity() {
|
|||||||
private fun listenClearData() {
|
private fun listenClearData() {
|
||||||
ScaleServiceManager.onClearData = {
|
ScaleServiceManager.onClearData = {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
appViewModel.clearAllData {
|
dbViewModel.clearAllData {
|
||||||
SpTool.cookMode = -1
|
SpTool.cookMode = -1
|
||||||
SpTool.canteenId = "0"
|
SpTool.canteenId = "0"
|
||||||
runOnUiThread { applySlots(emptyList()) }
|
runOnUiThread { applySlots(emptyList()) }
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
it.visible()
|
it.visible()
|
||||||
}, titleAction = {
|
}, titleAction = {
|
||||||
it.text = food?.foodName
|
it.text = food?.foodName
|
||||||
}, rightIconActon = {
|
}, rightIconAction = {
|
||||||
it.gone()
|
it.gone()
|
||||||
}, backAction = {
|
}, backAction = {
|
||||||
it.setOnClickListener {
|
it.setOnClickListener {
|
||||||
@@ -179,7 +179,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
*/
|
*/
|
||||||
private fun loadSlotsThenObserveScales() {
|
private fun loadSlotsThenObserveScales() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots = appViewModel.loadSeasoningSlot()
|
val slots = dbViewModel.loadSeasoningSlot()
|
||||||
slots.forEach { slot ->
|
slots.forEach { slot ->
|
||||||
slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName
|
slotMap["${slot.deviceId}#${slot.address}"] = slot.goodsId to slot.goodsName
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
val foodId = food?.foodId ?: return@launch
|
val foodId = food?.foodId ?: return@launch
|
||||||
val cookMode = food?.cookMode ?: return@launch
|
val cookMode = food?.cookMode ?: return@launch
|
||||||
val list =
|
val list =
|
||||||
appViewModel.getCookFoodGoodsList(foodId, cookMode, food?.dinnerType ?: "0")
|
dbViewModel.getCookFoodGoodsList(foodId, cookMode, food?.dinnerType ?: "0")
|
||||||
goodsList = list
|
goodsList = list
|
||||||
prefillSeasoningFromGoodsList(list)
|
prefillSeasoningFromGoodsList(list)
|
||||||
} else {
|
} else {
|
||||||
@@ -387,7 +387,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
seasoningAdapter.items
|
seasoningAdapter.items
|
||||||
.filter { it.useWeight > 0.0 }
|
.filter { it.useWeight > 0.0 }
|
||||||
.forEach { goodsList?.add(buildSeasoningEntity(it)) }
|
.forEach { goodsList?.add(buildSeasoningEntity(it)) }
|
||||||
appViewModel.saveCookFoodAndGoods(
|
dbViewModel.saveCookFoodAndGoods(
|
||||||
cookMode = food!!.cookMode,
|
cookMode = food!!.cookMode,
|
||||||
entity = cookFoodEntity,
|
entity = cookFoodEntity,
|
||||||
list = goodsList
|
list = goodsList
|
||||||
@@ -440,7 +440,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
* 从本地 dm_seasoning 表补充完整字段(popularName、zjmCode、materId、goodsCode 等)
|
* 从本地 dm_seasoning 表补充完整字段(popularName、zjmCode、materId、goodsCode 等)
|
||||||
*/
|
*/
|
||||||
private suspend fun buildSeasoningEntity(item: SeasoningWeightAdapter.Item): CookFoodGoodsEntity {
|
private suspend fun buildSeasoningEntity(item: SeasoningWeightAdapter.Item): CookFoodGoodsEntity {
|
||||||
val seasoning = appViewModel.getSeasoningByGoodsId(item.goodsId)
|
val seasoning = dbViewModel.getSeasoningByGoodsId(item.goodsId)
|
||||||
return CookFoodGoodsEntity().also { entity ->
|
return CookFoodGoodsEntity().also { entity ->
|
||||||
entity.foodId = cookFoodEntity.foodId
|
entity.foodId = cookFoodEntity.foodId
|
||||||
entity.goodsId = item.goodsId
|
entity.goodsId = item.goodsId
|
||||||
@@ -465,7 +465,7 @@ class SubmitFoodActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
// 用 viewModelScope 执行删除,不受当前 Activity 生命周期影响
|
// 用 viewModelScope 执行删除,不受当前 Activity 生命周期影响
|
||||||
// singleTask 跳转会销毁本 Activity 并取消 lifecycleScope,导致删除被中断
|
// singleTask 跳转会销毁本 Activity 并取消 lifecycleScope,导致删除被中断
|
||||||
appViewModel.markSubmittedAndDeleteAsync(
|
dbViewModel.markSubmittedAndDeleteAsync(
|
||||||
cookMode = food!!.cookMode,
|
cookMode = food!!.cookMode,
|
||||||
foodId = food!!.foodId!!,
|
foodId = food!!.foodId!!,
|
||||||
dinnerType = food!!.dinnerType
|
dinnerType = food!!.dinnerType
|
||||||
|
|||||||
@@ -87,12 +87,12 @@ class DbInspectFragment : BaseFragment<FragmentDbInspectBinding>() {
|
|||||||
|
|
||||||
// 加载更多按钮
|
// 加载更多按钮
|
||||||
binding.tvLoadMore.setOnClickListener {
|
binding.tvLoadMore.setOnClickListener {
|
||||||
currentActivity.appViewModel.loadMoreDbInspect(currentTableIndex, showDel)
|
currentActivity.dbViewModel.loadMoreDbInspect(currentTableIndex, showDel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 订阅 UI 状态
|
// 订阅 UI 状态
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
currentActivity.appViewModel.dbInspectState.collect { state ->
|
currentActivity.dbViewModel.dbInspectState.collect { state ->
|
||||||
renderState(state)
|
renderState(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ class DbInspectFragment : BaseFragment<FragmentDbInspectBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadFirstPage() {
|
private fun loadFirstPage() {
|
||||||
currentActivity.appViewModel.loadDbInspect(currentTableIndex, showDel)
|
currentActivity.dbViewModel.loadDbInspect(currentTableIndex, showDel)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: DbViewModel.DbInspectUiState) {
|
private fun renderState(state: DbViewModel.DbInspectUiState) {
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ class FoodListFragment : BaseFragment<FragmentFoodListBinding>() {
|
|||||||
)
|
)
|
||||||
foodName?.let { param["foodName"] = it }
|
foodName?.let { param["foodName"] = it }
|
||||||
if (pageNo == 1) {
|
if (pageNo == 1) {
|
||||||
pendingLocalList = activity.appViewModel.getCookFoodListDirect(
|
pendingLocalList = activity.dbViewModel.getCookFoodListDirect(
|
||||||
cookMode = 0,
|
cookMode = 0,
|
||||||
dinnerType = dinnerType
|
dinnerType = dinnerType
|
||||||
)
|
)
|
||||||
@@ -285,45 +285,69 @@ class FoodListFragment : BaseFragment<FragmentFoodListBinding>() {
|
|||||||
if (pageNo == 1) list.clear()
|
if (pageNo == 1) list.clear()
|
||||||
|
|
||||||
val mergedList = records?.toMutableList() ?: mutableListOf()
|
val mergedList = records?.toMutableList() ?: mutableListOf()
|
||||||
|
mergeCookingItems(mergedList, effectiveLocalList)
|
||||||
if (!effectiveLocalList.isNullOrEmpty()) {
|
deduplicateForPaging(mergedList, localList)
|
||||||
val cookingItems = mutableListOf<FoodRecord>()
|
renderList(mergedList, records)
|
||||||
effectiveLocalList.forEachIndexed { index, entity ->
|
|
||||||
val food = mergedList.firstOrNull { it.foodId == entity.foodId }
|
|
||||||
if (food != null) {
|
|
||||||
mergedList.remove(food)
|
|
||||||
food.isCooking = true
|
|
||||||
food.sort = index
|
|
||||||
food.dinnerType = entity.dinnerType ?: "0"
|
|
||||||
cookingItems.add(food)
|
|
||||||
} else {
|
|
||||||
cookingItems.add(
|
|
||||||
FoodRecord(
|
|
||||||
foodId = entity.foodId,
|
|
||||||
foodName = entity.foodName,
|
|
||||||
sort = index,
|
|
||||||
dinnerType = entity.dinnerType ?: "0",
|
|
||||||
isCooking = true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mergedList.addAll(0, cookingItems)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pageNo >= 2 && !localList.isNullOrEmpty()) {
|
|
||||||
val localIds = localList.map { it.foodId }.toHashSet()
|
|
||||||
mergedList.removeAll { it.foodId in localIds }
|
|
||||||
}
|
|
||||||
|
|
||||||
list.addAll(mergedList)
|
|
||||||
dishAdapter.notifyDataSetChanged()
|
|
||||||
val isLoadMoreEnable = (records?.size ?: 0) >= pageSize
|
|
||||||
binding.refreshLayout.setEnableRefresh(true)
|
|
||||||
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
|
|
||||||
if (isLoadMoreEnable) pageNo++
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将本地烹饪中条目置顶合并到网络列表:
|
||||||
|
* 网络列表中已有的条目标记 isCooking 并移至顶部,没有的则新建占位条目
|
||||||
|
*/
|
||||||
|
private fun mergeCookingItems(
|
||||||
|
mergedList: MutableList<FoodRecord>,
|
||||||
|
cookingEntities: List<CookFoodEntity>?
|
||||||
|
) {
|
||||||
|
if (cookingEntities.isNullOrEmpty()) return
|
||||||
|
val cookingItems = mutableListOf<FoodRecord>()
|
||||||
|
cookingEntities.forEachIndexed { index, entity ->
|
||||||
|
val existing = mergedList.firstOrNull { it.foodId == entity.foodId }
|
||||||
|
if (existing != null) {
|
||||||
|
mergedList.remove(existing)
|
||||||
|
existing.isCooking = true
|
||||||
|
existing.sort = index
|
||||||
|
existing.dinnerType = entity.dinnerType ?: "0"
|
||||||
|
cookingItems.add(existing)
|
||||||
|
} else {
|
||||||
|
cookingItems.add(
|
||||||
|
FoodRecord(
|
||||||
|
foodId = entity.foodId,
|
||||||
|
foodName = entity.foodName,
|
||||||
|
sort = index,
|
||||||
|
dinnerType = entity.dinnerType ?: "0",
|
||||||
|
isCooking = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mergedList.addAll(0, cookingItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 翻页时从网络结果中剔除第一页已加载的本地烹饪中条目,避免重复出现
|
||||||
|
*/
|
||||||
|
private fun deduplicateForPaging(
|
||||||
|
mergedList: MutableList<FoodRecord>,
|
||||||
|
localList: List<CookFoodEntity>?
|
||||||
|
) {
|
||||||
|
if (pageNo < 2 || localList.isNullOrEmpty()) return
|
||||||
|
val localIds = localList.map { it.foodId }.toHashSet()
|
||||||
|
mergedList.removeAll { it.foodId in localIds }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将合并结果追加到列表并刷新 UI,按网络返回条数决定是否开启加载更多
|
||||||
|
*/
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun renderList(mergedList: List<FoodRecord>, records: List<FoodRecord>?) {
|
||||||
|
list.addAll(mergedList)
|
||||||
|
dishAdapter.notifyDataSetChanged()
|
||||||
|
val isLoadMoreEnable = (records?.size ?: 0) >= pageSize
|
||||||
|
binding.refreshLayout.setEnableRefresh(true)
|
||||||
|
binding.refreshLayout.setEnableLoadMore(isLoadMoreEnable)
|
||||||
|
if (isLoadMoreEnable) pageNo++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
) = FragmentSeasoningConfigBinding.inflate(inflater, container, false)
|
) = FragmentSeasoningConfigBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
private lateinit var currentActivity: SingleFragmentActivity
|
private lateinit var currentActivity: SingleFragmentActivity
|
||||||
// private lateinit var appViewModel: DbViewModel
|
// private lateinit var dbViewModel: DbViewModel
|
||||||
|
|
||||||
private val adapter22 by lazy { buildAdapter22() }
|
private val adapter22 by lazy { buildAdapter22() }
|
||||||
private val adapter18 by lazy {
|
private val adapter18 by lazy {
|
||||||
@@ -186,7 +186,7 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
onUpdateName(name)
|
onUpdateName(name)
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
// 保存槽位配置
|
// 保存槽位配置
|
||||||
currentActivity.appViewModel.upsertSeasoningSlot(
|
currentActivity.dbViewModel.upsertSeasoningSlot(
|
||||||
SeasoningSlotEntity(
|
SeasoningSlotEntity(
|
||||||
deviceId = deviceId,
|
deviceId = deviceId,
|
||||||
address = address,
|
address = address,
|
||||||
@@ -195,7 +195,7 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
// 按 goodsId 去重保存完整调料信息到 dm_seasoning
|
// 按 goodsId 去重保存完整调料信息到 dm_seasoning
|
||||||
currentActivity.appViewModel.upsertSeasoningByGoodsId(item.toSeasoningEntity())
|
currentActivity.dbViewModel.upsertSeasoningByGoodsId(item.toSeasoningEntity())
|
||||||
broadcastAllSlots()
|
broadcastAllSlots()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,7 +205,7 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
/** 将单个槽位写入 Room,再广播全量配置给子设备 */
|
/** 将单个槽位写入 Room,再广播全量配置给子设备 */
|
||||||
private fun saveSlotAndBroadcast(slot: SeasoningSlotEntity) {
|
private fun saveSlotAndBroadcast(slot: SeasoningSlotEntity) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
currentActivity.appViewModel.upsertSeasoningSlot(slot)
|
currentActivity.dbViewModel.upsertSeasoningSlot(slot)
|
||||||
broadcastAllSlots()
|
broadcastAllSlots()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,14 +233,14 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
/** 从 Room 删除指定槽位,再广播全量配置给子设备 */
|
/** 从 Room 删除指定槽位,再广播全量配置给子设备 */
|
||||||
private fun deleteSlotAndBroadcast(deviceId: String, address: Int) {
|
private fun deleteSlotAndBroadcast(deviceId: String, address: Int) {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
currentActivity.appViewModel.deleteSeasoningSlot(deviceId, address)
|
currentActivity.dbViewModel.deleteSeasoningSlot(deviceId, address)
|
||||||
broadcastAllSlots()
|
broadcastAllSlots()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 读取全量槽位配置并通过 wsClient 推送给所有已连接子设备 */
|
/** 读取全量槽位配置并通过 wsClient 推送给所有已连接子设备 */
|
||||||
private suspend fun broadcastAllSlots() {
|
private suspend fun broadcastAllSlots() {
|
||||||
val allSlots = currentActivity.appViewModel.loadSeasoningSlot().map {
|
val allSlots = currentActivity.dbViewModel.loadSeasoningSlot().map {
|
||||||
SlotConfig(it.deviceId, it.address, it.goodsId, it.goodsName)
|
SlotConfig(it.deviceId, it.address, it.goodsId, it.goodsName)
|
||||||
}
|
}
|
||||||
ScaleServiceManager.sendSeasoningConfig(allSlots)
|
ScaleServiceManager.sendSeasoningConfig(allSlots)
|
||||||
@@ -249,7 +249,7 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
// /** 初始化 ViewModel */
|
// /** 初始化 ViewModel */
|
||||||
// private fun initViewModel() {
|
// private fun initViewModel() {
|
||||||
// val factory = AppFactory(DbRepository(BaseApp.instance!!.database.appDao()))
|
// val factory = AppFactory(DbRepository(BaseApp.instance!!.database.appDao()))
|
||||||
// appViewModel = ViewModelProvider(this, factory)[DbViewModel::class.java]
|
// dbViewModel = ViewModelProvider(this, factory)[DbViewModel::class.java]
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
@@ -292,9 +292,9 @@ class SeasoningConfigFragment : BaseFragment<FragmentSeasoningConfigBinding>() {
|
|||||||
adapter22.update(emptyList())
|
adapter22.update(emptyList())
|
||||||
adapter18.update(emptyList())
|
adapter18.update(emptyList())
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val slots22 = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_22)
|
val slots22 = currentActivity.dbViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_22)
|
||||||
val slots18 = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_18)
|
val slots18 = currentActivity.dbViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_18)
|
||||||
val slotsOil = currentActivity.appViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_1)
|
val slotsOil = currentActivity.dbViewModel.getSeasoningSlotsByDeviceId(ScaleDeviceConfig.DEVICE_ID_1)
|
||||||
slots22.forEach { slot ->
|
slots22.forEach { slot ->
|
||||||
val pos = ScaleDeviceConfig.SCALE_ORDER_22.indexOf(slot.address)
|
val pos = ScaleDeviceConfig.SCALE_ORDER_22.indexOf(slot.address)
|
||||||
if (pos >= 0) adapter22.updateItemName(pos, slot.goodsName)
|
if (pos >= 0) adapter22.updateItemName(pos, slot.goodsName)
|
||||||
|
|||||||
@@ -3,15 +3,28 @@ package com.shuwei.dish.match.utils
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.LinkProperties
|
import android.net.LinkProperties
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import java.net.Inet4Address
|
import java.net.Inet4Address
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网络工具类
|
* 网络工具类,提供网络状态检测和本机 IP 获取功能
|
||||||
*/
|
*/
|
||||||
object NetworkUtil {
|
object NetworkUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测设备是否连接到网络
|
||||||
|
* @param context 应用上下文
|
||||||
|
* @return true 表示已连接网络,false 表示未连接
|
||||||
|
*/
|
||||||
|
fun isNetworkConnected(context: Context): Boolean {
|
||||||
|
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
|
val network = cm.activeNetwork ?: return false
|
||||||
|
val capabilities = cm.getNetworkCapabilities(network) ?: return false
|
||||||
|
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取本机局域网 IPv4 地址
|
* 获取本机局域网 IPv4 地址
|
||||||
* - Android 12+(API 31+):使用 ConnectivityManager + LinkProperties,避免废弃 API
|
* - Android 12+(API 31+):使用 ConnectivityManager + LinkProperties,避免废弃 API
|
||||||
@@ -60,3 +73,4 @@ object NetworkUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.shuwei.dish.match.utils
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.net.NetworkCapabilities
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 网络连接检测工具类
|
|
||||||
* 提供检测设备网络连接状态的功能
|
|
||||||
*/
|
|
||||||
object NetworkUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测设备是否连接到网络
|
|
||||||
* @param context 应用上下文
|
|
||||||
* @return true 表示已连接网络,false 表示未连接
|
|
||||||
*/
|
|
||||||
fun isNetworkConnected(context: Context): Boolean {
|
|
||||||
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
||||||
val network = connectivityManager.activeNetwork ?: return false
|
|
||||||
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
|
|
||||||
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user