From 5ec15fafc58de134b1c62c845e11ecd068d15286 Mon Sep 17 00:00:00 2001 From: yueyang <2495544247@qq.com> Date: Tue, 27 Oct 2026 10:50:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E5=BE=85=E5=8A=9E=E6=88=AA=E5=9B=BE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E4=BB=BB=E5=8A=A1=E5=86=85=E7=94=BB=E5=BB=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/systemization-todos.blade.php | 131 +++++++++++++----- .../Business/SystemizationTodosTest.php | 8 +- 2 files changed, 99 insertions(+), 40 deletions(-) diff --git a/resources/views/business/pages/systemization-todos.blade.php b/resources/views/business/pages/systemization-todos.blade.php index b9456501..821ce9cd 100644 --- a/resources/views/business/pages/systemization-todos.blade.php +++ b/resources/views/business/pages/systemization-todos.blade.php @@ -83,10 +83,12 @@ .sys-todo-badge { display:inline-flex; align-items:center; padding:.1rem .45rem; border:1px solid #dfd6c5; border-radius:999px; background:#faf6ee; color:#51483c; white-space:nowrap; } .sys-todo-badge--incomplete { border-color:#dbbf7a; background:#fff7df; color:#935f07; } .sys-todo-badge--completed { border-color:#bad0ac; background:#f2f8ed; color:#53793e; } - .sys-todo-shots { display:grid; grid-template-columns:repeat(auto-fit,minmax(7rem,1fr)); gap:.4rem; max-width:none; } - .sys-todo-shots button { display:block; width:100%; height:5.5rem; padding:0; border:1px solid #ddd4c4; border-radius:.4rem; overflow:hidden; background:#fff; cursor:zoom-in; } - .sys-todo-shots img { width:100%; height:100%; padding:.2rem; object-fit:contain; background:#fff; } - .sys-todo-shots-caption { display:-webkit-box; margin-top:.35rem; overflow:hidden; color:#6d5630; font-size:.68rem; line-height:1.45; overflow-wrap:anywhere; -webkit-box-orient:vertical; -webkit-line-clamp:2; } + .sys-todo-table__title-wrap { display:flex; flex-wrap:wrap; align-items:flex-start; gap:.35rem .55rem; } + .sys-todo-table__title-text { min-width:0; flex:1 1 12rem; } + .sys-todo-shot-trigger { display:inline-flex; flex:0 0 auto; align-items:center; gap:.25rem; min-height:1.8rem; padding:0 .5rem; border:1px solid #d8c9aa; border-radius:.4rem; background:#fffaf0; color:#6d5630; font:inherit; font-size:.7rem; font-weight:500; white-space:nowrap; cursor:pointer; } + .sys-todo-shot-trigger:hover { border-color:var(--sys-gold); background:var(--sys-gold-soft); color:#6a5129; } + .sys-todo-shot-trigger:focus-visible { outline:2px solid var(--sys-gold); outline-offset:2px; } + .sys-todo-shot-trigger .material-icons-outlined { font-size:1rem; } .sys-todo-table__add { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:.5rem .75rem; margin-top:1rem; padding:.55rem .7rem; border:1px dashed #d8cdb8; border-radius:.55rem; background:#fcfaf5; color:#666; font-size:.72rem; } .sys-todo-table__add-copy { min-width:16rem; flex:1 1 30rem; } .sys-todo-table__reset-widths { min-height:1.8rem; padding:0 .55rem; border:1px solid var(--sys-border); border-radius:.4rem; background:#fff; color:#51483c; font:inherit; font-size:.7rem; cursor:pointer; } @@ -182,8 +184,11 @@ .sys-todo-image-dialog__head { display:flex; align-items:center; gap:1rem; padding:.65rem .85rem; background:#1d1d1f; } .sys-todo-image-dialog__head h2 { margin:0; min-width:0; overflow:hidden; font-size:.82rem; text-overflow:ellipsis; white-space:nowrap; } .sys-todo-image-dialog__head button { margin-left:auto; width:2rem; height:2rem; border:1px solid #5a554d; border-radius:999px; background:#2a2927; color:#fff; cursor:pointer; } - .sys-todo-image-dialog__body { display:grid; place-items:center; height:calc(92vh - 7rem); padding:.75rem; background:#111; overflow:auto; } + .sys-todo-image-dialog__body { display:grid; grid-template-columns:2.25rem minmax(0,1fr) 2.25rem; align-items:center; gap:.6rem; height:calc(92vh - 7rem); padding:.75rem; background:#111; overflow:auto; } .sys-todo-image-dialog__body img { max-width:100%; max-height:100%; object-fit:contain; } + .sys-todo-image-dialog__body button { display:inline-flex; align-items:center; justify-content:center; width:2.25rem; height:2.75rem; padding:0; border:1px solid #5a554d; border-radius:999px; background:#2a2927; color:#fff; font-size:1.5rem; cursor:pointer; } + .sys-todo-image-dialog__body button:hover { border-color:#f0e4bf; color:#f0e4bf; } + .sys-todo-image-dialog__body button[hidden] { visibility:hidden; } .sys-todo-image-dialog__foot { display:flex; justify-content:flex-end; padding:.55rem .85rem; background:#1d1d1f; } .sys-todo-image-dialog__foot a { color:#f0e4bf; font-size:.75rem; } @media (max-width:1300px) { .sys-todo-summary { grid-template-columns:repeat(2,minmax(0,1fr)); } } @@ -371,7 +376,6 @@ - @@ -386,7 +390,6 @@ 提醒 状态 完成情况 / 备注 - 完成截图 @@ -491,7 +494,19 @@ {{ $titleLabels[$loop->index] }} + data-sys-todo-row-edit="{{ $todoPayloadEncoded }}"> +
+ {{ $titleLabels[$loop->index] }} + @if ($item->attachments->isNotEmpty()) + + @endif +
+ {{ $item->owner ?: '—' }} {{ $item->assignee ?: '—' }} {{ $item->start_date?->format('Y-m-d') ?: ($item->start_note ?: '—') }} @@ -516,30 +531,9 @@ — @endif - - @if ($item->attachments->isNotEmpty()) -
- @foreach ($item->attachments as $attachment) - @php - $attachmentUrl = route('business.systemization-todos.attachments.show', [ - 'todo' => $item->id, - 'attachment' => $attachment->id, - ]); - @endphp - - @endforeach -
- 所属待办:{{ $titleLabels[$loop->index] ?: '未填写事项' }} - @else - — - @endif - @empty -
当前筛选条件下没有待办事项。
+
当前筛选条件下没有待办事项。
@endforelse @@ -549,7 +543,7 @@ data-sys-todo-inline-add data-sys-todo-add-mode="type">+ 类型 - 也可在现有类型下方新增内容,在内容下方新增待办。 + 也可在现有类型下方新增内容,在内容下方新增待办。 @@ -712,7 +706,9 @@
+ +
在新页面打开原图 @@ -735,6 +731,10 @@ var imagePreview = imageViewer.querySelector('[data-sys-todo-image-preview]'); var imageTitle = imageViewer.querySelector('[data-sys-todo-image-title]'); var imageOpen = imageViewer.querySelector('[data-sys-todo-image-open]'); + var imagePrevious = imageViewer.querySelector('[data-sys-todo-image-prev]'); + var imageNext = imageViewer.querySelector('[data-sys-todo-image-next]'); + var imageGalleryItems = []; + var imageGalleryIndex = 0; var categorySelect = dialog.querySelector('[data-sys-todo-category-select]'); var categoryValue = dialog.querySelector('[data-sys-todo-category-value]'); var newCategoryWrap = dialog.querySelector('[data-sys-todo-new-category]'); @@ -1193,19 +1193,58 @@ } } - function openImageViewer(url, name) { - imageTitle.textContent = name || '完成截图预览'; - imagePreview.src = url; - imagePreview.alt = name || '完成截图'; - imageOpen.href = url; + function showImageViewerItem() { + var item = imageGalleryItems[imageGalleryIndex]; + if (!item) return; + + var position = imageGalleryItems.length > 1 + ? (imageGalleryIndex + 1) + ' / ' + imageGalleryItems.length + ' · ' + : ''; + imageTitle.textContent = position + (item.name || '完成截图预览'); + imagePreview.src = item.url; + imagePreview.alt = item.name || '完成截图'; + imageOpen.href = item.url; + imagePrevious.hidden = imageGalleryItems.length <= 1; + imageNext.hidden = imageGalleryItems.length <= 1; + } + + function openImageViewerItems(items) { + imageGalleryItems = Array.isArray(items) && items.length + ? items + : []; + imageGalleryIndex = 0; + if (!imageGalleryItems.length) return; + + showImageViewerItem(); if (typeof imageViewer.showModal === 'function') imageViewer.showModal(); else imageViewer.setAttribute('open', ''); } + function openImageViewer(url, name) { + openImageViewerItems([{ url: url, name: name }]); + } + + function showPreviousImage() { + if (imageGalleryItems.length < 2) return; + imageGalleryIndex = (imageGalleryIndex - 1 + imageGalleryItems.length) % imageGalleryItems.length; + showImageViewerItem(); + } + + function showNextImage() { + if (imageGalleryItems.length < 2) return; + imageGalleryIndex = (imageGalleryIndex + 1) % imageGalleryItems.length; + showImageViewerItem(); + } + function closeImageViewer() { if (typeof imageViewer.close === 'function') imageViewer.close(); else imageViewer.removeAttribute('open'); imagePreview.removeAttribute('src'); + imageTitle.textContent = '完成截图预览'; + imageGalleryItems = []; + imageGalleryIndex = 0; + imagePrevious.hidden = true; + imageNext.hidden = true; } function openGroupDialog(type, value, count) { @@ -1331,6 +1370,14 @@ } document.addEventListener('click', function (event) { + var gallery = event.target.closest('[data-sys-todo-image-gallery]'); + if (gallery) { + event.preventDefault(); + event.stopPropagation(); + var galleryPayload = decodePayload(gallery.getAttribute('data-sys-todo-image-gallery')); + openImageViewerItems(galleryPayload.attachments || []); + return; + } var image = event.target.closest('[data-sys-todo-image-url]'); if (image) { event.preventDefault(); @@ -1397,6 +1444,8 @@ if (event.target.closest('[data-sys-todo-group-close]')) closeGroupDialog(); if (event.target.closest('[data-sys-todo-delete-close]')) closeDeleteConfirm(); if (event.target.closest('[data-sys-todo-image-close]')) closeImageViewer(); + if (event.target.closest('[data-sys-todo-image-prev]')) showPreviousImage(); + if (event.target.closest('[data-sys-todo-image-next]')) showNextImage(); if (event.target.closest('[data-sys-todo-choose-files]')) screenshotInput.click(); }); dialog.addEventListener('click', function (event) { @@ -1487,6 +1536,16 @@ closeImageViewer(); return; } + if (imageViewer.open && event.key === 'ArrowLeft') { + event.preventDefault(); + showPreviousImage(); + return; + } + if (imageViewer.open && event.key === 'ArrowRight') { + event.preventDefault(); + showNextImage(); + return; + } var groupCell = event.target.closest('[data-sys-todo-group-edit]'); if (groupCell && event.target === groupCell && (event.key === 'Enter' || event.key === ' ')) { event.preventDefault(); diff --git a/tests/Feature/Business/SystemizationTodosTest.php b/tests/Feature/Business/SystemizationTodosTest.php index 458535d0..f4055150 100644 --- a/tests/Feature/Business/SystemizationTodosTest.php +++ b/tests/Feature/Business/SystemizationTodosTest.php @@ -68,8 +68,8 @@ class SystemizationTodosTest extends FeatureTestCase ->assertSee('id="sysTodoDeleteConfirm"', false) ->assertSee('data-sys-todo-table-wrap', false) ->assertSee('data-sys-todo-scrollrail', false) - ->assertSee('object-fit:contain', false) - ->assertSee('data-sys-todo-col="screenshots" data-default-width="180" data-min-width="140"', false) + ->assertSee('data-sys-todo-image-prev', false) + ->assertSee('data-sys-todo-image-next', false) ->assertDontSee('playlist_add', false) ->assertDontSee('操作', false) ->assertDontSeeText('下一页') @@ -113,8 +113,8 @@ class SystemizationTodosTest extends FeatureTestCase ])) ->assertOk() ->assertSee('data-sys-todo-row-edit', false) - ->assertSee('data-sys-todo-image-url', false) - ->assertSeeText('所属待办:核对淘系收入与平台账单差异'); + ->assertSee('data-sys-todo-image-gallery', false) + ->assertSeeText('截图 2'); $firstAttachment = $todo->attachments()->firstOrFail(); $existingAttachment = $todo->attachments()->reorder()->orderByDesc('id')->firstOrFail(); Storage::disk('uploads')->assertExists($firstAttachment->path); -- 2.47.2