29204bc08a
Co-Authored-By: Claude Code <noreply@anthropic.com>
3.4 KiB
3.4 KiB
选图点选拦截 v2:硬封锁 + 仅本机判定(去服务器半场、去强制放行)
日期:2026-09-29 | 状态:用户拍板(方案 A:接受"服务端已删照片无法重传"限制)
背景与问题
v1(提交 7e5c550+0673f39)上线后两个实际问题:
- 选图不灵敏:
selectPredicate每次点选 await 判定,判定含服务器单项预检 (时间帽 2s)。弱网下每次点新照片勾选延迟 0.5~2s,用户以为没点上就反复点 (wechat_assets_pickerselectAsset源码:谓词返回前provider.selectAsset不执行——勾选必然等判定)。 - 拦截形同虚设:v1 设计了"二次点击强制选择"活口(escape hatch),配合上述 反复点击习惯,重复照片多点几次必然被强制选中——用户明确要求重复照片不能 被选择。
方案(v2)
1. 点选判定只查本机(治卡顿)
_judge仅保留本机 TaskStore 半场(同账号+相册+completed,filename+bytes), 删除服务器单项预检及其 2s 时间帽——点选延迟从「最多 2s 网络」降为「毫秒级 本地查询」。- 服务器查重不消失:入队时刻统一弹窗(checkDuplicatesUnified,一次批量 ≤500 张)照旧——跨设备/重装场景的重复仍在点上传时拦,服务端 409 兜底不变。
- iOS 注意:
title为空(需 FilterOption.needTitle)时本机半场无从匹配 → 放行;iOS 点选拦截实际不生效,跨设备判定依赖入队弹窗(与 v1 服务器半场 行为的差异登记于此)。
2. 硬封锁(去强制放行)
- 删除
_forced二次点击放行集:本机命中的重复照片每次点击都拒选, 判定缓存命中即秒拦,提示文案改为「这张已上传到该相册,无法重复选择」 (en: This photo has already been uploaded to this album),不再引导再点。 - SnackBar clearSnackBars 防堆积行为保留。
3. 判定缓存升级为 in-flight Future 共享
_verdicts从Map<String, bool>改为Map<String, Future<bool>>,putIfAbsent并发去重——同一照片双击/连点只发起一次判定(清偿 9-29 评审 登记 Minor 遗留)。_judge内部全捕获不抛错,缓存 Future 无失败态。
已接受的限制(用户拍板 A)
- 照片在后台被删除后想重传同一文件:本机历史仍记「已传」→ 永远拦死。 解决办法:清 App 数据或换设备(罕见场景,先接受;后续可加设置开关/服务端 存活性免疫,未排期)。
构造签名变化
PickerDuplicateGate 删除 client 与 serverCheckTimeout 入参(点选路径无
网络依赖);multiImagePickerProvider 相应不再注入 ApiClient。
测试(enqueue_test 拦截器组重写)
- 本机命中 → 拒选;连续多次点击均拒选(无强制路径);新提示文案; SnackBar 不堆积(第二个重复资产仅一条)。
- 不同 bytes / filename / 相册 / 账号 → 放行。
- in-flight 共享:并发两次 decideFact,fileSize 闭包仅被调用一次。
- title=null(iOS)→ 放行;fileSize 失败 → 放行;取消选择(selected=true) 恒放行且零查询(fileSize 计数为 0)。
- v1 服务器相关用例(②④⑥)随服务器半场移除而删除。
影响面
enqueue.dart(gate + provider 注入)+ enqueue_test.dart + l10n 双语一处
文案。不涉及服务端、契约、其它页面。