From 95b4f5e8f2389e40507a58b79157a50034aa1893 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Tue, 30 Jun 2026 10:08:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(network):=20=E6=B7=BB=E5=8A=A0API=20V2?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=94=AF=E6=8C=81=E5=B9=B6=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增ApiServiceV2接口定义,支持人脸缓存、增量数据、设备配置等功能 - 添加NetViewModelV2视图模型,实现新版本API的数据处理逻辑 - 创建RemoteRepositoryV2仓库,封装API V2的网络请求操作 - 新增UserFaceModelV2数据模型,优化人脸特征数据结构 - 添加DeviceConfigV2设备配置模型,支持更多设备参数 - 在ApiClient中注册apiServiceV2实例 - 更新BaseActivity使用NetViewModelV2替代UserViewModel - 修改DeviceInitActivity中的人脸数据获取和设备配置逻辑 - 重构FaceDao数据库访问对象,优化用户类型查询和删除操作 - 更新FaceEntity实体类,增加更多用户相关字段 - 移除BaseViewModel中的旧版网络基础功能代码 - 优化人脸数据同步和存储流程,提升性能表现 --- .../sw/platecabinet/activity/BaseActivity.kt | 80 +--- .../activity/DeviceInitActivity.kt | 11 +- .../activity/LoginByFaceActivity.kt | 21 +- .../com/sw/platecabinet/model/ErrorInfo.kt | 23 + .../model/response/UserFaceModel.kt | 17 +- .../model/response/UserFaceModelV2.kt | 44 ++ .../com/sw/platecabinet/network/ApiClient.kt | 5 + .../platecabinet/network/api/ApiServiceV2.kt | 66 +++ .../repository/RemoteRepositoryV2.kt | 70 +++ .../platecabinet/viewmodel/BaseViewModel.kt | 146 +++---- .../platecabinet/viewmodel/NetViewModelV2.kt | 249 +++++++++++ .../platecabinet/viewmodel/UserViewModel.kt | 402 +++++++++--------- .../com/sw/plate/utils/arcface/FaceApi.java | 24 +- .../utils/arcface/facedb/dao/FaceDao.java | 6 +- .../arcface/facedb/entity/FaceEntity.java | 23 +- 15 files changed, 792 insertions(+), 395 deletions(-) create mode 100644 app/src/main/java/com/sw/platecabinet/model/response/UserFaceModelV2.kt create mode 100644 app/src/main/java/com/sw/platecabinet/network/api/ApiServiceV2.kt create mode 100644 app/src/main/java/com/sw/platecabinet/repository/RemoteRepositoryV2.kt create mode 100644 app/src/main/java/com/sw/platecabinet/viewmodel/NetViewModelV2.kt diff --git a/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt index 8d8b192..5762ddd 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/BaseActivity.kt @@ -25,11 +25,10 @@ import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel import com.sw.platecabinet.R import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.ext.clickWithCoroutines -import com.sw.platecabinet.model.response.UserFaceModel import com.sw.platecabinet.utils.IntervalExecutor import com.sw.platecabinet.utils.SpTool import com.sw.platecabinet.view.CustomLoadingDialog -import com.sw.platecabinet.viewmodel.UserViewModel +import com.sw.platecabinet.viewmodel.NetViewModelV2 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch @@ -48,10 +47,8 @@ abstract class BaseActivity : AppCompatActivity() { // private val permissionHelpers = mutableMapOf() // protected var keyEventHelper: ScanGunKeyEventHelper? = null - // 用户对应的viewModel - protected val userViewModel by viewModels() - public val recognizeViewModel by viewModels() + public val netViewModelV2 by viewModels() private var startTime: Long = 0 @@ -298,84 +295,23 @@ abstract class BaseActivity : AppCompatActivity() { // private val dealyMillis = 10 * 60 * 1000L private val initialDelay = 1 * 1000L private val dealyMillis = 10 * 1000L - fun startFaceTask(block: (List) -> Unit) { + fun startFaceTask() { faceTaskJob = intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) { - getFaceIncrementList(action = block) + getFaceIncrementList() } } private var faceTimestamp = 0L //private var taskPageNo = 1 - private fun getFaceIncrementList(pageNo: Int = 1, action: (List) -> Unit) { + private fun getFaceIncrementList(pageNo: Int = 1) { val timestamp = SpTool.lastFaceTimestamp - userViewModel.getFaceIncrementList( + netViewModelV2.getFaceIncrementList( pageNo = pageNo, timestamp = timestamp - ) { list -> - runOnUiThread { - if (pageNo == 1 && list.isEmpty()) { - return@runOnUiThread - } - updateFaceData(list) - val userIdList = list.map { it.userId } - action(userIdList) - if (list.isNotEmpty()) { - faceTimestamp = list.last().faceUpdateTimestamp ?: 0 - } - SpTool.lastFaceTimestamp = faceTimestamp - } - } - } - - private fun updateFaceData(list: List) { - lifecycleScope.launch(Dispatchers.IO) { - val faceList = mutableListOf() - val faceDao = FaceDatabase.getInstance(this@BaseActivity).faceDao() - try { - list.forEach { model -> - if (model.faceDeleted == true) { - //删除数据 - faceDao.deleteFaceById(model.userId) - } else { - // 获取该用户所有已存特征,判断当前特征是否已存在 - val existList = faceDao.queryAllByUserName(model.userId) - val featureMatches = - existList.map { Base64.encode(it.featureData) == model.faceFeatureStr } - Timber.d("userId=${model.userId}, 已存记录数=${existList.size}, 各条特征是否与服务器一致=$featureMatches") - val alreadyExists = featureMatches.any { it } - if (!alreadyExists) { - //当前特征不存在,保存 - runCatching { getNewFaceEntity(model) } - .onSuccess { faceList.add(it) } - .onFailure { Timber.e(it, "人脸特征解码失败: userId=${model.userId}") } - } - } - } - } catch (e: Exception) { - e.printStackTrace() - } - try { - if (faceList.isNotEmpty()) { - FaceDatabase.getInstance(this@BaseActivity).faceDao().insert(faceList) - } - recognizeViewModel.refreshFaceList() - } catch (e: Exception) { - e.printStackTrace() - } - } - } - - private fun getNewFaceEntity(model: UserFaceModel): FaceEntity { - return FaceEntity( - model.userId, - null, - Base64.decode(model.faceFeatureStr) - ).also { - //1-会员、2-临时用户 - it.userType = if (model.member) "1" else "2" - it.cardNo = model.cardNo + ) { + recognizeViewModel.refreshFaceList() } } diff --git a/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt index 176367a..ac0706e 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/DeviceInitActivity.kt @@ -3,7 +3,6 @@ package com.sw.platecabinet.activity import android.content.Intent import androidx.lifecycle.lifecycleScope import com.sw.plate.utils.ToastUtils -import com.sw.plate.utils.arcface.FaceApi import com.sw.platecabinet.GlobalData import com.sw.platecabinet.databinding.ActivityDeviceInitBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding @@ -32,7 +31,7 @@ class DeviceInitActivity : BaseActivity() { //val count = FaceApi().queryFaceCount() //if (count == 0) { if (SpTool.firstGetFace) { - userViewModel.getUserFaceCache { status, msg -> + netViewModelV2.getUserFaceCache { status, msg -> SpTool.firstGetFace = false getDeviceConfig() } @@ -44,7 +43,7 @@ class DeviceInitActivity : BaseActivity() { } private fun getDeviceConfig() { - userViewModel.getDeviceConfig { deviceConfig -> + netViewModelV2.getDeviceConfig(onSuccess = { deviceConfig -> runOnUiThread { if (deviceConfig == null) { hideWaitingDialog() @@ -61,7 +60,11 @@ class DeviceInitActivity : BaseActivity() { goLoginActivity() }, 500) } - } + }, onFailure = { errMsg -> + runOnUiThread { + ToastUtils.showToast(errMsg ?: "接口异常") + } + }) } override fun registerDataChange() { diff --git a/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt b/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt index 15d3bb4..12ba983 100644 --- a/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt +++ b/app/src/main/java/com/sw/platecabinet/activity/LoginByFaceActivity.kt @@ -20,7 +20,6 @@ import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import com.arcsoft.face.ErrorInfo import com.bumptech.glide.Glide -import com.google.gson.Gson import com.sw.inbound.utils.DateTimeUtils import com.sw.plate.utils.Base64 import com.sw.plate.utils.ToastUtils @@ -33,7 +32,6 @@ import com.sw.plate.utils.arcface.PreviewConfig import com.sw.plate.utils.arcface.camera.CameraListener import com.sw.plate.utils.arcface.camera.DualCameraHelper import com.sw.plate.utils.arcface.face.constants.LivenessType -import com.sw.plate.utils.arcface.face.constants.RecognizeColor import com.sw.plate.utils.arcface.face.model.CompareResult import com.sw.plate.utils.arcface.face.model.FacePreviewInfo import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration @@ -49,7 +47,7 @@ import com.sw.platecabinet.dialog.CustomDialog import com.sw.platecabinet.ext.clickWithDebounce import com.sw.platecabinet.ext.gone import com.sw.platecabinet.ext.visible -import com.sw.platecabinet.model.response.UserFaceModel +import com.sw.platecabinet.model.response.UserFaceModelV2 import com.sw.platecabinet.utils.BitmapSaver import com.sw.platecabinet.utils.CountDownUtil import com.sw.platecabinet.utils.Debouncer @@ -113,9 +111,7 @@ class LoginByFaceActivity : BaseActivity(), EventBus.getDefault().register(this) //开启人脸增量数据定时任务 - startFaceTask { - loadLogInfo("collectFace增量接口数据用户id:${Gson().toJson(it)}") - } + startFaceTask() val soundMap = hashMapOf() soundMap[COLLECT_SUCCESS] = R.raw.collect_success @@ -887,7 +883,7 @@ class LoginByFaceActivity : BaseActivity(), } private fun addUserFace(faceData: String, imageFile: File) { - userViewModel.addUserFace(faceData, imageFile) { status, faceModel -> + netViewModelV2.addUserFace(faceData, imageFile) { status, faceModel -> loadLogInfo("collectFace,saveFaceInfo: ----------12,人脸数据发送完成时间:${DateTimeUtils.getDateTimeString()},结果:$status-----------") if (status.not()) { ToastUtils.showToast("新增数据失败") @@ -943,18 +939,11 @@ class LoginByFaceActivity : BaseActivity(), private var currentUserId: String? = null - private fun saveFaceInfo(faceModel: UserFaceModel, block: () -> Unit = {}) { + private fun saveFaceInfo(faceModel: UserFaceModelV2, block: () -> Unit = {}) { try { loadLogInfo("collectFace,saveFaceInfo: ----------8,保存人脸取特征数据-----------") val faceDao = FaceDatabase.getInstance(this).faceDao() - val faceEntity = FaceEntity( - faceModel.userId, - null, - Base64.decode(faceModel.faceFeatureStr) - ).also { - //1-会员、2-临时用户 - it.userType = if (faceModel.member) "1" else "2" - } + val faceEntity = faceModel.toFaceEntity() val faceId = faceDao.insert(faceEntity) faceEntity.faceId = faceId loadLogInfo("collectFace,saveFaceInfo: ----------10,人脸数据保存完成-----------") diff --git a/app/src/main/java/com/sw/platecabinet/model/ErrorInfo.kt b/app/src/main/java/com/sw/platecabinet/model/ErrorInfo.kt index 47c4449..55d3edd 100644 --- a/app/src/main/java/com/sw/platecabinet/model/ErrorInfo.kt +++ b/app/src/main/java/com/sw/platecabinet/model/ErrorInfo.kt @@ -1,5 +1,7 @@ package com.sw.platecabinet.model +import com.google.gson.annotations.SerializedName + /** * 错误信息 code == 200 成功 */ @@ -19,6 +21,27 @@ data class DeviceConfig( var arcsoftActiveKey: String? = null ) +data class DeviceConfigV2( + /** 业务服务器 BASE URL */ + val appPackageUrl: String? = null, + /** 食堂/餐厅名称 */ + val canteenName: String? = null, + /** 食堂/餐厅 ID(后续所有业务 API 的 restId) */ + val canteenId: String? = null, + /** 虹软人脸 SDK App ID */ + val arcsoftAppId: String? = null, + /** 虹软人脸 SDK Key */ + val arcsoftSdkKey: String? = null, + /** 虹软人脸 SDK Active Key */ + val arcsoftActiveKey: String? = null, + /** MQTT 客户端服务器 IP */ + val clientServerIp: String? = null, + /** 智慧食堂服务器 IP(MQTT 端口) */ + val zhstServerIp: String? = null + +) + + data class CodeMsg( val code: String? = "", val msg: String? = "" diff --git a/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModel.kt b/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModel.kt index 34625c5..01021d1 100644 --- a/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModel.kt +++ b/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModel.kt @@ -9,19 +9,6 @@ import kotlinx.parcelize.Parcelize */ @Parcelize data class UserFaceModel( -// @SerializedName("faceFeature") -// val faceFeature: String? = "", -// @SerializedName("faceFeatureString") -// val faceFeatureString: String? = "", -// @SerializedName("faceType") -// val faceType: String? = "", -// @SerializedName("userFaceId") -// val userFaceId: String? = "", -// @SerializedName("userId") -// val userId: String? = "", -// @SerializedName("updateTimeStamp") -// val updateTimeStamp: Long = 0, - val userId: String? = "", val faceFeatureStr: String? = "", val faceUpdateTimestamp: Long? = null, @@ -32,10 +19,10 @@ data class UserFaceModel( /** * 会员编号 */ - val cardNo: String, + val cardNo: String? = null, /** * 是否会员 */ - val member: Boolean + val member: Boolean? = null ) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModelV2.kt b/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModelV2.kt new file mode 100644 index 0000000..1bf30a2 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/model/response/UserFaceModelV2.kt @@ -0,0 +1,44 @@ +package com.sw.platecabinet.model.response + + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import com.sw.plate.utils.arcface.facedb.entity.FaceEntity +import kotlinx.parcelize.Parcelize + +/** + * 用户人脸信息 + */ +@Parcelize +data class UserFaceModelV2( + val userFaceId: String? = null, + val userId: String? = null, + val faceFeature: String? = null, + val faceFeatureStr: String? = null, + val faceFeatureString: String? = null, + val faceUpdateTimestamp: Long? = null, + val cardNo: String? = null, + val member: Boolean? = false, + val faceDeleted: Boolean? = false, + val personType: String? = null +) : Parcelable { + fun resolveFeatureStr(): String? { + return faceFeature?.takeIf { it.isNotEmpty() } + ?: faceFeatureStr?.takeIf { it.isNotEmpty() } + ?: faceFeatureString?.takeIf { it.isNotEmpty() } + } + + fun toFaceEntity(): FaceEntity { + val featureBase64 = resolveFeatureStr() + return FaceEntity( + userId, + android.util.Base64.decode(featureBase64, android.util.Base64.DEFAULT), + personType, + cardNo, + userId, + userFaceId, + member ?: false, + faceUpdateTimestamp ?: 0L + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt index 02ee2c2..4d1beba 100644 --- a/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt +++ b/app/src/main/java/com/sw/platecabinet/network/ApiClient.kt @@ -3,6 +3,7 @@ package com.sw.platecabinet.network import com.sw.platecabinet.GlobalData import com.sw.platecabinet.MyApp import com.sw.platecabinet.network.api.ApiService +import com.sw.platecabinet.network.api.ApiServiceV2 import com.sw.platecabinet.network.interceptor.RequestInterceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -37,4 +38,8 @@ object ApiClient { val apiService: ApiService by lazy { retrofit.create(ApiService::class.java) } + + val apiServiceV2: ApiServiceV2 by lazy { + retrofit.create(ApiServiceV2::class.java) + } } diff --git a/app/src/main/java/com/sw/platecabinet/network/api/ApiServiceV2.kt b/app/src/main/java/com/sw/platecabinet/network/api/ApiServiceV2.kt new file mode 100644 index 0000000..a61a27b --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/network/api/ApiServiceV2.kt @@ -0,0 +1,66 @@ +package com.sw.platecabinet.network.api + +import com.sw.platecabinet.GlobalData +import com.sw.platecabinet.model.DeviceConfigV2 +import com.sw.platecabinet.model.response.ApiResponse +import com.sw.platecabinet.model.response.UserFaceModel +import com.sw.platecabinet.model.response.UserFaceModelV2 +import okhttp3.MultipartBody +import retrofit2.http.Body +import retrofit2.http.Field +import retrofit2.http.FormUrlEncoded +import retrofit2.http.GET +import retrofit2.http.Multipart +import retrofit2.http.POST +import retrofit2.http.Part +import retrofit2.http.Url + +interface ApiServiceV2 { + /** + * 获取人脸缓存数据 + */ + @POST + suspend fun getUserFaceCache( + @Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/common/face/page", + @Body param: Map + ): ApiResponse> + + /** + * 获取人脸增量数据 + */ + @POST + suspend fun getFaceIncrementList( + @Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/common/face/increment", + @Body param: Map + ): ApiResponse?> + + /** + * 获取设备配置数据 + */ + @GET + suspend fun getDeviceConfig( + @Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/pickup/device/config" + ): ApiResponse + + /** + * 添加人脸数据 + */ + @POST + @FormUrlEncoded + suspend fun addUserFace( + @Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/user/add-by-face", + @Field("featureChar") faceData: String, + @Field("url") imageUr: String + ): ApiResponse + + /** + * 上传图片 + */ + @Multipart + @POST + suspend fun uploadImage( + @Url url: String = "${GlobalData.appBaseUrl}/nutrition/neglect/upload", + @Part file: MultipartBody.Part, + ): ApiResponse + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/repository/RemoteRepositoryV2.kt b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepositoryV2.kt new file mode 100644 index 0000000..49f339e --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/repository/RemoteRepositoryV2.kt @@ -0,0 +1,70 @@ +package com.sw.platecabinet.repository + +import com.sw.platecabinet.model.DeviceConfigV2 +import com.sw.platecabinet.model.response.ApiResponse +import com.sw.platecabinet.model.response.UserFaceModel +import com.sw.platecabinet.model.response.UserFaceModelV2 +import com.sw.platecabinet.network.api.ApiServiceV2 +import com.sw.platecabinet.utils.FileUtils +import java.io.File + +/** + * 远程数据处理 + */ +class RemoteRepositoryV2 constructor( + private val apiService: ApiServiceV2 +) : BaseRepository() { + + /** + * 获取人脸数据 + */ + suspend fun getUserFaceCache( + pageNum: Int, + pageSize: Int = 100, + ): ApiResponse> { + return safeApiCall { + apiService.getUserFaceCache( + param = mapOf( + "pageNum" to pageNum, + "pageSize" to pageSize + ) + ) + } + } + + + suspend fun getFaceIncrementList( + pageNum: Long, + pageSize: Long = 100L, + timestamp: Long + ): ApiResponse?> { + return safeApiCall { + apiService.getFaceIncrementList( + param = mapOf( + "pageNum" to pageNum, + "pageSize" to pageSize, + "timestamp" to timestamp + ) + ) + } + } + + suspend fun getDeviceConfig(): ApiResponse { + return safeApiCall { apiService.getDeviceConfig() } + } + + suspend fun addUserFace(faceData: String, imageUr: String): ApiResponse { + return safeApiCall { apiService.addUserFace(faceData = faceData, imageUr = imageUr) } + } + + suspend fun uploadImage(file: File): ApiResponse { + return safeApiCall { + val part = FileUtils.genRequestPart(file) + if (part == null) { + ApiResponse(code = "-1", msg = "解析图片失败") + } else { + apiService.uploadImage(file = part) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt index bb8a817..38d5c10 100644 --- a/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/BaseViewModel.kt @@ -1,74 +1,74 @@ -package com.sw.platecabinet.viewmodel - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.sw.plate.utils.ToastUtils -import com.sw.platecabinet.model.response.ApiResponse -import com.sw.platecabinet.network.ApiClient -import com.sw.platecabinet.repository.RemoteRepository -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.launch -import timber.log.Timber - -abstract class BaseViewModel() : ViewModel() { - protected val repository = RemoteRepository(ApiClient.apiService) - - // 显示进度条 - private val _showLoading = MutableStateFlow(false) - val showLoading: StateFlow = _showLoading - - /** - * 带进度条的请求 - */ - protected fun launchWithLoading(block: suspend () -> Unit) { - viewModelScope.launch { - try { - _showLoading.value = true - block() - } catch (e: Exception) { - // 错误处理可被子类重写 - handleError(e) - } finally { - _showLoading.value = false - } - } - } - - /** - * 不带进度条的请求 - */ - protected fun launch(block: suspend () -> Unit) { - viewModelScope.launch() { - try { - block() - } catch (e: Exception) { - // 错误处理可被子类重写 - handleError(e) - } - } - } - - protected open fun parseResponse(response: ApiResponse<*>): Boolean { - if (response.isSuccess()) { - return true - } - Timber.d("msg = ${response.msg}, code = ${response.code}") - ToastUtils.showToast("${response.msg}(${response.code})") - return false - } - - - fun handleError(exception: Exception) { - Timber.d("handleError ${exception.message}") - } - -// fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) { -//// GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!! -//// GlobalData.appBaseUrl="https://vip.shuziweidao.com" -//// GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!! -//// GlobalData.appId = equipmentInfo.arcsoftAppId!! -//// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!! -//// GlobalData.restId = equipmentInfo.canteenId!! +//package com.sw.platecabinet.viewmodel +// +//import androidx.lifecycle.ViewModel +//import androidx.lifecycle.viewModelScope +//import com.sw.plate.utils.ToastUtils +//import com.sw.platecabinet.model.response.ApiResponse +//import com.sw.platecabinet.network.ApiClient +//import com.sw.platecabinet.repository.RemoteRepository +//import kotlinx.coroutines.flow.MutableStateFlow +//import kotlinx.coroutines.flow.StateFlow +//import kotlinx.coroutines.launch +//import timber.log.Timber +// +//abstract class BaseViewModel() : ViewModel() { +// protected val repository = RemoteRepository(ApiClient.apiService) +// +// // 显示进度条 +// private val _showLoading = MutableStateFlow(false) +// val showLoading: StateFlow = _showLoading +// +// /** +// * 带进度条的请求 +// */ +// protected fun launchWithLoading(block: suspend () -> Unit) { +// viewModelScope.launch { +// try { +// _showLoading.value = true +// block() +// } catch (e: Exception) { +// // 错误处理可被子类重写 +// handleError(e) +// } finally { +// _showLoading.value = false +// } +// } // } -} \ No newline at end of file +// +// /** +// * 不带进度条的请求 +// */ +// protected fun launch(block: suspend () -> Unit) { +// viewModelScope.launch() { +// try { +// block() +// } catch (e: Exception) { +// // 错误处理可被子类重写 +// handleError(e) +// } +// } +// } +// +// protected open fun parseResponse(response: ApiResponse<*>): Boolean { +// if (response.isSuccess()) { +// return true +// } +// Timber.d("msg = ${response.msg}, code = ${response.code}") +// ToastUtils.showToast("${response.msg}(${response.code})") +// return false +// } +// +// +// fun handleError(exception: Exception) { +// Timber.d("handleError ${exception.message}") +// } +// +//// fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) { +////// GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!! +////// GlobalData.appBaseUrl="https://vip.shuziweidao.com" +////// GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!! +////// GlobalData.appId = equipmentInfo.arcsoftAppId!! +////// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!! +////// GlobalData.restId = equipmentInfo.canteenId!! +//// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/NetViewModelV2.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/NetViewModelV2.kt new file mode 100644 index 0000000..0d6d4b8 --- /dev/null +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/NetViewModelV2.kt @@ -0,0 +1,249 @@ +package com.sw.platecabinet.viewmodel + +import androidx.lifecycle.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.FaceDatabase +import com.sw.plate.utils.arcface.facedb.entity.FaceEntity +import com.sw.platecabinet.GlobalData +import com.sw.platecabinet.GlobalKey +import com.sw.platecabinet.model.DeviceConfigV2 +import com.sw.platecabinet.model.response.UserFaceModel +import com.sw.platecabinet.model.response.UserFaceModelV2 +import com.sw.platecabinet.network.ApiClient +import com.sw.platecabinet.repository.RemoteRepositoryV2 +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 NetViewModelV2 : ViewModel() { + + companion object { + const val PAGE_SIZE = 100 + } + + private val faceApi: FaceApi = FaceApi() + private val repository = RemoteRepositoryV2(ApiClient.apiServiceV2) + + + //fun getUserFace( + // pageNo: Int, + // pageSize: Int, + // callback: (Boolean, List) -> Unit + //) { + // viewModelScope.launch { + // val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize) + // if (response.isSuccess()) callback(true, response.data ?: emptyList()) + // else callback(false, emptyList()) + // } + //} + + /** + * 获取人脸数据 + */ + fun getUserFaceCache( + pageNo: Int = 1, + pageSize: Int = PAGE_SIZE, + callback: (Boolean, String?) -> Unit = { _, _ -> } + ) { + var currentPageNo = pageNo + viewModelScope.launch { + val response = repository.getUserFaceCache(pageNo, pageSize) + if (response.isSuccess().not()) { + callback(false, response.msg) + return@launch + } + // 获取成功一次后缓存状态 + SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) + val list = response.data ?: emptyList() + if (pageNo == 1 && list.isEmpty()) { + callback(false, "暂无数据") + return@launch + } + val faceEntityList = list.mapNotNull { face -> + val featureBase64 = face.resolveFeatureStr() + if (featureBase64.isNullOrBlank()) null + else { + val featureData = base64ToByteArray(featureBase64) + if (featureData == null) null + else face.toFaceEntity() + } + } + 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(onSuccess: (DeviceConfigV2?) -> Unit, onFailure: (String?) -> Unit) { +// Timber.tag(TAG).d("getDeviceConfig") + viewModelScope.launch { + val response = repository.getDeviceConfig() + if (response.isSuccess()) { + onSuccess(response.data) + } else { + onFailure(response.msg) + } + } + } + + + /** + * 获取人脸数据 + */ + fun getFaceIncrementList( + pageNo: Int = 1, + pageSize: Int = PAGE_SIZE, + timestamp: Long, + refreshFaceList: () -> Unit + ) { + viewModelScope.launch { + val response = repository.getFaceIncrementList( + pageNum = pageNo.toLong(), + pageSize = pageSize.toLong(), + timestamp = timestamp + ) + if (response.isSuccess().not()) { + return@launch + } + withContext(Dispatchers.IO) { + val list = response.data ?: emptyList() + updateFaceData(list) + if (list.isNotEmpty()) { + faceTimestamp = list.last().faceUpdateTimestamp ?: 0 + } + SpTool.lastFaceTimestamp = faceTimestamp + try { + refreshFaceList() + } catch (e: Exception) { + e.printStackTrace() + } + } + } + } + + private fun updateFaceData(list: List) { + try { + list.forEach { model -> + if (model.faceDeleted == true) { + //删除数据 + faceApi.deleteByUserName(model.userId) + } else { + // 获取该用户所有已存特征,判断当前特征是否已存在 + val existList = faceApi.queryAllByUserName(model.userId) + val featureMatches = + existList.map { Base64.encode(it.featureData) == model.faceFeatureStr } + Timber.d("userId=${model.userId}, 已存记录数=${existList.size}, 各条特征是否与服务器一致=$featureMatches") + val alreadyExists = featureMatches.any { it } + if (!alreadyExists) { + faceApi.insert(model.toFaceEntity()) + } + } + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + /** + * 添加人脸数据 + */ + fun addUserFace(faceData: String, imageFile: File, block: (Boolean, UserFaceModelV2?) -> Unit) { + viewModelScope.launch { + val imageResp = repository.uploadImage(imageFile) + val imageUrl = imageResp.data ?: "" + if (imageUrl.isBlank()) { + block(false, null) + return@launch + } + val faceResp = repository.addUserFace(faceData, imageUrl) + if (faceResp.isSuccess().not()) { + block(false, null) + return@launch + } + block(true, faceResp.data) + } + } + + private fun base64ToByteArray(base64: String?): ByteArray? { + base64 ?: return null + return try { + Base64.decode(base64) + } catch (e: Exception) { + null + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt b/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt index 9616d9d..06cc5ce 100644 --- a/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt +++ b/app/src/main/java/com/sw/platecabinet/viewmodel/UserViewModel.kt @@ -1,201 +1,201 @@ -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) - } - } - -} \ No newline at end of file +//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 == true) "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) +// } +// } +// +//} \ No newline at end of file diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java index 17b2417..353cdc1 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/FaceApi.java @@ -32,7 +32,7 @@ public class FaceApi { */ public void updateFaceData(int index, List list) { Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size()); - FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); + FaceDao faceDao = getFaceDao(); //if (index == 1) { // faceDao.deleteAll(); // faceDao.resetId(); @@ -41,7 +41,7 @@ public class FaceApi { } public void clearFaceData() { - FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); + FaceDao faceDao = getFaceDao(); faceDao.deleteAll(); faceDao.resetId(); } @@ -88,29 +88,33 @@ public class FaceApi { } public void deleteByUserName(String userName) { - FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); - faceDao.deleteFaceById(userName); + getFaceDao().deleteFaceById(userName); } public Long insert(FaceEntity entity) { if (entity == null) { return 0L; } - FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); - return faceDao.insert(entity); + return getFaceDao().insert(entity); } public FaceEntity queryByUserName(String userName) { if (TextUtils.isEmpty(userName)) { return null; } - FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); - return faceDao.queryByUserName(userName); + return getFaceDao().queryByUserName(userName); } public int queryFaceCount() { - FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao(); - return faceDao.getFaceCount(); + return getFaceDao().getFaceCount(); + } + + public List queryAllByUserName(String userName) { + return getFaceDao().queryAllByUserName(userName); + } + + public FaceDao getFaceDao() { + return FaceDatabase.getInstance(App.getContext()).faceDao(); } } diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java index 34e2b2f..2926276 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/dao/FaceDao.java @@ -104,13 +104,13 @@ public interface FaceDao { /** * @return 删除临时用户人脸 */ - @Query("DELETE from face WHERE user_type = '2'") - int deleteTempUserFaceData(); + @Query("DELETE from face WHERE user_type = :userType") + int deleteUserFaceData(int userType); /** * 查询用户人脸数 * @param userType 1-会员,2-临时用户 */ @Query("SELECT COUNT(1) FROM face WHERE user_type = :userType") - int getFaceCount(String userType); + int getFaceCountByUserType(int userType); } diff --git a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java index e0e4387..36a4159 100644 --- a/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java +++ b/lib_face/src/main/java/com/sw/plate/utils/arcface/facedb/entity/FaceEntity.java @@ -52,12 +52,33 @@ public class FaceEntity implements Parcelable { /** * 会员编号 */ - @ColumnInfo(name = "cardNo") + @ColumnInfo(name = "card_no") private String cardNo; @Ignore private int trackId;//人脸追踪ID + @ColumnInfo(name = "user_idd") + private String userId; + @ColumnInfo(name = "user_face_id") + private String userFaceId; + @ColumnInfo(name = "member") + private boolean member; + @ColumnInfo(name = "face_update_timestamp") + private long faceUpdateTimestamp; + + public FaceEntity(String userName, byte[] featureData, String userType, String cardNo, String userId, String userFaceId, boolean member, long faceUpdateTimestamp) { + this.userName = userName; + this.featureData = featureData; + this.userType = userType; + this.cardNo = cardNo; + this.userId = userId; + this.userFaceId = userFaceId; + this.member = member; + this.faceUpdateTimestamp = faceUpdateTimestamp; + registerTime = System.currentTimeMillis(); + } + public FaceEntity(String userName, String imagePath, byte[] featureData) { this.userName = userName; this.imagePath = imagePath;