From ab0d9b35f59d7b9cc4132b386d36d9d268664768 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Fri, 3 Apr 2026 18:04:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(data):=20=E6=9B=B4=E6=96=B0=E9=A3=9F?= =?UTF-8?q?=E7=89=A9=E8=90=A5=E5=85=BB=E6=95=B0=E6=8D=AE=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E5=90=91=E9=87=8F=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在DataBean中将肉蛋相关字段重命名为肉蛋豆,并添加总重量字段 - 新增FoodVectorTool工具类用于处理食物向量数据的分页获取和存储 - 重构InitActivity中的食物向量数据获取逻辑,使用新的工具类替代原有实现 - 在MainActivity中集成食物向量数据同步功能,在清除本地数据后重新获取 - 更新MainScreenPresentation中营养信息显示逻辑,适配新的数据模型结构 - 修改ApiClient中的日志标记逻辑,为不同接口添加特定的标签 - 调整食物订单列表的数据更新方式,优化适配器通知策略 --- .../sw/dualscreen/activity/InitActivity.kt | 80 +++++++++---------- .../sw/dualscreen/activity/MainActivity.kt | 16 ++++ .../sw/dualscreen/model/response/DataBean.kt | 14 ++-- .../com/sw/dualscreen/network/ApiClient.kt | 4 +- .../presentation/MainScreenPresentation.kt | 36 ++++----- .../com/sw/dualscreen/utils/FoodVectorTool.kt | 69 ++++++++++++++++ 6 files changed, 152 insertions(+), 67 deletions(-) create mode 100644 app/src/main/java/com/sw/dualscreen/utils/FoodVectorTool.kt diff --git a/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt index b5bc433..8932efe 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/InitActivity.kt @@ -17,6 +17,7 @@ import com.sw.dualscreen.model.response.FoodVector import com.sw.dualscreen.objbox.Food import com.sw.dualscreen.objbox.FoodModule import com.sw.dualscreen.objbox.ObjectBox +import com.sw.dualscreen.utils.FoodVectorTool import com.sw.dualscreen.utils.L import com.sw.dualscreen.utils.NetworkUtils import com.sw.dualscreen.viewmodel.BaseViewModel @@ -26,7 +27,7 @@ import kotlinx.coroutines.launch class InitActivity : BaseActivity() { companion object { - private const val PAGE_SIZE = 100 + const val PAGE_SIZE = 100 } private val userViewModel by viewModels() @@ -41,52 +42,47 @@ class InitActivity : BaseActivity() { } private fun getCollectedFoodVector(block: () -> Unit) { - userViewModel.getCollectedFoodVector( - param = mutableMapOf( - "pageNum" to "$pageNum", - "pageSize" to "$PAGE_SIZE", - "version" to GlobalData.foodModelVersion - ) - ) { items -> - if (items == null) { +// userViewModel.getCollectedFoodVector( +// param = mutableMapOf( +// "pageNum" to "$pageNum", +// "pageSize" to "$PAGE_SIZE", +// "version" to GlobalData.foodModelVersion +// ) +// ) { items -> +// if (items == null) { +// getVectorErrorDialog() +// return@getCollectedFoodVector +// } +// val list = items +// if (pageNum == 1 && list.isEmpty()) { +// block() +// return@getCollectedFoodVector +// } +// if (list.size >= PAGE_SIZE) { +// saveFoodVector(list) +// pageNum++ +// getCollectedFoodVector(block) +// return@getCollectedFoodVector +// } +// if (list.isNotEmpty()) { +// saveFoodVector(list) +// block() +// } +// } + + FoodVectorTool.getFoodVector( + userViewModel, + onPageFinish = { list -> + list?.let { FoodVectorTool.saveFoodVector(lifecycleScope,list) } + }, successBlock = { + block() + }, failureBlock = { getVectorErrorDialog() - return@getCollectedFoodVector } - val list = items - if (pageNum == 1 && list.isEmpty()) { - block() - return@getCollectedFoodVector - } - if (list.size >= PAGE_SIZE) { - saveFoodVector(list) - pageNum++ - getCollectedFoodVector(block) - return@getCollectedFoodVector - } - if (list.isNotEmpty()) { - saveFoodVector(list) - block() - } - } + ) } // private val box by lazy { ObjectBox.boxStore.boxFor(Food::class) } - private fun saveFoodVector(list: List) { - lifecycleScope.launch { - val vectorList = list.map { vt -> - val foodVector = vt.foodVector?.removeSurrounding("[", "]")?.split(",") - ?.map { it.toFloatOrNull() ?: 0.0f }?.toFloatArray() - Food( - collectId = vt.id, - foodId = vt.foodId, - foodName = vt.foodName, - version = vt.version, - foodVector = foodVector - ) - } - ObjectBox.putAll(vectorList) - } - } override fun initialize() { super.initialize() diff --git a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt index b1959fb..f2ee06d 100644 --- a/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt +++ b/app/src/main/java/com/sw/dualscreen/activity/MainActivity.kt @@ -55,6 +55,7 @@ import com.sw.dualscreen.socket.TcpClient import com.sw.dualscreen.utils.ActivityManager import com.sw.dualscreen.utils.BitmapSaver import com.sw.dualscreen.utils.Debouncer +import com.sw.dualscreen.utils.FoodVectorTool import com.sw.dualscreen.utils.GsonUtils import com.sw.dualscreen.utils.ImageUtil import com.sw.dualscreen.utils.IntervalExecutor @@ -215,6 +216,21 @@ class MainActivity : BaseActivity() { withContext(Dispatchers.IO) { FaceServer.getInstance().clearAllFaces() } + withContext(Dispatchers.IO) { + ObjectBox.removeAll() + } + FoodVectorTool.getFoodVector( + userViewModel = viewModel, + onPageFinish = { list -> + list?.let { FoodVectorTool.saveFoodVector(lifecycleScope,list) } + }, + successBlock = { + viewModel.getUserFaceCache(pageNo = 1) + }, failureBlock = { + hideWaitingDialog() // 显示提示信息 + ToastUtils.showToast(it) + } + ) } viewModel.getUserFaceCache(pageNo = 1, onSuccess = { recognizeViewModel.refreshFaceList() diff --git a/app/src/main/java/com/sw/dualscreen/model/response/DataBean.kt b/app/src/main/java/com/sw/dualscreen/model/response/DataBean.kt index 3effcbb..c583582 100644 --- a/app/src/main/java/com/sw/dualscreen/model/response/DataBean.kt +++ b/app/src/main/java/com/sw/dualscreen/model/response/DataBean.kt @@ -100,12 +100,14 @@ data class UserNutrition( val fruitsVegetablesNearExcess: String? = null, //果蔬超量 val fruitsVegetablesExcess: String? = null, - //肉蛋推荐值 - val meatEggsRecommend: String? = null, - //肉蛋即将超量 - val meatEggsNearExcess: String? = null, - //肉蛋超量 - val meatEggsExcess: String? = null, + //肉蛋豆推荐值 + val meatEggsBeansRecommend: String? = null, + //肉蛋豆即将超量 + val meatEggsBeansNearExcess: String? = null, + //肉蛋豆超量 + val meatEggsBeansExcess: String? = null, + //总重量 + val eatWeightSum:Double? = null, ) //{"code":"00000","data":"{\"orderType\":0,\"orderPayFrom\":2,\"payType\":\"1\",\"paySuc\":0,\"totalFee\":0.01,\"orderCode\":\"1998193614899372032\",\"message\":\"支付成功\",\"payCode\":\"1998193614899372032508227\"}","msg":"成功","total":0} diff --git a/app/src/main/java/com/sw/dualscreen/network/ApiClient.kt b/app/src/main/java/com/sw/dualscreen/network/ApiClient.kt index 415557a..cd2e260 100644 --- a/app/src/main/java/com/sw/dualscreen/network/ApiClient.kt +++ b/app/src/main/java/com/sw/dualscreen/network/ApiClient.kt @@ -24,7 +24,9 @@ object ApiClient { .addNetworkInterceptor(Interceptor {chain -> val request = chain.request() val url = request.url.toString() - val tag = if (url.contains("terminal/neglect/common/app/faceFeature/increment/list")) "faceIncrement" else "ApiClient" + val tag = if (url.contains("terminal/neglect/common/app/faceFeature/increment/list")) "faceIncrement" + else if (url.contains("terminal/neglect/pay/app/turnOrderInfo")) "turnOrderInfo" + else "ApiClient" val loggingInterceptor = HttpLoggingInterceptor(logger = { Timber.tag(tag).d("okhttp logger ==>${it}") }).apply { diff --git a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt index 5c87227..12b4a5c 100644 --- a/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt +++ b/app/src/main/java/com/sw/dualscreen/presentation/MainScreenPresentation.kt @@ -485,9 +485,7 @@ class MainScreenPresentation( binding.nutritionInclude.tvUserName.text = userNutrition?.name.maskName() val recommendCalorie = (userNutrition?.recommendCalorie ?: 0.0).roundedDecimalPlace(1) -// binding.detailInclude.tvTotalWeight.text = "总重量:${userNutrition?.}克" - binding.nutritionInclude.tvRecommendHeat.text = - "推荐热量:${recommendCalorie.roundedDecimalPlace(1)}kcal" + binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${recommendCalorie.roundedDecimalPlace(1)}kcal" // binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${recommendCalorie.removeTrailingZeros()}kcal" //updateWeight(lastWeight / 1000) // ------------------------------------------------- @@ -715,8 +713,8 @@ class MainScreenPresentation( val last = foodOrderList.last() if (last.isLocalData) { foodOrderList.remove(last) - foodOrderAdapter.submitList(foodOrderList) - //foodOrderAdapter.notifyDataSetChanged() +// foodOrderAdapter.submitList(foodOrderList) + foodOrderAdapter.notifyDataSetChanged() } } return @@ -730,8 +728,8 @@ class MainScreenPresentation( last.eatNum = eatNum last.num = weight last.price = price - foodOrderAdapter.submitList(foodOrderList) - //foodOrderAdapter.notifyItemChanged(foodOrderList.lastIndex) +// foodOrderAdapter.submitList(foodOrderList) + foodOrderAdapter.notifyItemChanged(foodOrderList.lastIndex) return } } @@ -750,7 +748,8 @@ class MainScreenPresentation( isLocalData = true ) ) - foodOrderAdapter.submitList(foodOrderList) +// foodOrderAdapter.submitList(foodOrderList) + foodOrderAdapter.notifyDataSetChanged() Log.d( TAG, "addFoodToOrder: size=${foodOrderList.size},新增数据:${foodOrderList.last()}" @@ -803,8 +802,10 @@ class MainScreenPresentation( val fruitsVegetables = energy.fruitsVegetables val meatEggs = energy.meatEggs - binding.detailInclude.tvTotalCalorie.text = - "总热量:${totalKcal.roundedDecimalPlace(1)}千卡" + binding.detailInclude.tvTotalCalorie.text = "总热量:${totalKcal.roundedDecimalPlace(1)}千卡" + + val totalWeight = (userNutrition?.eatWeightSum ?: 0.0) + weight + binding.detailInclude.tvTotalWeight.text = "总重量:${totalWeight.roundedDecimalPlace(1)}克" val include = binding.nutritionInclude @@ -874,9 +875,9 @@ class MainScreenPresentation( // 设置肉蛋----------------------------------------------------------- val meatEggsArray = UserNutritionUtils.getCalorieArray( - left = userNutrition?.meatEggsRecommend, - mid = userNutrition?.meatEggsNearExcess, - right = userNutrition?.meatEggsExcess + left = userNutrition?.meatEggsBeansRecommend, + mid = userNutrition?.meatEggsBeansNearExcess, + right = userNutrition?.meatEggsBeansExcess ) val meatEggsIndex = UserNutritionUtils.findCalorieIndex(energy.meatEggs, meatEggsArray) @@ -1480,12 +1481,11 @@ class MainScreenPresentation( if (model == null) return@runOnUiThread foodOrderList.clear() foodOrderList.addAll(model.list ?: emptyList()) - foodOrderAdapter.submitList(foodOrderList) - //foodOrderAdapter.notifyDataSetChanged() - binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克" + //foodOrderAdapter.submitList(foodOrderList) + foodOrderAdapter.notifyDataSetChanged() + //binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克" Log.d(TAG, "addFoodToOrder: 更新总重量,订单列表------------------------------") - binding.detailInclude.tvTotalCalorie.text = - "总热量:${model.calorie.roundedDecimalPlace(1)}千卡" +// binding.detailInclude.tvTotalCalorie.text = "总热量:${model.calorie.roundedDecimalPlace(1)}千卡" jointPaymentQueryFinish = true //重新加载营养信息 diff --git a/app/src/main/java/com/sw/dualscreen/utils/FoodVectorTool.kt b/app/src/main/java/com/sw/dualscreen/utils/FoodVectorTool.kt new file mode 100644 index 0000000..d191f00 --- /dev/null +++ b/app/src/main/java/com/sw/dualscreen/utils/FoodVectorTool.kt @@ -0,0 +1,69 @@ +package com.sw.dualscreen.utils + +import androidx.lifecycle.lifecycleScope +import com.sw.dualscreen.GlobalData +import com.sw.dualscreen.activity.InitActivity +import com.sw.dualscreen.model.response.FoodVector +import com.sw.dualscreen.objbox.Food +import com.sw.dualscreen.objbox.ObjectBox +import com.sw.dualscreen.viewmodel.UserViewModel +import kotlinx.coroutines.launch + +object FoodVectorTool { + var pageNum: Int = 1 + const val PAGE_SIZE: Int = InitActivity.PAGE_SIZE + + fun getFoodVector( + userViewModel: UserViewModel, + onPageFinish:(List?)-> Unit, + successBlock: () -> Unit, + failureBlock: (String) -> Unit + ): Unit { + userViewModel.getCollectedFoodVector( + param = mutableMapOf( + "pageNum" to "$pageNum", + "pageSize" to "$PAGE_SIZE", + "version" to GlobalData.foodModelVersion + ) + ) { items -> + if (items == null) { + failureBlock("未查询到向量数据") + return@getCollectedFoodVector + } + val list = items + if (pageNum == 1 && list.isEmpty()) { + //接口成功无数据,暂时认为成功 + successBlock() + return@getCollectedFoodVector + } + if (list.size >= PAGE_SIZE) { + onPageFinish(list) + pageNum++ + getFoodVector(userViewModel, onPageFinish, successBlock, failureBlock) + return@getCollectedFoodVector + } + if (list.isNotEmpty()) { + onPageFinish(list) + } + successBlock() + } + } + + fun saveFoodVector(lifecycleScope: androidx.lifecycle.LifecycleCoroutineScope ,list: List) { + lifecycleScope.launch { + val vectorList = list.map { vt -> + val foodVector = vt.foodVector?.removeSurrounding("[", "]")?.split(",") + ?.map { it.toFloatOrNull() ?: 0.0f }?.toFloatArray() + Food( + collectId = vt.id, + foodId = vt.foodId, + foodName = vt.foodName, + version = vt.version, + foodVector = foodVector + ) + } + ObjectBox.putAll(vectorList) + } + } + +} \ No newline at end of file