/// 人脸同步的业务范围,所有入口最终映射为部门快照或用户增量。 enum FaceSyncMode { /// 本部门及子部门的完整权威快照,用于每日对账和人工同步。 departmentSnapshot, /// 指定用户的最新状态回查,用于 MQ 低延迟增量同步。 userDelta, /// 非生产调试使用的全租户快照,生产界面不会暴露该模式。 debugAllSnapshot, } /// 一次人脸差异同步的结构化汇总,可直接映射到现有任务日志统计列。 class FaceSyncSummary { /// 创建同步汇总;失败样本只保存脱敏标识,不保存姓名、图片地址或特征。 const FaceSyncSummary({ required this.mode, required this.scanned, required this.added, required this.updated, required this.deleted, required this.skipped, required this.failed, required this.maskedFailedSampleIds, }); /// 本次同步模式。 final FaceSyncMode mode; /// 从服务端完整读取并校验的记录数。 final int scanned; /// 新增并成功写入本地数据库及虹软内存库的样本数。 final int added; /// 元数据或图片版本成功更新的样本数。 final int updated; /// 成功从虹软、本地数据库和正式文件范围移除的孤儿样本数。 final int deleted; /// 服务端与本地版本完全一致、未发生下载或虹软写入的样本数。 final int skipped; /// 本次处理失败且保留待下次重试的样本数。 final int failed; /// 失败样本的脱敏编号,最多由同步服务保留有限数量用于现场定位。 final List maskedFailedSampleIds; /// 本次成功新增、更新和删除的变更总数。 int get changed => added + updated + deleted; /// 是否存在需要下次重试的失败样本。 bool get hasFailures => failed > 0; /// 面向任务日志和设置页的简短结果描述。 String get message { if (!hasFailures) { return '扫描 $scanned,新增 $added,更新 $updated,删除 $deleted,跳过 $skipped'; } final failedSamples = maskedFailedSampleIds.isEmpty ? '' : ',失败样本 ${maskedFailedSampleIds.join(',')}'; return '扫描 $scanned,新增 $added,更新 $updated,删除 $deleted,失败 $failed$failedSamples'; } } /// V3 快照不完整、游标倒退或样本标识冲突时抛出的整次同步异常。 class FaceSyncSnapshotException implements Exception { /// 使用不包含图片地址和人员信息的安全摘要创建快照异常。 const FaceSyncSnapshotException(this.message); /// 可写入终端任务日志的安全错误摘要。 final String message; /// 返回安全错误摘要。 @override String toString() => message; } /// 部分样本失败时交给统一调度器记录统计的异常。 class FaceSyncPartialFailureException implements Exception { /// 创建包含脱敏失败样本和完整计数的部分失败异常。 const FaceSyncPartialFailureException(this.summary); /// 已完成的同步统计,失败项均保留旧数据等待下次重试。 final FaceSyncSummary summary; /// 返回面向设置页的汇总描述。 @override String toString() => summary.message; }