Appearance
第 31 章 · 目录的记忆术
背景:路径记忆与叶子目录展开逻辑分散
过程:统一路径记忆与叶子目录展开(ADR-097)
惊醒
那天早晨,图书馆的摆书人 library-core.ts 突然被一阵抱怨惊醒。
"你这摆书人怎么回事?"用户站在分类1的书架前,手里拿着一本《妮基塔·无垢契约》的模型书,"我昨天明明在这里看过书,今天一进门就被你扔回大门口了!"
摆书人揉了揉眼睛,看了看门口——确实,用户说的没错。分类1里的单模型目录明明被展开显示了,但记忆之书却固执地指向了更深的路径。
"可是……"摆书人挠了挠头,"记忆之书记录的就是那个位置啊。"
"那又怎样?"用户把书啪地放在桌上,"我在分类1就能看到这本书,你却非要让我钻进那个只有一本书的小房间!"
追查
摆书人开始翻找记忆之书的运作机制。
记忆之书由两部分组成:
- 模型记忆:记住用户上次看的书,自动翻到那一页
- 路径记忆:记住用户上次走到哪个房间
问题出在模型记忆上。当用户在分类1看到展开的模型时,模型的实际位置是 /分类1/妮基塔/妮基塔ALL.pmx,但摆书人的目录展开逻辑会把这个目录里的书直接搬到分类1来展示。
记忆之书不知道这个"搬家"操作,它只知道按照模型的实际位置去翻页,结果就翻到了那个只有一本书的小房间。
"这就像……"摆书人自言自语,"你把书架上的书抽出来放在桌面上展示,但记忆之书却非要让你回到书架的原始位置去找。"
真相
摆书人找到了问题的核心:目录展开逻辑和记忆逻辑是两套独立的系统。
目录展开逻辑(buildLevel)会判断:如果一个目录下只有一本书(无论是 pmx 还是 zip),就把这本书直接拿到父目录展示,避免用户多走一层。
但记忆逻辑(prepareModelRestore)却不知道这个规则,它只会机械地按照模型的实际路径去展开。
"解决方案很简单,"摆书人拿起笔,"让记忆逻辑也学会判断——如果目标目录是一个会被展开的叶子目录,那就停在父目录,不要钻进去。"
于是摆书人写下了三个公共函数:
isLeafFlattenDir — 判断一个目录是否应该被展开:
- 如果目录下有子目录 → 不展开(有分类意义)
- 如果目录下全是多模型 zip → 不展开(有分类意义)
- 其他情况 → 展开(无分类意义,直接展示模型)
computeRestoreSegments — 计算记忆应该展开到哪一级:
- 从根目录开始逐级检查
- 遇到会被展开的叶子目录就停下
- 返回需要展开的路径段
modelToResourceItem — 把模型转换成网格视图能用的卡片:
- 统一模型→卡片的转换逻辑
- 支持多语言显示策略
- 缓存元数据优先
教训
摆书人把这三个函数刻在图书馆的石柱上,让所有城邦都能看到。
"聚合者的记忆不能是机械的,"他在刻字时自言自语,"它必须理解联邦的运作规则。记住一个位置很容易,但记住为什么在这个位置才是真正的智慧。"
教训摘要:记忆要理解规则,而不是机械重复路径。