package com.sw.platecabinet.viewmodel import androidx.lifecycle.viewModelScope import com.arcsoft.face.ErrorInfo 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 com.sw.platecabinet.GlobalData import com.sw.platecabinet.GlobalKey import com.sw.platecabinet.model.DeviceConfig import com.sw.platecabinet.model.response.UserFaceModel import com.sw.platecabinet.utils.SpTool import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber import java.io.File /** * 用户viewmodel */ class UserViewModel : BaseViewModel() { companion object { const val PAGE_SIZE = 100 } private val faceApi: FaceApi = FaceApi() fun getUserFace( pageNo: Int, pageSize: Int, callback: (List) -> Unit ) { launchWithLoading { val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize) val status = parseResponse(response) if (status) callback(response.data ?: emptyList()) else emptyList() } } /** * 获取人脸数据 */ fun getUserFaceCache( pageNo: Int = 1, pageSize: Int = PAGE_SIZE, callback: (Boolean, String?) -> Unit = { statue, msg -> } ) { var currentPageNo = pageNo launchWithLoading { val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize) val status = parseResponse(response) if (status.not()) { callback(false, response.msg) return@launchWithLoading } // 获取成功一次后缓存状态 SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) val list: List = response.data ?: emptyList() if (pageNo == 1 && list.isEmpty()) { callback(false, "暂无数据") return@launchWithLoading } val faceEntityList = list.map { FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr)).apply { userType = if (it.member) "1" else "2" } } withContext(Dispatchers.Default) { if (currentPageNo == 1) { //第一页数据删除本地数据库 faceApi.clearFaceData() } faceApi.updateFaceData(pageNo, faceEntityList) if (list.size >= pageSize) { faceTimestamp = list.last().faceUpdateTimestamp ?: 0 currentPageNo++ getUserFaceCache( pageNo = currentPageNo, callback = callback ) return@withContext } if (list.isNotEmpty()) { faceTimestamp = list.last().faceUpdateTimestamp ?: 0 } SpTool.lastFaceTimestamp = faceTimestamp callback(true, "查询完成") } } } private var faceTimestamp = 0L /** * 激活人脸识别引擎 */ 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") // ThreadUtils.launch { 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 getDeviceConfig(block: (DeviceConfig?) -> Unit) { // Timber.tag(TAG).d("getDeviceConfig") launch { val response = repository.getDeviceConfig() if (parseResponse(response)) { block(response.data) } else { block(null) } } } /** * 获取人脸数据 */ fun getFaceIncrementList( pageNo: Int = 1, pageSize: Int = PAGE_SIZE, timestamp: Long, block: (List) -> Unit ) { 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() block(list) } } } } /** * 添加人脸数据 */ fun addUserFace(faceData: String, imageFile: File, block: (Boolean, UserFaceModel?) -> Unit) { launch { val imageResp = repository.uploadImage(imageFile) val imageUrl = imageResp.data ?: "" if (imageUrl.isBlank()) { block(false, null) return@launch } val faceResp = repository.addUserFace(faceData, imageUrl) val status = parseResponse(faceResp) if (status.not()) { block(false, null) return@launch } block(true, faceResp.data) } } }