增量人脸数据查询优化

This commit is contained in:
2025-12-31 11:53:35 +08:00
parent b5daf0f5df
commit 2656e89244
12 changed files with 242 additions and 66 deletions
+10
View File
@@ -30,6 +30,16 @@
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:theme="@style/Theme.FaceCollect"> android:theme="@style/Theme.FaceCollect">
<!-- 注册BootReceiver,监听开机完成广播 -->
<receiver
android:name=".receiver.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@@ -88,6 +88,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
private val mainViewModel by viewModels<MainViewModel>() private val mainViewModel by viewModels<MainViewModel>()
private var currentUserId: String? = null private var currentUserId: String? = null
private var lastFaceTrackId = -1
override fun inflateViewBinding() = ActivityMainBinding.inflate(layoutInflater) override fun inflateViewBinding() = ActivityMainBinding.inflate(layoutInflater)
@@ -102,7 +103,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
super.initialize() super.initialize()
mainViewModel.getUserFaceCache(pageNo = pageNo) mainViewModel.getUserFaceCache(pageNo = pageNo)
FaceEngineUtils.activeEngine() FaceEngineUtils.activeEngine()
setupArcCamera()
binding.btnCollectFace.setOnClickListener { binding.btnCollectFace.setOnClickListener {
requestSinglePermissionResult(Manifest.permission.CAMERA) { granted -> requestSinglePermissionResult(Manifest.permission.CAMERA) { granted ->
if (granted.not()) { if (granted.not()) {
@@ -121,7 +122,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
binding.tvFaceTip.visible() binding.tvFaceTip.visible()
binding.layoutState.gone() binding.layoutState.gone()
resumeCamera() // resumeCamera()
startFaceTask() startFaceTask()
} }
@@ -173,6 +174,31 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
it.put("content", faceData) it.put("content", faceData)
} }
tcpClient?.send(jsonObject) tcpClient?.send(jsonObject)
// TODO: 保存采集的人脸数据,暂时生成id,实际id在结算终端生成并发送到各台设备
saveFaceInfo(faceData)
}
private fun saveFaceInfo(faceData: String) {
Thread {
try {
val tempId = "${System.currentTimeMillis()}-123456789"
val faceEntity = FaceEntity(
tempId,
null,
Base64.decode(faceData)
).also {
it.userType = "2"
}
FaceDatabase.getInstance(this).faceDao().insert(faceEntity)
recognizeViewModel.refreshFaceList();
runOnUiThread {
toast("你的人脸信息已采集")
}
} catch (e: Exception) {
e.printStackTrace()
}
}.start()
} }
private var tcpClient: TcpClient? = null private var tcpClient: TcpClient? = null
@@ -199,6 +225,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
super.onSendFailed(json, e) super.onSendFailed(json, e)
toast("发送失败${e?.message}") toast("发送失败${e?.message}")
} }
override fun onMessage(json: JSONObject?) {
super.onMessage(json)
val type = json?.getInt("type")
// 根据服务端消息类型处理删除新增临时用户人脸数据---------------------
when (type) {
LanServer.TYPE_ADD_FACE_DATA -> {
//采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据
}
LanServer.TYPE_CLEAR_FACE_DATA -> {
clearFaceData()
}
else-> {}
}
}
}) })
tcpClient?.start(); tcpClient?.start();
@@ -219,6 +261,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
// private var imageBitmap: Bitmap? = null // private var imageBitmap: Bitmap? = null
private fun collectFace() { private fun collectFace() {
//toast("currentUserId=$currentUserId")
if (currentUserId != null) {
toast("您已采集过人脸信息")
return
}
currentUserId = null currentUserId = null
userFaceInfo = null userFaceInfo = null
recognizeViewModel.updateRegisterStatus(REGISTER_STATUS_READY) recognizeViewModel.updateRegisterStatus(REGISTER_STATUS_READY)
@@ -248,10 +295,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
private fun getFaceData(block: (String) -> Unit) { private fun getFaceData(block: (String) -> Unit) {
runBlocking { runBlocking {
job = executor.startIntervalTask(5) { job = executor.startIntervalTask(5) {
if (currentUserId != null && currentUserId!!.isNotBlank()) { // if (currentUserId != null && currentUserId!!.isNotBlank()) {
toast("您已采集过人脸信息") // toast("您已采集过人脸信息")
return@startIntervalTask // return@startIntervalTask
} // }
if (userFaceInfo == null) { if (userFaceInfo == null) {
return@startIntervalTask return@startIntervalTask
} }
@@ -353,13 +400,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
TAG, TAG,
"recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}" "recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}"
) )
val lastFaceTrackId = compareResult.trackId lastFaceTrackId = compareResult.trackId
val faceEntity = compareResult.faceEntity val faceEntity = compareResult.faceEntity
currentUserId = faceEntity.userName currentUserId = faceEntity.userName
// if (!currentUserId.isNullOrBlank()) { if (!currentUserId.isNullOrBlank()) {
//// toast("您已采集过人脸信息") toast("您已采集过人脸信息")
// return@Observer return@Observer
// } }
// //未识别到,拍摄照片 // //未识别到,拍摄照片
}) })
@@ -663,29 +710,19 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList) binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList)
} }
// val listIsEmpty = facePreviewInfoList.isEmpty() val listIsEmpty = facePreviewInfoList.isEmpty()
// val listFirstTrackId = if (listIsEmpty.not()) facePreviewInfoList[0].trackId else null val listFirstTrackId = if (listIsEmpty.not()) facePreviewInfoList[0].trackId else null
// Log.d(TAG,"listIsEmpty=$listIsEmpty,lastFaceTrackId=$lastFaceTrackId,listFirstTrackId=$listFirstTrackId") Log.d(
// if (listIsEmpty || (lastFaceTrackId != listFirstTrackId)) { TAG,
// if (lastFaceTrackId != -1 && currentUserId != null) { "listIsEmpty=$listIsEmpty,lastFaceTrackId=$lastFaceTrackId,listFirstTrackId=$listFirstTrackId"
// mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0 )
// Timber.tag(com.sw.dualscreen.presentation.MainScreenPresentation.Companion.TAG).i("$lastFaceTrackId 用户离开") if (listIsEmpty || (lastFaceTrackId != listFirstTrackId)) {
// lastFaceTrackId = -1 if (lastFaceTrackId != -1 && currentUserId != null) {
// Timber.tag(com.sw.dualscreen.presentation.MainScreenPresentation.Companion.TAG) Log.d(TAG, "$lastFaceTrackId 用户离开")
// .d("postUserData userNutritionData是否null ${userNutrition == null}, currentFood是否null: ${currentFood == null}currentUserId是否null${currentUserId == null}") lastFaceTrackId = -1
// if (userNutrition == null || currentFood == null || currentUserId == null) { currentUserId = null
// return }
// } }
// postUserData()
// if (mealPickupMode == 1 || isKeepFaceState) {
// step2FaceRecognizing(currentFood!!)
// isKeepFaceState = false
// } else {
// activity.isAnalyzing = false
// step1FoodRecognizing()
// }
// }
// }
} }
fun switchCamera() { fun switchCamera() {
@@ -757,14 +794,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
private val intervalExecutor by lazy { IntervalExecutor() } private val intervalExecutor by lazy { IntervalExecutor() }
private var faceTaskJob: Job? = null private var faceTaskJob: Job? = null
// private val initialDelay = 5 * 60 * 1000L
// private val dealyMillis = 10 * 60 * 1000L
private val initialDelay = 60 * 1000L
private val dealyMillis = 30 * 1000L
private var taskPageNo = 1 private var taskPageNo = 1
fun startFaceTask() { fun startFaceTask() {
faceTaskJob = faceTaskJob =
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) { intervalExecutor.startIntervalTaskWithInitialDelay(60 * 1000L, 30 * 1000L) {
val timestamp = SpTool.getLastFaceTimestamp() val timestamp = SpTool.getLastFaceTimestamp()
if (timestamp == 0L) { if (timestamp == 0L) {
return@startIntervalTaskWithInitialDelay return@startIntervalTaskWithInitialDelay
@@ -774,7 +807,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
timestamp = timestamp, timestamp = timestamp,
onAllQueryFinished = { onAllQueryFinished = {
taskPageNo = 1 taskPageNo = 1
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
}, },
onPageQueryFinished = { list -> onPageQueryFinished = { list ->
runOnUiThread { runOnUiThread {
@@ -822,4 +854,34 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), ViewTreeObserver.OnGlo
}.start() }.start()
} }
// private var dinnerTypeJob: Job? = null
// fun startDinnerTypeTask() {
// dinnerTypeJob =
// intervalExecutor.startIntervalTaskWithInitialDelay(10 * 60 * 1000L, 15 * 60 * 1000L) {
// mainViewModel.getDinnerType {
//
// }
// }
// }
private fun clearFaceData() {
Thread {
val faceDao = FaceDatabase.getInstance(this).faceDao()
faceDao.deleteTempUserFaceData()
recognizeViewModel.refreshFaceList();
}.start()
}
override fun onResume() {
super.onResume()
setupArcCamera()
resumeCamera()
}
override fun onPause() {
super.onPause()
pauseCamera()
}
} }
@@ -15,7 +15,7 @@ object GlobalData {
/** /**
* 具体业务baseurl * 具体业务baseurl
*/ */
var appBaseUrl: String = "" var appBaseUrl: String = "https://dev.yixiong-tech.com:8081"
/** /**
* 横排数量 * 横排数量
@@ -20,7 +20,7 @@ data class UserFaceModel(
// @SerializedName("userId") // @SerializedName("userId")
val userId: String? = "", val userId: String? = "",
val faceFeatureStr: String? = "", val faceFeatureStr: String? = "",
val faceUpdateTimestamp: Long?=null,
val faceDeleted: Boolean? = false val faceDeleted: Boolean? = false
) )
// : Parcelable // : Parcelable
@@ -41,3 +41,13 @@ data class FaceData(
val pages: Int, val pages: Int,
val records: List<UserFaceModel2>? = null val records: List<UserFaceModel2>? = null
) )
data class DinnerType(
val id: String? = "",
//餐次
val dinnerType: String? = "",
//餐次收费模式(0称重,1固定,2不收费)
val chargeType: Int = 0,
//固定收费(元) 仅charge_type = 1 时
val fixedAmount: Double?=null
)
@@ -1,8 +1,8 @@
package com.sw.dualscreen.network package com.sw.face.collect.network
import android.util.Log import android.util.Log
import com.sw.face.collect.network.api.ApiService import com.sw.face.collect.network.api.ApiService
import com.sw.dualscreen.network.interceptor.RequestInterceptor import com.sw.face.collect.network.interceptor.RequestInterceptor
import com.sw.face.collect.MyApp import com.sw.face.collect.MyApp
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
@@ -11,7 +11,8 @@ import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object ApiClient { object ApiClient {
private const val BASE_URL = "http://device.shuziweidao.com:8889/" // private const val BASE_URL = "http://device.shuziweidao.com:8889/"
private const val BASE_URL = "https://dev.yixiong-tech.com:8081"
//private const val TIME_OUT = 30L // 超时时间(秒) //private const val TIME_OUT = 30L // 超时时间(秒)
//todo 临时测试改为5秒 //todo 临时测试改为5秒
@@ -2,6 +2,7 @@ package com.sw.face.collect.network.api
import com.sw.face.collect.base.GlobalData import com.sw.face.collect.base.GlobalData
import com.sw.face.collect.model.ApiResponse import com.sw.face.collect.model.ApiResponse
import com.sw.face.collect.model.DinnerType
import com.sw.face.collect.model.UserFaceModel import com.sw.face.collect.model.UserFaceModel
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.RequestBody import okhttp3.RequestBody
@@ -33,4 +34,12 @@ interface ApiService {
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/faceFeature/increment/list", @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/faceFeature/increment/list",
@Body param: Map<String, Long> @Body param: Map<String, Long>
): ApiResponse<List<UserFaceModel>?> ): ApiResponse<List<UserFaceModel>?>
/**
* 获取当前餐点类型
*/
@GET
suspend fun getDinnerType(
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/getRegionRule",
): ApiResponse<DinnerType?>
} }
@@ -1,9 +1,8 @@
package com.sw.dualscreen.network.interceptor package com.sw.face.collect.network.interceptor
import android.text.TextUtils import android.text.TextUtils
import com.sw.dualscreen.GlobalData
import com.sw.dualscreen.GlobalKey
import com.sw.dualscreen.utils.SPUtil import com.sw.dualscreen.utils.SPUtil
import com.sw.face.collect.base.GlobalData
import com.sw.plate.App import com.sw.plate.App
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Request import okhttp3.Request
@@ -30,12 +29,12 @@ class RequestInterceptor : Interceptor {
return chain.proceed(newRequest) return chain.proceed(newRequest)
} }
private fun getToken(originRequest: Request): String { // private fun getToken(originRequest: Request): String {
val tokenParam = originRequest.header("X-Access-Token") // val tokenParam = originRequest.header("X-Access-Token")
if (!TextUtils.isEmpty(tokenParam)) return tokenParam!! // if (!TextUtils.isEmpty(tokenParam)) return tokenParam!!
// 从本地获取token的逻辑 // // 从本地获取token的逻辑
val spUtil = SPUtil.getInstance(context = App.getContext()) // val spUtil = SPUtil.getInstance(context = App.getContext())
return spUtil.get(GlobalKey.KEY_TOKEN, "") as String // return spUtil.get(GlobalKey.KEY_TOKEN, "") as String
// return "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6MTQ2LCJ1c2VyTmFtZSI6IjEzNjgxNDQ4ODU2IiwibmFtZSI6IuW-kOejiiIsInBhc3N3b3JkIjoiOTllOTQ1ZmVjZmZjNWIzNDI4MmUwNDRlODYyMzdjM2UxZjU5OWY5OCIsInNhbHQiOiI0NmEzMzUzYWU4OTA0MDYxYjMzODU5ZWNlYTBlMGE2NyIsInBob25lIjoiMTM2ODE0NDg4NTYiLCJzdGF0dXMiOjEsInVzZXJUeXBlIjoyLCJjcmVhdGVVc2VyTm8iOiIxNDEiLCJjcmVhdGVUaW1lIjoxNjI2OTQzNDE2MDAwLCJ1cGRhdGVVc2VyTm8iOiIxNDEiLCJ1cGRhdGVUaW1lIjoxNjI2OTQzNDE2MDAwLCJpc0RlbCI6ZmFsc2UsImVhSWQiOjk5LCJlYUlkTGlzdCI6Ijk5IiwiaXNTaG9wTWFuYWdlciI6dHJ1ZSwidXNlck5vIjoiMWY5Nzk5ZWMtODlkYi00MWYyLTk1YTEtY2UzNTA3Y2QyMTU2In0.f7wImPgBOYMV0AqRchnXGPkUWZN9dFJ9gLPsaB8uNldd21IfXLjJl8y-FiWVuVUvlwUvGpgqGDFR1JKj5H7amw" //// return "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6MTQ2LCJ1c2VyTmFtZSI6IjEzNjgxNDQ4ODU2IiwibmFtZSI6IuW-kOejiiIsInBhc3N3b3JkIjoiOTllOTQ1ZmVjZmZjNWIzNDI4MmUwNDRlODYyMzdjM2UxZjU5OWY5OCIsInNhbHQiOiI0NmEzMzUzYWU4OTA0MDYxYjMzODU5ZWNlYTBlMGE2NyIsInBob25lIjoiMTM2ODE0NDg4NTYiLCJzdGF0dXMiOjEsInVzZXJUeXBlIjoyLCJjcmVhdGVVc2VyTm8iOiIxNDEiLCJjcmVhdGVUaW1lIjoxNjI2OTQzNDE2MDAwLCJ1cGRhdGVVc2VyTm8iOiIxNDEiLCJ1cGRhdGVUaW1lIjoxNjI2OTQzNDE2MDAwLCJpc0RlbCI6ZmFsc2UsImVhSWQiOjk5LCJlYUlkTGlzdCI6Ijk5IiwiaXNTaG9wTWFuYWdlciI6dHJ1ZSwidXNlck5vIjoiMWY5Nzk5ZWMtODlkYi00MWYyLTk1YTEtY2UzNTA3Y2QyMTU2In0.f7wImPgBOYMV0AqRchnXGPkUWZN9dFJ9gLPsaB8uNldd21IfXLjJl8y-FiWVuVUvlwUvGpgqGDFR1JKj5H7amw"
} // }
} }
@@ -0,0 +1,19 @@
package com.sw.face.collect.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import com.sw.face.collect.MainActivity
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
Log.d("BootReceiver","设备启动完成,开始执行自启动逻辑")
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
}
@@ -2,6 +2,7 @@ package com.sw.face.collect.repository
import com.sw.dualscreen.repository.BaseRepository import com.sw.dualscreen.repository.BaseRepository
import com.sw.face.collect.model.ApiResponse import com.sw.face.collect.model.ApiResponse
import com.sw.face.collect.model.DinnerType
import com.sw.face.collect.model.UserFaceModel import com.sw.face.collect.model.UserFaceModel
import com.sw.face.collect.network.api.ApiService import com.sw.face.collect.network.api.ApiService
@@ -28,7 +29,7 @@ class RemoteRepository constructor(
) )
} }
} }
/** /**
* 获取人脸数据 * 获取人脸数据
*/ */
suspend fun getFaceIncrementList( suspend fun getFaceIncrementList(
@@ -47,4 +48,13 @@ class RemoteRepository constructor(
} }
} }
/**
* 获取当前餐点类型
*/
suspend fun getDinnerType(): ApiResponse<DinnerType?> {
return safeApiCall {
apiService.getDinnerType()
}
}
} }
@@ -1,7 +1,8 @@
package com.sw.face.collect.socket; package com.sw.face.collect.socket;
public class LanServer { public class LanServer {
public static final int TYPE_ADD_FACE_DATA = 1;
public static final int TYPE_CLEAR_FACE_DATA = 2;
private static volatile LanCommunicationManager instance; private static volatile LanCommunicationManager instance;
public static LanCommunicationManager getInstance() { public static LanCommunicationManager getInstance() {
@@ -18,4 +19,17 @@ public class LanServer {
} }
return instance; return instance;
} }
void a() {
//HashMap<String, Object> data = new HashMap<>();
//data.put("type", LanServer.TYPE_ADD_FACE_DATA);
//data.put("faceId", tempUserId);//收到采集信息,每次生成新的ID
//data.put("faceFeature", faceFeatureString);
//lanServer.broadcast(new JSONObject(data));
//
//HashMap<String, Object> data = new HashMap<>();
//data.put("type", LanServer.TYPE_CLEAR_FACE_DATA);
//lanServer.broadcast(new JSONObject(data));
}
} }
@@ -2,10 +2,11 @@ package com.sw.face.collect.viewmodel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.sw.dualscreen.network.ApiClient import com.sw.face.collect.network.ApiClient
import com.sw.dualscreen.utils.SPUtil import com.sw.dualscreen.utils.SPUtil
import com.sw.face.collect.base.GlobalKey import com.sw.face.collect.base.GlobalKey
import com.sw.face.collect.model.ApiResponse import com.sw.face.collect.model.ApiResponse
import com.sw.face.collect.model.DinnerType
import com.sw.face.collect.model.UserFaceModel import com.sw.face.collect.model.UserFaceModel
import com.sw.face.collect.repository.RemoteRepository import com.sw.face.collect.repository.RemoteRepository
import com.sw.face.collect.utils.SpTool import com.sw.face.collect.utils.SpTool
@@ -25,6 +26,8 @@ class MainViewModel() : ViewModel() {
private val faceApi: FaceApi = FaceApi() private val faceApi: FaceApi = FaceApi()
protected val repository = RemoteRepository(ApiClient.apiService) protected val repository = RemoteRepository(ApiClient.apiService)
private var lastFaceTimestamp = 0L
protected open fun parseResponse(response: ApiResponse<*>): Boolean { protected open fun parseResponse(response: ApiResponse<*>): Boolean {
val code = response.code val code = response.code
if (code == "00000" || code == "200" || code == "0") { if (code == "00000" || code == "200" || code == "0") {
@@ -43,14 +46,15 @@ class MainViewModel() : ViewModel() {
var currentPageNo = pageNo var currentPageNo = pageNo
// Timber.tag(TAG).d("getUserFaceCache index = $currentPageNo") // Timber.tag(TAG).d("getUserFaceCache index = $currentPageNo")
viewModelScope.launch { viewModelScope.launch {
//获取全量数据时,时间戳改为0
SpTool.setLastFaceTimestamp(0)
val response = repository.getUserFaceCache(currentPageNo) val response = repository.getUserFaceCache(currentPageNo)
if (parseResponse(response)) { if (parseResponse(response)) {
// 获取成功一次后缓存状态 // 获取成功一次后缓存状态
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
val list: List<UserFaceModel> = response.data ?: emptyList() val list: List<UserFaceModel> = response.data ?: emptyList()
if (list.isEmpty()) { if (pageNo == 1 && list.isEmpty()) {
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
ToastUtils.showToast("查询人脸数据为空") ToastUtils.showToast("查询人脸数据为空")
return@withContext return@withContext
} }
@@ -59,11 +63,17 @@ class MainViewModel() : ViewModel() {
} }
faceApi.updateFaceData(currentPageNo, faceEntity) faceApi.updateFaceData(currentPageNo, faceEntity)
if (list.size >= pageSize) { if (list.size >= pageSize) {
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
currentPageNo++ currentPageNo++
getUserFaceCache(currentPageNo) getUserFaceCache(currentPageNo)
} else { return@withContext
SpTool.setLastFaceTimestamp(System.currentTimeMillis())
} }
//查询完成所有数据,保存时间戳
if (list.isNotEmpty()) {
//非空最后一条数据的是时间戳,空使用上次list最后一条时间戳
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
}
SpTool.setLastFaceTimestamp(lastFaceTimestamp)
} }
} }
} }
@@ -76,7 +86,7 @@ class MainViewModel() : ViewModel() {
pageNo: Int = 1, pageNo: Int = 1,
pageSize: Int = PAGE_SIZE, pageSize: Int = PAGE_SIZE,
timestamp: Long, timestamp: Long,
onAllQueryFinished:()->Unit, onAllQueryFinished: () -> Unit,
onPageQueryFinished: (List<UserFaceModel>) -> Unit onPageQueryFinished: (List<UserFaceModel>) -> Unit
) { ) {
viewModelScope.launch { viewModelScope.launch {
@@ -89,7 +99,11 @@ class MainViewModel() : ViewModel() {
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
val list: List<UserFaceModel> = response.data ?: emptyList() val list: List<UserFaceModel> = response.data ?: emptyList()
onPageQueryFinished(list) onPageQueryFinished(list)
if (pageNo == 1 && list.isEmpty()) {
return@withContext
}
if (list.size >= pageSize) { if (list.size >= pageSize) {
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
getFaceIncrementList( getFaceIncrementList(
pageNo = pageNo + 1, pageNo = pageNo + 1,
pageSize = pageSize, pageSize = pageSize,
@@ -97,8 +111,30 @@ class MainViewModel() : ViewModel() {
onAllQueryFinished = onAllQueryFinished, onAllQueryFinished = onAllQueryFinished,
onPageQueryFinished = onPageQueryFinished onPageQueryFinished = onPageQueryFinished
) )
} else { return@withContext
onAllQueryFinished() }
//查询完成所有数据,保存时间戳
if (list.isNotEmpty()) {
//非空最后一条数据的是时间戳,空使用上次list最后一条时间戳
lastFaceTimestamp = list.last().faceUpdateTimestamp ?: 0L
}
SpTool.setLastFaceTimestamp(lastFaceTimestamp)
onAllQueryFinished()
}
}
}
}
/**
* 获取当前餐点类型
*/
fun getDinnerType(block: (DinnerType) -> Unit) {
viewModelScope.launch {
val response = repository.getDinnerType()
if (parseResponse(response)) {
withContext(Dispatchers.Default) {
response.data?.let {
block(it)
} }
} }
} }
@@ -88,4 +88,10 @@ public interface FaceDao {
@Query("UPDATE sqlite_sequence SET seq = 0 WHERE name ='face'") @Query("UPDATE sqlite_sequence SET seq = 0 WHERE name ='face'")
void resetId(); void resetId();
/**
* @return 删除临时用户人脸
*/
@Query("DELETE from face WHERE user_type = '2'")
int deleteTempUserFaceData();
} }