ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

PureLive 分类收藏身份契约:跨平台 ID 碰撞修复与领域身份审计实战指南

PureLive 分类收藏身份契约:跨平台 ID 碰撞修复与领域身份审计实战指南 音视频直播移动开发【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载导读多直播平台聚合客户端在收藏分类分类页关注这一看似简单的功能上藏着一个极易被忽视的领域陷阱不同平台的分类 ID 完全可能相同例如虎牙与斗鱼都存在areaId1而旧实现只比较 ID导致收藏判断、取消收藏与数据迁移时跨平台误伤。本文以 PureLive 仓库的docs/FAVORITE_AREA_IDENTITY_AUDIT_2026_09_08.md审计记录为核心结合源码讲解分类收藏领域身份identity契约的设计动机、身份生成规则、持久化兼容策略与完整验证流程读者可据此理解聚合类应用中平台 分类复合主键的落地方法并掌握一套可复现的回归验证与收尾方法。一、审计背景为什么收藏虎牙 areaId1会误删斗鱼记录PureLive 在 3.1.84121 版本上对分类收藏功能做了一次专项审计基线与结论均限定在冻结的本地上游引用c6c9bd70...与 merge base527fea1b...范围内判为upstream-existing不是对当前联网最新版的结论。审计发现四个真实缺陷跨平台 ID 碰撞误判收藏虎牙areaId1后打开斗鱼areaId1设置层isFavoriteArea与分类页关注按钮只比较 ID会提前将该分类认作已收藏走确认取消UI 路径时按 ID 删除会把其他平台的同 ID 记录一并删掉。对象引用删除失效设置层removeArea使用对象引用删除从 JSON 备份重建同一分类后引用不同删除静默失败。这与 UI 按 ID 批量删除是两条独立调用路径共同缺少统一的领域身份合同。主键字段过宽旧平台把areaType父分类元数据一律纳入主键但旧备份可能省略父分类字段导致合并后身份漂移而 IPTV 使用全局唯一频道 IDgetCategoryRooms仅按频道 ID 查找provider 不参与频道身份不应强行加上命名空间。猫耳命名空间缺失猫耳Missevan目录请求明确区分catalog_id/tag_id两套 API 命名空间未知/缺失type不应被当作通配符匹配二者否则目录与标签收藏会互相污染。二、领域身份契约身份生成规则的源码落地审计的设计结论是收藏判断、添加、删除与旧 Hive 备份合并共用同一套身份生成规则其实现位于 lib/core/models/live_area.dartstatic String? identityKeyFor({String? platform, String? areaId, String? areaType}) { final site platform?.trim().toLowerCase() ?? ; final id areaId?.trim() ?? ; if (site.isEmpty || id.isEmpty) return null; final namespace site missevan ? areaType?.trim().toLowerCase() ?? : ; return jsonEncode([site, namespace, id]); }规则要点platform去首尾空白并转小写消除HUYA/huya这类大小写与空格差异areaId去首尾空白但保留大小写——部分平台频道 ID 大小写敏感不做小写折叠namespace仅猫耳missevan的areaType参与命名空间区分catalog与tag两套 API其余平台一律不引入父分类元数据保证旧备份省略父分类时身份稳定结构化编码使用jsonEncode([site, namespace, id])而非字符串拼接避免platform|areaId这类分隔符碰撞例如平台名自身含分隔符的情形。LiveArea保持可变对象、不重载/hashCode、不改变既有序列化字段身份判断通过显式方法完成String? get identityKey identityKeyFor(platform: platform, areaId: areaId, areaType: areaType); bool hasSameIdentity(LiveArea other) { final key identityKey; return key ! null key other.identityKey; }hasSameIdentity是identityKey的语义比较既不依赖对象引用也不依赖重载。三、控制器三层操作判断、添加、删除全部基于身份设置层核心控制器 lib/domains/live/data/favorite_room_controller.dart 中分类收藏的三类操作全部收敛到身份契约上判断isFavoriteArea第 264-266 行遍历favoriteAreas用candidate.hasSameIdentity(area)判定天然避免跨平台同 ID 误判添加addArea第 366-374 行identityKey null平台或 ID 缺失或已存在同身份记录时拒绝添加删除removeArea第 385-394 行removeWhere((candidate) candidate.hasSameIdentity(area))只移除同一身份保留其他平台、其他命名空间以及确认对话框期间新增的记录。数据保留策略与审计要求一致没有平台或 ID 的旧记录原样保留不自动清理用户数据也不作为可添加/匹配的正常收藏取消收藏只删同身份记录不触碰其他平台的同名分类旧备份合并保留当前顺序与非空展示字段并允许补齐旧父分类字段。持久化层使用写失败回滚的双写策略_persistAreasOrRollback先把内存列表写入 HivefavoriteAreas键失败时回滚内存并尽力重写旧快照保证 UI 状态与磁盘一致。审计明确没有为此修改应用持久化逻辑即身份修订不动数据表结构、不影响播放、录制、弹窗与窗口模块。四、分类页按钮从一次性快照改为响应式读取审计还暴露了一个 UI 生命周期缺陷收藏分类页控制器只在onInit复制一次设置列表引用设置层替换列表后已挂载页面仍观察旧快照导致关注状态不刷新。冻结上游同样存在此路径。修复方案是不在控制器中复制快照也不新增 Worker 或订阅而是在页面Obx中实时读取实际收藏 observable。对应实现见 lib/domains/live/presentation/area_rooms/area_rooms_page.dart 的FavoriteAreaFloatingButtonreturn Obx(() { final isFavorite FavoriteRoomController.to.isFavoriteArea(area); // ...根据 isFavorite 渲染圆形已关注或关注 名称状态 });Obx直接订阅FavoriteRoomController.to.favoriteAreasRxListLiveArea设置层任何替换都会立即驱动按钮重绘。交互侧还做了防抖_busy标志阻止并发点击取消收藏弹出确认对话框unfollow/unfollow_message确认后才调用removeAreaDurably异常时通过ToastUtil.show提示favorite_changes_save_failed。分类列表控制器area_rooms_controller.dart按站点与分类生成areaRoomsControllerTag仅作为页面/数据控制器标识不参与收藏身份判定。五、身份契约的连带应用迁移去重与备份合并同一身份规则被_itemIdentity复用于设置升级迁移的去重场景lib/core/config/migrations/settings_upgrade_migration.dartif (key favoriteAreas) { return LiveArea.identityKeyFor( platform: item[platform]?.toString(), areaId: item[areaId]?.toString(), areaType: item[areaType]?.toString(), ) ?? jsonEncode(item); }身份键为 null缺平台或 ID时回退为整条 JSON 编码保证不可匹配的记录仍保留唯一性、不误合并。与此配套的还有房间收藏的身份归一化_normalizeFavoriteRoomIdentitiesonInit与restoreFavoriteLists时对favoriteRooms做 trim、小写与去重非法 ID0/null/undefined/nan/none直接剔除。六、验证与交付红测 → 修订 → 终测的完整闭环审计批次严格执行先证明缺陷、再验证修复的流程共三轮记录第一轮红测20260907T173752870Z-favorite-area-red.json8 项业务断言稳定失败覆盖跨平台判断、重建删除、旧父分类删除、猫耳命名空间、ID 规范化、IPTV 删除、无身份误匹配与旧备份合并另 2 项是测试夹具问题原模型已有的 null→空字符串反序列化约定、GetMaterialApp 首路由未挂载即点击不算新应用缺陷。第二轮修订验证20260907T174610432Z-favorite-area-identity.json38 项测试主体通过但文件 Hive 收尾停滞导致整轮标失败。排查发现本地锁定依赖 Hive CE 2.19.3其hive_impl.dart的openBox(bytes: ...)使用正式内存后端最终 Widget 测试改用该内存后端与真实设置控制器而非替换业务方法普通异步测试继续验证真实文件 Hive 往返收尾加入 15 秒超时避免夹具无限挂起。没有为此修改应用持久化逻辑。最终通过20260907T174927592Z-favorite-area-identity.json38/38 通过本批 12 项分类收藏测试 旧 Hive 合并、备份集合校验、房间有效性及原生目录控制器回归6 个文件analyze无问题49.2 秒整轮 178.363 秒峰值 CPU 11.72%重型进程工作集约 13.4 GB结束活跃重型进程数 0证据保存在local-artifacts/favorite-area-20260908/validation-source.json绑定 6 个 Dart 文件的 SHA-256资源记录在local-artifacts/build-records/。审计过程还记录了进程收尾纪律初始 Widget 失败后 Hive 收尾停滞核对父子进程与本项目测试命令后仅终止该轮flutter_tester子进程守卫finally正常记录失败并释放不误杀其他项目的 Java/Gradle 进程。测试结论明确不外推为 Android/Windows 原生验收。七、回滚与边界兼容性设计本批修订为局部领域身份修订独立提交、可按批回滚不改播放、录制、弹幕、窗口或数据表结构持久化 JSON 格式保持兼容旧备份可正常合并回滚后恢复旧的 ID 碰撞行为即回到跨平台同 ID 误判/误删状态属于预期行为未使用 ADB、MT、Root 或 LSP无安装包、手机变更或发布动作版本仍3.1.84121不递增、不发布。审计同时提示了相邻集成风险猫耳catalog/tag同号是本分支新增适配的相邻风险旧备份合并键只有platform/areaId开放新入口前需补全身份合同本批没有新增平台注册。后续计划为猫耳注册、设置迁移、链接/请求头与播放录制接入最后执行原生验收与发布门禁。八、实践要点速查聚合收藏类数据必须建立复合身份(platform 归一化, 命名空间, areaId 归一化)三者构成身份任何单一字段都不可作为主键归一化规则要按字段差异化platform 小写折叠、areaId 保留大小写、仅特殊平台引入命名空间避免一刀切破坏既有数据判断、添加、删除共用同一身份函数三条调用路径UI 批量、设置层引用、备份合并必须收敛杜绝判断用 A 规则、删除用 B 规则的割裂用结构化编码代替字符串拼接jsonEncode([...])天然规避分隔符碰撞且编码结果稳定可持久化响应式 UI 直接订阅 Observable不要在控制器里复制列表快照Obx中实时读取即可让关注状态始终同步验证先红后绿先用红测固化 8 项失败断言再修订实现最后以 38/38 全绿、analyze 零告警作为交付门禁并保留 SHA-256 证据链兼容优先不清理用户旧数据、不改变 JSON 格式缺失身份字段的记录原样保留回滚成本可控。赞分享音视频直播移动开发【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载相关推荐飞书 IM 领域建模与 lark-cli 实战指南核心概念、身份映射与消息增强契约飞书 IM 领域建模与 lark cli 实战指南核心概念、身份映射与消息增强契约 本文以 lark cliLark/飞书官方 CLI 工具由 larksCLIAI 技能lark-cli 共享规则实战指南身份、认证、输出契约与高风险操作审批协议lark cli 共享规则实战指南身份、认证、输出契约与高风险操作审批协议 lark cli 是飞书官方维护的命令行工具面向人与 AI Agent 设计覆CLIAI 技能直播分区分类列表所有权与分页契约修复实战以 PureLive 猫耳平台只读列表异常为例直播分区分类列表所有权与分页契约修复实战以 PureLive 猫耳平台只读列表异常为例 导读 本文以 PureLive纯粹直播开源仓库中的一份技术审计文档音视频直播移动开发上一篇终极指南如何利用NLP技术优化旅游行业——旅游评论分析和目的地推荐的完整方案下一篇如何快速掌握Python异步编程asyncio.run主入口完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表