feat(face): 新增人脸库展示与增量更新支持

- 在PLC设置界面新增人脸库统计模块,显示人脸总数并支持刷新
- 人脸总数数据从本地数据库异步查询并更新界面
- 修改API接口调用,采用POST请求体方式提交人脸数据(包含url和特征字符串)
- 在网络调用中实现人脸数据的增量分页获取,递归拉取所有数据页
- 维护人脸数据的最大时间戳,确保增量更新只处理最新数据
- 优化人脸数据缓存逻辑,第一页重置数据并同步时间戳
- 添加FeatureBody数据类封装人脸特征请求体参数
- 修正相关仓库层方法以适配新的API接口参数和返回结构
This commit is contained in:
mazengfei
2026-07-07 17:33:04 +08:00
parent cb107c2da2
commit 9a8ac83d33
6 changed files with 136 additions and 21 deletions
@@ -82,12 +82,17 @@ class NetViewModelV2 : ViewModel() {
}
withContext(Dispatchers.Default) {
if (currentPageNo == 1) {
//第一页数据删除本地数据库
//第一页数据删除本地数据库,同时重置时间戳
faceApi.clearFaceData()
faceTimestamp = 0L
}
faceApi.updateFaceData(pageNo, faceEntityList)
if (list.size >= pageSize) {
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
// 取当前页最大时间戳,与已累积的比较取最大值
val pageMaxTimestamp = maxFaceTimestamp(list)
if (pageMaxTimestamp > faceTimestamp) {
faceTimestamp = pageMaxTimestamp
}
currentPageNo++
getUserFaceCache(
pageNo = currentPageNo, callback = callback
@@ -95,7 +100,11 @@ class NetViewModelV2 : ViewModel() {
return@withContext
}
if (list.isNotEmpty()) {
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
// 最后一页:取当前页最大时间戳,与已累积的比较取最大值
val pageMaxTimestamp = maxFaceTimestamp(list)
if (pageMaxTimestamp > faceTimestamp) {
faceTimestamp = pageMaxTimestamp
}
}
SpTool.lastFaceTimestamp = faceTimestamp
callback(true, "查询完成")
@@ -161,7 +170,7 @@ class NetViewModelV2 : ViewModel() {
/**
* 获取人脸数据
* 增量获取人脸数据(支持分页递归,取所有页中的最大时间戳)
*/
fun getFaceIncrementList(
pageNo: Int = 1,
@@ -169,9 +178,10 @@ class NetViewModelV2 : ViewModel() {
timestamp: Long,
refreshFaceList: () -> Unit
) {
var currentPageNo = pageNo
viewModelScope.launch {
val response = repository.getFaceIncrementList(
pageNum = pageNo.toLong(),
pageNum = currentPageNo.toLong(),
pageSize = pageSize.toLong(),
timestamp = timestamp
)
@@ -181,10 +191,27 @@ class NetViewModelV2 : ViewModel() {
withContext(Dispatchers.IO) {
val list = response.data ?: emptyList()
updateFaceData(list)
if (list.isNotEmpty()) {
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
// 取当前页最大时间戳,与已累积的比较取最大值
val pageMaxTimestamp = maxFaceTimestamp(list)
if (pageMaxTimestamp > faceTimestamp) {
faceTimestamp = pageMaxTimestamp
}
if (list.size >= pageSize) {
// 还有下一页,继续递归拉取
currentPageNo++
getFaceIncrementList(
pageNo = currentPageNo,
pageSize = pageSize,
timestamp = timestamp,
refreshFaceList = refreshFaceList
)
return@withContext
}
// 所有页拉取完毕,保存最终时间戳(只升不降)
val storedTimestamp = SpTool.lastFaceTimestamp
if (faceTimestamp > storedTimestamp) {
SpTool.lastFaceTimestamp = faceTimestamp
}
SpTool.lastFaceTimestamp = faceTimestamp
try {
refreshFaceList()
} catch (e: Exception) {
@@ -246,4 +273,11 @@ class NetViewModelV2 : ViewModel() {
}
}
/**
* 从人脸数据列表中取出最大的 faceUpdateTimestamp(跳过 null 值)
*/
private fun maxFaceTimestamp(list: List<UserFaceModelV2>): Long {
return list.mapNotNull { it.faceUpdateTimestamp }.maxOrNull() ?: 0L
}
}