feat(face): 支持按userFaceId查询单条人脸记录

- FaceDao新增queryByUserFaceId接口,实现按userFaceId精确查询
- FaceApi新增queryByUserFaceId方法,封装Dao查询逻辑
- LoginByFaceActivity插入人脸时,先按userFaceId查询,存在则更新避免重复
- NetViewModelV2同步人脸数据时,优先用userFaceId判重,减少重复入库
- 修正FaceEntity中userId字段数据库列名错误(user_id替代user_idd)
- 增加注释说明及代码格式优化,提升代码可读性和健壮性
This commit is contained in:
mazengfei
2026-08-18 09:12:40 +08:00
parent 747e243122
commit 524837ec20
6 changed files with 1312 additions and 7 deletions
@@ -1018,7 +1018,17 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
loadLogInfo("collectFace,saveFaceInfo: ----------8,保存人脸取特征数据-----------")
val faceDao = FaceDatabase.getInstance(this).faceDao()
val faceEntity = faceModel.toFaceEntity()
val faceId = faceDao.insert(faceEntity)
// 先查后插:按 userFaceId 判重,避免采集入库与增量同步各插一条
val userFaceId = faceModel.userFaceId
val existing = if (!userFaceId.isNullOrEmpty()) faceDao.queryByUserFaceId(userFaceId) else null
val faceId = if (existing != null) {
// 已存在记录,更新特征等字段并复用主键,避免重复
faceEntity.faceId = existing.faceId
faceDao.updateFaceEntity(faceEntity)
existing.faceId
} else {
faceDao.insert(faceEntity)
}
faceEntity.faceId = faceId
loadLogInfo("collectFace,saveFaceInfo: ----------10,人脸数据保存完成-----------")
recognizeViewModel.refreshFaceList()
@@ -232,12 +232,18 @@ class NetViewModelV2 : ViewModel() {
faceApi.deleteByUserFaceId(userFaceId)
}
} else {
// 获取该用户所有已存特征,判断当前特征是否已存在
// 优先按 userFaceId 精确判重,避免特征字段不一致导致重复入库
val userFaceId = model.userFaceId
if (!userFaceId.isNullOrEmpty() && faceApi.queryByUserFaceId(userFaceId) != null) {
// 本地已存在该 userFaceId,跳过插入
return@forEach
}
// userFaceId 为空时,回退到特征比较去重(修正字段来源,保证与入库一致)
val featureStr = model.resolveFeatureStr()
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 }
val alreadyExists = existList.any { entity ->
featureStr != null && Base64.encode(entity.featureData) == featureStr
}
if (!alreadyExists) {
faceApi.insert(model.toFaceEntity())
}
File diff suppressed because it is too large Load Diff
@@ -98,6 +98,17 @@ public class FaceApi {
getFaceDao().deleteFaceByUserFaceId(userFaceId);
}
/**
* 按 userFaceId 查询单条人脸记录
*/
public FaceEntity queryByUserFaceId(String userFaceId) {
if (userFaceId == null || userFaceId.isEmpty()) {
return null;
}
return getFaceDao().queryByUserFaceId(userFaceId);
}
public Long insert(FaceEntity entity) {
if (entity == null) {
return 0L;
@@ -61,6 +61,12 @@ public interface FaceDao {
@Query("DELETE from face WHERE user_face_id = :userFaceId")
int deleteFaceByUserFaceId(String userFaceId);
/**
* 按 userFaceId 查询单条人脸记录
*/
@Query("SELECT * FROM face WHERE user_face_id = :userFaceId LIMIT 1")
FaceEntity queryByUserFaceId(String userFaceId);
/**
* 删除所有已注册的人脸
*
@@ -58,7 +58,7 @@ public class FaceEntity implements Parcelable {
@Ignore
private int trackId;//人脸追踪ID
@ColumnInfo(name = "user_idd")
@ColumnInfo(name = "user_id")
private String userId;
@ColumnInfo(name = "user_face_id")
private String userFaceId;