feat(data): 更新食物营养数据模型并优化向量数据处理
- 在DataBean中将肉蛋相关字段重命名为肉蛋豆,并添加总重量字段 - 新增FoodVectorTool工具类用于处理食物向量数据的分页获取和存储 - 重构InitActivity中的食物向量数据获取逻辑,使用新的工具类替代原有实现 - 在MainActivity中集成食物向量数据同步功能,在清除本地数据后重新获取 - 更新MainScreenPresentation中营养信息显示逻辑,适配新的数据模型结构 - 修改ApiClient中的日志标记逻辑,为不同接口添加特定的标签 - 调整食物订单列表的数据更新方式,优化适配器通知策略
This commit is contained in:
@@ -17,6 +17,7 @@ import com.sw.dualscreen.model.response.FoodVector
|
|||||||
import com.sw.dualscreen.objbox.Food
|
import com.sw.dualscreen.objbox.Food
|
||||||
import com.sw.dualscreen.objbox.FoodModule
|
import com.sw.dualscreen.objbox.FoodModule
|
||||||
import com.sw.dualscreen.objbox.ObjectBox
|
import com.sw.dualscreen.objbox.ObjectBox
|
||||||
|
import com.sw.dualscreen.utils.FoodVectorTool
|
||||||
import com.sw.dualscreen.utils.L
|
import com.sw.dualscreen.utils.L
|
||||||
import com.sw.dualscreen.utils.NetworkUtils
|
import com.sw.dualscreen.utils.NetworkUtils
|
||||||
import com.sw.dualscreen.viewmodel.BaseViewModel
|
import com.sw.dualscreen.viewmodel.BaseViewModel
|
||||||
@@ -26,7 +27,7 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
class InitActivity : BaseActivity<ActivityInitBinding>() {
|
class InitActivity : BaseActivity<ActivityInitBinding>() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val PAGE_SIZE = 100
|
const val PAGE_SIZE = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
private val userViewModel by viewModels<UserViewModel>()
|
private val userViewModel by viewModels<UserViewModel>()
|
||||||
@@ -41,52 +42,47 @@ class InitActivity : BaseActivity<ActivityInitBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getCollectedFoodVector(block: () -> Unit) {
|
private fun getCollectedFoodVector(block: () -> Unit) {
|
||||||
userViewModel.getCollectedFoodVector(
|
// userViewModel.getCollectedFoodVector(
|
||||||
param = mutableMapOf(
|
// param = mutableMapOf(
|
||||||
"pageNum" to "$pageNum",
|
// "pageNum" to "$pageNum",
|
||||||
"pageSize" to "$PAGE_SIZE",
|
// "pageSize" to "$PAGE_SIZE",
|
||||||
"version" to GlobalData.foodModelVersion
|
// "version" to GlobalData.foodModelVersion
|
||||||
)
|
// )
|
||||||
) { items ->
|
// ) { items ->
|
||||||
if (items == null) {
|
// 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()
|
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 val box by lazy { ObjectBox.boxStore.boxFor(Food::class) }
|
||||||
private fun saveFoodVector(list: List<FoodVector>) {
|
|
||||||
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() {
|
override fun initialize() {
|
||||||
super.initialize()
|
super.initialize()
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import com.sw.dualscreen.socket.TcpClient
|
|||||||
import com.sw.dualscreen.utils.ActivityManager
|
import com.sw.dualscreen.utils.ActivityManager
|
||||||
import com.sw.dualscreen.utils.BitmapSaver
|
import com.sw.dualscreen.utils.BitmapSaver
|
||||||
import com.sw.dualscreen.utils.Debouncer
|
import com.sw.dualscreen.utils.Debouncer
|
||||||
|
import com.sw.dualscreen.utils.FoodVectorTool
|
||||||
import com.sw.dualscreen.utils.GsonUtils
|
import com.sw.dualscreen.utils.GsonUtils
|
||||||
import com.sw.dualscreen.utils.ImageUtil
|
import com.sw.dualscreen.utils.ImageUtil
|
||||||
import com.sw.dualscreen.utils.IntervalExecutor
|
import com.sw.dualscreen.utils.IntervalExecutor
|
||||||
@@ -215,6 +216,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
FaceServer.getInstance().clearAllFaces()
|
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 = {
|
viewModel.getUserFaceCache(pageNo = 1, onSuccess = {
|
||||||
recognizeViewModel.refreshFaceList()
|
recognizeViewModel.refreshFaceList()
|
||||||
|
|||||||
@@ -100,12 +100,14 @@ data class UserNutrition(
|
|||||||
val fruitsVegetablesNearExcess: String? = null,
|
val fruitsVegetablesNearExcess: String? = null,
|
||||||
//果蔬超量
|
//果蔬超量
|
||||||
val fruitsVegetablesExcess: String? = null,
|
val fruitsVegetablesExcess: String? = null,
|
||||||
//肉蛋推荐值
|
//肉蛋豆推荐值
|
||||||
val meatEggsRecommend: String? = null,
|
val meatEggsBeansRecommend: String? = null,
|
||||||
//肉蛋即将超量
|
//肉蛋豆即将超量
|
||||||
val meatEggsNearExcess: String? = null,
|
val meatEggsBeansNearExcess: String? = null,
|
||||||
//肉蛋超量
|
//肉蛋豆超量
|
||||||
val meatEggsExcess: 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}
|
//{"code":"00000","data":"{\"orderType\":0,\"orderPayFrom\":2,\"payType\":\"1\",\"paySuc\":0,\"totalFee\":0.01,\"orderCode\":\"1998193614899372032\",\"message\":\"支付成功\",\"payCode\":\"1998193614899372032508227\"}","msg":"成功","total":0}
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ object ApiClient {
|
|||||||
.addNetworkInterceptor(Interceptor {chain ->
|
.addNetworkInterceptor(Interceptor {chain ->
|
||||||
val request = chain.request()
|
val request = chain.request()
|
||||||
val url = request.url.toString()
|
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 = {
|
val loggingInterceptor = HttpLoggingInterceptor(logger = {
|
||||||
Timber.tag(tag).d("okhttp logger ==>${it}")
|
Timber.tag(tag).d("okhttp logger ==>${it}")
|
||||||
}).apply {
|
}).apply {
|
||||||
|
|||||||
@@ -485,9 +485,7 @@ class MainScreenPresentation(
|
|||||||
binding.nutritionInclude.tvUserName.text = userNutrition?.name.maskName()
|
binding.nutritionInclude.tvUserName.text = userNutrition?.name.maskName()
|
||||||
val recommendCalorie = (userNutrition?.recommendCalorie ?: 0.0).roundedDecimalPlace(1)
|
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"
|
// binding.nutritionInclude.tvRecommendHeat.text = "推荐热量:${recommendCalorie.removeTrailingZeros()}kcal"
|
||||||
//updateWeight(lastWeight / 1000)
|
//updateWeight(lastWeight / 1000)
|
||||||
// -------------------------------------------------
|
// -------------------------------------------------
|
||||||
@@ -715,8 +713,8 @@ class MainScreenPresentation(
|
|||||||
val last = foodOrderList.last()
|
val last = foodOrderList.last()
|
||||||
if (last.isLocalData) {
|
if (last.isLocalData) {
|
||||||
foodOrderList.remove(last)
|
foodOrderList.remove(last)
|
||||||
foodOrderAdapter.submitList(foodOrderList)
|
// foodOrderAdapter.submitList(foodOrderList)
|
||||||
//foodOrderAdapter.notifyDataSetChanged()
|
foodOrderAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -730,8 +728,8 @@ class MainScreenPresentation(
|
|||||||
last.eatNum = eatNum
|
last.eatNum = eatNum
|
||||||
last.num = weight
|
last.num = weight
|
||||||
last.price = price
|
last.price = price
|
||||||
foodOrderAdapter.submitList(foodOrderList)
|
// foodOrderAdapter.submitList(foodOrderList)
|
||||||
//foodOrderAdapter.notifyItemChanged(foodOrderList.lastIndex)
|
foodOrderAdapter.notifyItemChanged(foodOrderList.lastIndex)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -750,7 +748,8 @@ class MainScreenPresentation(
|
|||||||
isLocalData = true
|
isLocalData = true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
foodOrderAdapter.submitList(foodOrderList)
|
// foodOrderAdapter.submitList(foodOrderList)
|
||||||
|
foodOrderAdapter.notifyDataSetChanged()
|
||||||
Log.d(
|
Log.d(
|
||||||
TAG,
|
TAG,
|
||||||
"addFoodToOrder: size=${foodOrderList.size},新增数据:${foodOrderList.last()}"
|
"addFoodToOrder: size=${foodOrderList.size},新增数据:${foodOrderList.last()}"
|
||||||
@@ -803,8 +802,10 @@ class MainScreenPresentation(
|
|||||||
val fruitsVegetables = energy.fruitsVegetables
|
val fruitsVegetables = energy.fruitsVegetables
|
||||||
val meatEggs = energy.meatEggs
|
val meatEggs = energy.meatEggs
|
||||||
|
|
||||||
binding.detailInclude.tvTotalCalorie.text =
|
binding.detailInclude.tvTotalCalorie.text = "总热量:${totalKcal.roundedDecimalPlace(1)}千卡"
|
||||||
"总热量:${totalKcal.roundedDecimalPlace(1)}千卡"
|
|
||||||
|
val totalWeight = (userNutrition?.eatWeightSum ?: 0.0) + weight
|
||||||
|
binding.detailInclude.tvTotalWeight.text = "总重量:${totalWeight.roundedDecimalPlace(1)}克"
|
||||||
|
|
||||||
val include = binding.nutritionInclude
|
val include = binding.nutritionInclude
|
||||||
|
|
||||||
@@ -874,9 +875,9 @@ class MainScreenPresentation(
|
|||||||
|
|
||||||
// 设置肉蛋-----------------------------------------------------------
|
// 设置肉蛋-----------------------------------------------------------
|
||||||
val meatEggsArray = UserNutritionUtils.getCalorieArray(
|
val meatEggsArray = UserNutritionUtils.getCalorieArray(
|
||||||
left = userNutrition?.meatEggsRecommend,
|
left = userNutrition?.meatEggsBeansRecommend,
|
||||||
mid = userNutrition?.meatEggsNearExcess,
|
mid = userNutrition?.meatEggsBeansNearExcess,
|
||||||
right = userNutrition?.meatEggsExcess
|
right = userNutrition?.meatEggsBeansExcess
|
||||||
)
|
)
|
||||||
val meatEggsIndex =
|
val meatEggsIndex =
|
||||||
UserNutritionUtils.findCalorieIndex(energy.meatEggs, meatEggsArray)
|
UserNutritionUtils.findCalorieIndex(energy.meatEggs, meatEggsArray)
|
||||||
@@ -1480,12 +1481,11 @@ class MainScreenPresentation(
|
|||||||
if (model == null) return@runOnUiThread
|
if (model == null) return@runOnUiThread
|
||||||
foodOrderList.clear()
|
foodOrderList.clear()
|
||||||
foodOrderList.addAll(model.list ?: emptyList())
|
foodOrderList.addAll(model.list ?: emptyList())
|
||||||
foodOrderAdapter.submitList(foodOrderList)
|
//foodOrderAdapter.submitList(foodOrderList)
|
||||||
//foodOrderAdapter.notifyDataSetChanged()
|
foodOrderAdapter.notifyDataSetChanged()
|
||||||
binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克"
|
//binding.detailInclude.tvTotalWeight.text = "总重量:${model.eatWeightSum}克"
|
||||||
Log.d(TAG, "addFoodToOrder: 更新总重量,订单列表------------------------------")
|
Log.d(TAG, "addFoodToOrder: 更新总重量,订单列表------------------------------")
|
||||||
binding.detailInclude.tvTotalCalorie.text =
|
// binding.detailInclude.tvTotalCalorie.text = "总热量:${model.calorie.roundedDecimalPlace(1)}千卡"
|
||||||
"总热量:${model.calorie.roundedDecimalPlace(1)}千卡"
|
|
||||||
jointPaymentQueryFinish = true
|
jointPaymentQueryFinish = true
|
||||||
|
|
||||||
//重新加载营养信息
|
//重新加载营养信息
|
||||||
|
|||||||
@@ -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<FoodVector>?)-> 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<FoodVector>) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user