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.DeviceConfig import com.sw.dualscreen.model.response.DinnerType import com.sw.dualscreen.model.response.FoodInfo import com.sw.dualscreen.model.response.FoodOrder import com.sw.dualscreen.model.response.FoodVector import com.sw.dualscreen.model.response.MemberInfo import com.sw.dualscreen.model.response.UserFaceModel import com.sw.dualscreen.model.response.UserFaceModel2 import com.sw.dualscreen.model.response.UserNutrition import com.sw.dualscreen.objbox.CollectedFoodInfo import com.sw.dualscreen.utils.SPUtil import com.sw.dualscreen.utils.SpTool 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.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okhttp3.RequestBody import timber.log.Timber import java.io.File class UserViewModel : BaseViewModel() { companion object { private const val TAG = "UserViewModel" const val PAGE_SIZE = 100 } private val faceApi: FaceApi = FaceApi() // 识别出的列表 // private val _identifiedFoodInfoList = MutableStateFlow>(emptyList()) // val identifiedFoodInfoList: StateFlow> = _identifiedFoodInfoList // 搜索出的食物列表 // private val _searchFoodInfoList = MutableStateFlow>(emptyList()) // val searchFoodInfoList: StateFlow> = _searchFoodInfoList // 就餐数据 // private val _nutritionData = MutableStateFlow(null) // val nutritionData: StateFlow = _nutritionData /** * 饭点类型 早餐/午餐/晚餐 */ private val _dinnerTypeInfo = MutableStateFlow(null) val dinnerTypeInfo: StateFlow = _dinnerTypeInfo /** * 人脸加载完成 */ private val _loadFaceResult = MutableStateFlow(false) val loadFaceResult: StateFlow = _loadFaceResult private val _identifiedFoodInfoList2 = MutableStateFlow>(emptyList()) val identifiedFoodInfoList2: StateFlow> = _identifiedFoodInfoList2 private var lastFaceTimestamp = 0L /** * 获取token */ fun getEquipmentToken(qrcodeId: String = GlobalData.deviceId) { // Timber.tag(TAG).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(pageNo = 1) // } // } // } } /** * 获取人脸数据 */ fun getUserFaceCache(pageNo: Int = 1, pageSize: Int = PAGE_SIZE) { var currentPageNo = pageNo Timber.tag(TAG).d("getUserFaceCache index = $currentPageNo") launch { _loadFaceResult.value = false //获取全量数据时,时间戳改为0 SpTool.setLastFaceTimestamp(0) val response = repository.getUserFaceCache(currentPageNo) if (parseResponse(response)) { // 获取成功一次后缓存状态 SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) withContext(Dispatchers.Default) { val list: List = response.data ?: emptyList() if (pageNo == 1 && list.isEmpty()) { ToastUtils.showToast("查询人脸数据为空") return@withContext } // val item = list.firstOrNull { it.userId == "1951105919342936066" } // Timber.tag(TAG).d("getUserFaceCache userId = ${item?.userId}") val faceEntity = list.map { FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr)) } faceApi.updateFaceData(currentPageNo, faceEntity) if (list.size >= pageSize) { lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L currentPageNo++ getUserFaceCache(currentPageNo) return@withContext } //查询完成所有数据,保存时间戳 if (list.isNotEmpty()) { //非空最后一条数据的是时间戳,空使用上次list最后一条时间戳 lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L } SpTool.setLastFaceTimestamp(lastFaceTimestamp) _loadFaceResult.value = true } // val nextPageIndex = response.result?.nextPageIndex ?: -1 // if (nextPageIndex > 0) { // getUserFaceCache(nextPageIndex) // } else { // _loadFaceResult.value = true // } } } } // fun getUserFaceCache2(index: Int = 0) { // Timber.d("getUserFaceCache index = $index") // launch { // _loadFaceResult.value = false // val response = repository.getUserFaceCache2(index) // if (parseResponse(response)) { // // 获取成功一次后缓存状态 // SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) // withContext(Dispatchers.Default) { // val list: List = response.result?.records ?: emptyList() // val faceEntity = list.map { // FaceEntity(it.userId, null, Base64.decode(it.face)) // } // faceApi.updateFaceData2(index, faceEntity) // } // val nextPageIndex = response.result?.nextPageIndex ?: -1 // if (nextPageIndex > 0) { // getUserFaceCache2(nextPageIndex) // } else { // _loadFaceResult.value = true // } // } // } // } /** * 获取人脸数据 */ fun getFaceIncrementList( pageNo: Int = 1, pageSize: Int = PAGE_SIZE, timestamp: Long, onAllQueryFinished: () -> Unit, onPageQueryFinished: (List) -> Unit ) { Timber.tag(TAG).d("getFaceIncrementList") launch { val response = repository.getFaceIncrementList( pageNum = pageNo.toLong(), pageSize = pageSize.toLong(), timestamp = timestamp ) if (parseResponse(response)) { withContext(Dispatchers.Default) { val list: List = response.data ?: emptyList() if (pageNo == 1 && list.isEmpty()) { return@withContext } onPageQueryFinished(list) if (list.size >= pageSize) { lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L getFaceIncrementList( pageNo = pageNo + 1, pageSize = pageSize, timestamp = timestamp, onAllQueryFinished = onAllQueryFinished, onPageQueryFinished = onPageQueryFinished ) return@withContext } //查询完成所有数据,保存时间戳 if (list.isNotEmpty()) { //非空实现最后一条数据的是时间戳,空使用上次list最后一条时间戳 lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L } SpTool.setLastFaceTimestamp(lastFaceTimestamp) onAllQueryFinished() } } } } fun getCollectedFoodList( pageNo: Int = 1, pageSize: Int = 100, foodName: String, block: (List) -> Unit ) { Timber.tag(TAG).d("getCollectedFoodList index = $pageNo") launch { val response = repository.getCollectedFoodList( pageNum = pageNo, pageSize = pageSize, foodName = foodName ) if (parseResponse(response)) { withContext(Dispatchers.Default) { val list: List = response.data ?: emptyList() block(list) } } else { block(emptyList()) } } } /** * 激活人脸识别引擎 */ fun activeEngine() { Timber.tag(TAG).d("activeEngine") faceApi.activeEngine( App.getContext(), GlobalData.appId, GlobalData.sdkKey, GlobalData.activeKey, object : FaceApi.ActiveCallback { override fun onSuccess(activeCode: Int) { Timber.tag(TAG).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 getIdentifiedFoodList() { // Timber.tag(TAG).d("identifiedFoodList") // launchWithLoading { // val response = repository.getRestInfoFoodsByType(foodName = "") // if (parseResponse(response)) { // _identifiedFoodInfoList.value = response.result ?: emptyList() // } // } // } // fun cleanIdentifiedFoodInfoList() { // Timber.tag(TAG).d("cleanIdentifiedFoodInfoList") // _identifiedFoodInfoList.value = emptyList() // } /** * 搜索食物 */ fun searchByFoodName(foodName: String, action: (List) -> Unit = {}) { Timber.tag(TAG).d("searchByFoodName foodName = $foodName") launchWithLoading { val response = repository.getRestInfoFoodsByType(foodName = foodName) if (parseResponse(response)) { val list = response.data ?: emptyList() action(list) // _identifiedFoodInfoList.value = response.data ?: emptyList() } } } // fun cleanSearchFoodInfoList() { // Timber.tag(TAG).d("cleanSearchFoodInfoList") // _searchFoodInfoList.value = emptyList() // } // /** // * 获取用户就餐数据 // */ // fun getUserNutritionData(userId: String, foodId: String) { // Timber.tag(TAG).d("getUserNutritionData userId = ${userId}, foodId = $foodId") // _nutritionData.value = null // launch { // val response = repository.getUserNutritionData(userId = userId, foodId = foodId) // if (parseResponse(response)) { // _nutritionData.value = response.result // } // } // } /** * 获取用户就餐数据 */ fun getUserNutritionData(userId: String, block: (UserNutrition?) -> Unit) { Timber.tag(TAG).d("getUserNutritionData userId = $userId") launch { val response = repository.getUserNutritionData(userId = userId) if (parseResponse(response)) { block(response.data) } else { block(null) } } } /** * 获取支付二维码 */ fun getQrCodeImg( orderId: String, userId: String? = null, totalFee: String? = null, block: (String?) -> Unit ) { Timber.tag(TAG).d("getQrCodeImg orderId = $orderId, userId = $userId") launch { val response = repository.getQrCodeImg(orderNo = orderId, memberId = userId, totalFee = totalFee) if (parseResponse(response)) { block(response.data) } else { block(null) } } } fun getDinnerType() { Timber.tag(TAG).d("getDinnerType") _dinnerTypeInfo.value = null launch { val response = repository.getDinnerType() if (parseResponse(response)) { _dinnerTypeInfo.value = response.data } } } /** * 提交就餐数据 */ fun postUserNutritionData(param: List) { Timber.tag(TAG).d("postUserNutritionData param = $param") launch { val response = repository.postUserNutritionData(param) if (parseResponse(response)) { } } } fun getFoodInfo(foodName: String, action: (List) -> Unit = {}) { Timber.tag(TAG).d("getFoodInfo") launchWithLoading { val response = repository.getFoodInfo(foodName = foodName) if (parseResponse(response)) { val list = response.data ?: emptyList() // _identifiedFoodInfoList.value = list action(list) } else { action(emptyList()) } } } fun createOrder(order: FoodOrder, block: (String) -> Unit) { Timber.tag(TAG).d("createOrder") launchWithLoading { val response = repository.createOrder(order) if (parseResponse(response)) { block(response.data.toString()) } else { block("") } } } /** * 现金支付 */ fun cashPay(param: HashMap, block: (Boolean) -> Unit) { Timber.tag(TAG).d("cashPay") launchWithLoading { val response = repository.cashPay(param) if (parseResponse(response)) { block(response.data ?: false) } else { block(false) } } } // /** // * 查询订单状态 // * // * @param queryType 查询类型 1支付2退款 // * @param orderId 订单号 // */ // fun queryOrderState(queryType:Int, orderId:String, block:(PayResult?)-> Unit) { // Timber.tag(TAG).d("queryOrderState") // val param = hashMapOf( // "queryType" to "$queryType", // "payOrderNo" to orderId // ) // launchWithLoading { // val response = repository.queryOrderState(param) // if (parseResponse(response)) { // block(response.data) // } else { // block(null) // } // } // } /** * 扫码成功回调 * * @param orderId 订单号 */ suspend fun queryOrderState(orderId: String, block: (Boolean) -> Unit) { Timber.tag(TAG).d("queryOrderState") val response = repository.queryOrderState(orderNo = orderId) if (parseResponse(response)) { //val respData = response.data as? String // ?: if (response.data is Any) { // GsonUtils.toJson(response.data) // } else { // "" // } //al payResult = GsonUtils.fromJson(respData, PayResult::class.java) //val orderState = payResult?.paySuc == "1" //data=1的话 是支付成功 0是待支付 block(response.data == "1") } else { block(false) } } /** * 会员支付 */ fun memberPay(param: HashMap, block: (Boolean) -> Unit) { Timber.tag(TAG).d("memberPay") launchWithLoading { val response = repository.memberPay(param) if (parseResponse(response)) { block(true) } else { block(false) } } } /** * 绑定订单 */ fun bindOrder(userId: String, orderId: String, mode: Int, block: (Boolean) -> Unit) { Timber.tag(TAG).d("bindOrder") launchWithLoading { val response = repository.bindOrder(userId = userId, orderId = orderId, mode = mode) if (parseResponse(response)) { block(true) } else { block(false) } } } fun getMemberInfoById(memberId: String, block: (MemberInfo?) -> Unit) { Timber.tag(TAG).d("getMemberInfo") launchWithLoading { val response = repository.getMemberInfoById(memberId) if (parseResponse(response)) { block(response.data) } else { block(null) } } } fun getMemberInfoByPhone(phone: String, key: String, block: (MemberInfo?) -> Unit) { Timber.tag(TAG).d("getMemberInfo") launchWithLoading { val response = repository.getMemberInfoByPhone(phone, key) if (parseResponse(response)) { block(response.data) } else { block(null) } } } // fun uploadCollectFoodPics(files: List, params: HashMap, callback: (Boolean) -> Unit) { // Timber.tag(TAG).d("uploadCollectFoodPics") // launchWithLoading { // val fileList = files.filterNotNull() // if (fileList.isEmpty()) { // callback(false) // return@launchWithLoading // } // val resp = repository.uploadCollectFoodPics(fileList, params) // if (!parseResponse(resp)) { // callback(false) // return@launchWithLoading // } // callback(resp.code == "00000") // } // } suspend fun uploadCollectFoodPics( files: List, params: HashMap ): List? { Timber.tag(TAG).d("uploadCollectFoodPics") val fileList = files.filterNotNull() if (fileList.isEmpty()) { return null } val resp = repository.uploadCollectFoodPics(fileList, params) if (resp.code != "00000") { return null } return resp.data } fun getDeviceConfig(block: (DeviceConfig?) -> Unit) { Timber.tag(TAG).d("getDeviceConfig") launchWithLoading { val response = repository.getDeviceConfig() if (parseResponse(response)) { block(response.data) } else { block(null) } } } fun getCollectedFoodVector(param: MutableMap, block: (List?) -> Unit) { Timber.tag(TAG).d("getCollectedFoodVector") launchWithLoading { val response = repository.getCollectedFoodVector(param) if (parseResponse(response)) { block(response.data) } else { block(null) } } } fun deleteCollectFood(foodId:String?, version: String?, block: (Boolean) -> Unit) { Timber.tag(TAG).d("deleteCollectFood") launchWithLoading { val response = repository.deleteCollectFood(foodId, version) if (parseResponse(response)) { block(true) } else { block(false) } } } }