feat(app): server-side duplicate pre-check at enqueue moment
Task 2 of docs/plans/2026-09-28-上传查重前置到入队前-实施计划.md:
surface server-side duplicate history at the "click upload" moment,
merged with the local check into the EXISTING dialog.
- ApiClient.checkUploadDuplicates: POST /v1/uploads/duplicates/check
(commit 805f77b endpoint); 500/chunk sequential requests; chunk-local
index translated to global; empty list short-circuits (no request);
errors normalized to AppException via _send.
- enqueue.checkDuplicatesUnified: local TaskStore history ∪ server
history; server hits map back to filename via global index into the
stat'd picks; merged, de-duplicated (filename+bytes) list; server
failure (network/permission/any) silently degrades to local-only —
init 409 remains the backstop.
- capture_page + album_detail_page _pickFromGallery now call the
unified entry; dialog/skip/force logic untouched.
Tests: api_client chunking (1200 → 500/500/200) + index translation +
merge + 404 normalization + empty no-request; page-level three states
(hit/no-hit/network failure) incl. fresh-install server-only-hit dialog
on both pages; pre-existing Task 8 dialog tests keep passing via the
degrade path.
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -342,8 +342,9 @@ class _AlbumDetailPageState extends ConsumerState<AlbumDetailPage> {
|
||||
if (paths.isEmpty || !mounted) return;
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
|
||||
// P0-1 层 1:入队前查重。
|
||||
final duplicates = await checkDuplicates(
|
||||
// P0-1 层 1+2(Task 2 统一入口):入队前查重——本机 TaskStore 历史
|
||||
// ∪ 服务器历史(bytes 命中;服务器失败静默降级本机-only)。
|
||||
final duplicates = await checkDuplicatesUnified(
|
||||
ref,
|
||||
accountId: account,
|
||||
albumId: album.id,
|
||||
|
||||
@@ -453,8 +453,9 @@ class _CapturePageState extends ConsumerState<CapturePage>
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
|
||||
// P0-1 层 1:入队前查重(同相册已完成的 filename+bytes 匹配)。
|
||||
final duplicates = await checkDuplicates(
|
||||
// P0-1 层 1+2(Task 2 统一入口):入队前查重——本机 TaskStore 历史
|
||||
// ∪ 服务器历史(bytes 命中;服务器失败静默降级本机-only)。
|
||||
final duplicates = await checkDuplicatesUnified(
|
||||
ref,
|
||||
accountId: widget.target.accountId,
|
||||
albumId: widget.target.albumId,
|
||||
|
||||
Reference in New Issue
Block a user