diff --git a/resources/views/business/pages/partials/installation-fee-summary.blade.php b/resources/views/business/pages/partials/installation-fee-summary.blade.php index 32e526e7..51075a4c 100644 --- a/resources/views/business/pages/partials/installation-fee-summary.blade.php +++ b/resources/views/business/pages/partials/installation-fee-summary.blade.php @@ -210,6 +210,7 @@ width: min(68rem, calc(100vw - 2rem)); max-width: none; max-height: calc(100vh - 2rem); + box-sizing: border-box; padding: 0; border: 1px solid #d8d2c7; border-radius: 0.75rem; @@ -351,13 +352,49 @@ } .installation-fee-dialog__scroll { - min-height: 12rem; + flex: 1 1 auto; + min-height: 0; + box-sizing: border-box; overflow: auto; - padding: 0 1.1rem; + padding: 0 1.1rem 0.65rem; + overscroll-behavior: contain; + scrollbar-color: #b9954f #f1ece3; + scrollbar-gutter: stable; + scrollbar-width: thin; + cursor: grab; + touch-action: pan-x pan-y; + } + + .installation-fee-dialog__scroll.is-dragging { + cursor: grabbing; + user-select: none; + } + + .installation-fee-dialog__scroll::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + .installation-fee-dialog__scroll::-webkit-scrollbar-track { + background: #f1ece3; + } + + .installation-fee-dialog__scroll::-webkit-scrollbar-thumb { + border-radius: 999px; + background: #b9954f; + } + + .installation-fee-dialog__scroll::-webkit-scrollbar-thumb:hover { + background: #856632; + } + + .installation-fee-panel { + min-width: 100%; } .installation-fee-table { width: 100%; + min-width: 72rem; border-collapse: collapse; font-size: 0.75rem; font-variant-numeric: tabular-nums; @@ -370,6 +407,7 @@ line-height: 1.5; text-align: left; vertical-align: middle; + white-space: nowrap; } .installation-fee-table thead th { @@ -400,6 +438,7 @@ .installation-fee-platform-summary table { width: 100%; + min-width: 32rem; border-collapse: collapse; font-size: 0.75rem; font-variant-numeric: tabular-nums; @@ -412,6 +451,7 @@ line-height: 1.5; text-align: left; vertical-align: middle; + white-space: nowrap; } .installation-fee-platform-summary th { @@ -519,7 +559,11 @@ -
+
@@ -580,7 +624,7 @@ var emptyEl = dialog.querySelector('[data-installation-fee-empty]'); var platformEmptyEl = dialog.querySelector('[data-installation-fee-platform-empty]'); var countEl = dialog.querySelector('[data-installation-fee-count]'); - var scrollEl = dialog.querySelector('.installation-fee-dialog__scroll'); + var scrollEl = dialog.querySelector('[data-installation-fee-scroll]'); var tabsEl = dialog.querySelector('.installation-fee-tabs'); var tabButtons = Array.from(dialog.querySelectorAll('[data-installation-fee-tab]')); var tabPanels = Array.from(dialog.querySelectorAll('[data-installation-fee-panel]')); @@ -617,6 +661,7 @@ }); if (scrollEl) { scrollEl.scrollTop = 0; + scrollEl.scrollLeft = 0; } updateCount(); } @@ -920,6 +965,66 @@ timer = window.setTimeout(function () { refresh(true); }, 250); } + var dragState = null; + + function finishHorizontalDrag(event) { + if (!dragState) { + return; + } + var state = dragState; + dragState = null; + scrollEl.classList.remove('is-dragging'); + if (event && state.pointerId !== null && scrollEl.hasPointerCapture(state.pointerId)) { + scrollEl.releasePointerCapture(state.pointerId); + } + } + + if (scrollEl) { + scrollEl.addEventListener('pointerdown', function (event) { + if (event.button !== 0 || event.target.closest('button, a, input, select, textarea')) { + return; + } + dragState = { + active: false, + pointerId: event.pointerId, + startX: event.clientX, + startY: event.clientY, + scrollLeft: scrollEl.scrollLeft + }; + }); + scrollEl.addEventListener('pointermove', function (event) { + if (!dragState || dragState.pointerId !== event.pointerId) { + return; + } + var dx = event.clientX - dragState.startX; + var dy = event.clientY - dragState.startY; + if (!dragState.active) { + if (Math.abs(dx) < 6 || Math.abs(dx) <= Math.abs(dy)) { + return; + } + dragState.active = true; + scrollEl.classList.add('is-dragging'); + scrollEl.setPointerCapture(event.pointerId); + var selection = window.getSelection(); + if (selection) { + selection.removeAllRanges(); + } + } + event.preventDefault(); + scrollEl.scrollLeft = dragState.scrollLeft - dx; + }); + ['pointerup', 'pointercancel', 'lostpointercapture'].forEach(function (eventName) { + scrollEl.addEventListener(eventName, finishHorizontalDrag); + }); + scrollEl.addEventListener('wheel', function (event) { + if (!event.shiftKey || Math.abs(event.deltaY) <= Math.abs(event.deltaX)) { + return; + } + scrollEl.scrollLeft += event.deltaY; + event.preventDefault(); + }, { passive: false }); + } + openButton.addEventListener('click', function () { openDialog(); refresh(false); diff --git a/tests/Feature/Business/ManagementCrudTest.php b/tests/Feature/Business/ManagementCrudTest.php index 1d134a32..ebb7eeb4 100644 --- a/tests/Feature/Business/ManagementCrudTest.php +++ b/tests/Feature/Business/ManagementCrudTest.php @@ -297,6 +297,13 @@ class ManagementCrudTest extends FeatureTestCase ->assertSee('installation-fee-panel is-active', false) ->assertSeeText('店铺明细') ->assertSee('overflow-x: auto', false) + ->assertSee('data-installation-fee-scroll', false) + ->assertSee('scrollbar-color: #b9954f #f1ece3', false) + ->assertSee('scrollbar-gutter: stable', false) + ->assertSee('cursor: grab', false) + ->assertSee('min-width: 72rem', false) + ->assertSee("scrollEl.addEventListener('pointerdown'", false) + ->assertSee('scrollEl.scrollLeft = dragState.scrollLeft - dx', false) ->assertSeeText('共 0 条平台汇总') ->assertSee('--installation-fee-accent: #856632', false) ->assertSee('border-left: 3px solid var(--installation-fee-accent)', false)