Files
StallDualScreen/app/src/main/java/com/sw/dualscreen/viewmodel/UserViewModel.kt
T
2025-08-04 18:02:45 +08:00

212 lines
7.0 KiB
Kotlin

package com.sw.dualscreen.viewmodel
import androidx.lifecycle.viewModelScope
import com.arcsoft.face.ErrorInfo
import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.model.request.UserNutritionParam
import com.sw.dualscreen.model.response.DinnerTypeInfo
import com.sw.dualscreen.model.response.FoodInfo
import com.sw.dualscreen.model.response.UserFaceModel
import com.sw.dualscreen.model.response.UserNutritionData
import com.sw.inbound.utils.SPUtil
import com.sw.plate.App
import com.sw.plate.utils.Base64
import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.FaceApi
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
class UserViewModel : BaseViewModel() {
private val faceApi: FaceApi = FaceApi()
// 识别出的列表
private val _identifiedFoodInfoList = MutableStateFlow<List<FoodInfo>>(emptyList())
val identifiedFoodInfoList: StateFlow<List<FoodInfo>> = _identifiedFoodInfoList
// 搜索出的食物列表
private val _searchFoodInfoList = MutableStateFlow<List<FoodInfo>>(emptyList())
val searchFoodInfoList: StateFlow<List<FoodInfo>> = _searchFoodInfoList
// 就餐数据
private val _nutritionData = MutableStateFlow<UserNutritionData?>(null)
val nutritionData: StateFlow<UserNutritionData?> = _nutritionData
/**
* 饭点类型
*/
private val _dinnerTypeInfo = MutableStateFlow<DinnerTypeInfo?>(null)
val dinnerTypeInfo: StateFlow<DinnerTypeInfo?> = _dinnerTypeInfo
/**
* 获取token
*/
fun getEquipmentToken(qrcodeId: String = "3ea47dc0-3cf0-3c2f-909c-265a9a65572e") {
Timber.d("getEquipmentToken")
launchWithLoading {
val response = repository.getEquipmentToken(qrcodeId)
if (parseResponse(response)) {
// 缓存token
SPUtil.getInstance().put(GlobalKey.KEY_TOKEN, response.result)
// 首次运行获取人脸数据
if (SPUtil.getInstance().get(GlobalKey.KEY_FIRST_RUN, false) != true) {
getUserFaceCache(index = 0)
}
}
}
}
/**
* 获取人脸数据
*/
fun getUserFaceCache(index: Int = 0) {
Timber.d("getUserFaceCache index = $index")
launch {
val response = repository.getUserFaceCache(index)
if (parseResponse(response)) {
// 获取成功一次后缓存状态
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
withContext(Dispatchers.Default) {
val list: List<UserFaceModel> = response.result?.data ?: emptyList()
val faceEntity = list.map {
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureString))
}
faceApi.updateFaceData(index, faceEntity)
activeEngine()
}
val nextPageIndex = response.result?.nextPageIndex ?: -1
if (nextPageIndex > 0) {
getUserFaceCache(nextPageIndex)
}
}
}
}
/**
* 激活人脸识别引擎
*/
fun activeEngine() {
Timber.d("activeEngine")
faceApi.activeEngine(
App.getContext(),
GlobalData.appId,
GlobalData.sdkKey,
GlobalData.activeKey,
object : FaceApi.ActiveCallback {
override fun onSuccess(activeCode: Int) {
Timber.d("activeEngine activeCode = $activeCode")
viewModelScope.launch(Dispatchers.Main) {
when (activeCode) {
ErrorInfo.MOK -> {
ToastUtils.showToast("激活引擎成功")
}
ErrorInfo.MERR_ASF_ALREADY_ACTIVATED -> {
// ToastUtils.showToast("引擎已激活,无需再次激活")
}
else -> {
ToastUtils.showToast("激活引擎失败($activeCode)")
}
}
}
}
override fun onFail(e: Exception?) {
viewModelScope.launch(Dispatchers.Main) {
ToastUtils.showToast("激活引擎异常,${e?.message}")
}
}
})
}
/**
* 重置用户信息
*/
fun resetUserInfo() {
Timber.d("resetUserInfo")
}
fun getIdentifiedFoodList() {
Timber.d("identifiedFoodList")
launchWithLoading {
delay(5000)
_identifiedFoodInfoList.value = List(6) {
FoodInfo(
id = "185225109358109491${it}",
foodName = "豆芽炒粉条$it",
imgUrl = "http://101.201.149.156:9002/temp/20230912/f54b2d76-45e1-4c6b-a7a0-5fd1eace99d1_1694484601879.png"
)
}
// _currentFoodInfo.value = _identifiedFoodInfoList.value[0]
}
}
fun cleanIdentifiedFoodInfoList() {
Timber.d("cleanIdentifiedFoodInfoList")
_identifiedFoodInfoList.value = emptyList<FoodInfo>()
}
/**
* 搜索食物
*/
fun searchByFoodName(foodName: String) {
Timber.d("searchByFoodName foodName = $foodName")
launchWithLoading {
val response = repository.getRestInfoFoodsByType(foodName = foodName)
if (parseResponse(response)) {
_searchFoodInfoList.value = response.result ?: emptyList()
}
}
}
fun cleanSearchFoodInfoList() {
Timber.d("cleanSearchFoodInfoList")
_searchFoodInfoList.value = emptyList<FoodInfo>()
}
/**
* 获取用户就餐数据
*/
fun getUserNutritionData(userId: String, foodId: String) {
Timber.d("getUserNutritionData userId = ${userId}, foodId = $foodId")
launchWithLoading {
val response = repository.getUserNutritionData(userId = userId, foodId = foodId)
if (parseResponse(response)) {
_nutritionData.value = response.result
}
}
}
fun getDinnerType() {
Timber.d("getDinnerType")
launchWithLoading {
val response = repository.getDinnerType()
if (parseResponse(response)) {
_dinnerTypeInfo.value = response.result
}
}
}
/**
* 提交就餐数据
*/
fun postUserNutritionData(param: UserNutritionParam) {
Timber.d("postUserNutritionData param = $param")
launchWithLoading {
val response = repository.postUserNutritionData(param)
if (parseResponse(response)) {
}
}
}
}