修「补录行被合并回来」的重复:对账时认它的派生 UUID
成因链:站点补录的到访没有留档行(entity_raw 里没有它),也就没有 UUID;导出时会被补上
一个确定性 UUID v5("ZVISIT/<src_pk>") 写进包里,手机于是把它当成一条真记录;这份包再
合并回站点时,站点这侧没有 UUID 可对齐,DiffVisits 直接判成「备份新增」又插一条 ——
时间线上出现两条一模一样的到访(实测数据集 9 有 43 对,生产时间线一屏就有 53 对)。
- rond:把派生 UUID 抽成 DerivedUUID / DerivedVisitUUID / VisitMatchUUID(导出侧 coreDataUUID
复用同一个函数),差异与合并都拿它当对账键(diff.go 的 byUUID、backup_merge 的 storedByUUID)。
- 「时间 + 地点」兜底配对补 used 检查:同一条站点行现在两个索引里都有,不查会被 classify 两次。
- 数据编辑页的「重复到访」卡片认得这类(成因标「你补录的那条被合并回来的一份」),
清理时把副本名下的位移 / 天气**改挂**到保留项——补录行自己名下没有位移,跟着删就白丢里程;
派生 UUID 判定排在「站点侧副本」之前(证据更强)。
用例:rond 两条(正例 + 派生 UUID 不相配的反例)、web 一条端到端(造补录行与副本 → 检出 →
清理 → 断言位移与天气改挂、留档被清)。变异验证:去掉改挂语义、关掉该判定,两条都立刻红。
This commit is contained in:
@@ -418,8 +418,9 @@ func (s *Server) mergeVisits(ctx context.Context, ex execer, dsID int64, b *rond
|
||||
visSrc := map[int]int{}
|
||||
storedByUUID := map[string]rond.StoredVisit{}
|
||||
for _, sv := range storedVisits {
|
||||
if sv.UUID != "" {
|
||||
storedByUUID[sv.UUID] = sv
|
||||
// 站点补录的行没有留档 UUID,用它的派生 UUID 当键(与差异页同一套对齐,见 rond.VisitMatchUUID)
|
||||
if u := rond.VisitMatchUUID(sv); u != "" {
|
||||
storedByUUID[u] = sv
|
||||
}
|
||||
}
|
||||
for _, v := range b.Visits {
|
||||
|
||||
Reference in New Issue
Block a user