1
This commit is contained in:
1 parent
a10359f7e0
commit
62546bc937
5 files changed
+107
-22
No files matched your search
@@ -162,6 +162,7 @@ function handleSnapHostScroll() {
|
||||
const pickerOpen = ref(false)
|
||||
const pickerTempIds = ref<string[]>([])
|
||||
const pickerSearch = ref('')
|
||||
const pickerListScrollRef = ref<HTMLElement | null>(null)
|
||||
const clearConfirmOpen = ref(false)
|
||||
const pendingClearServiceId = ref<string | null>(null)
|
||||
const dragSelecting = ref(false)
|
||||
@@ -171,6 +172,61 @@ const dragBaseIds = ref<string[]>([])
|
||||
const dragStartPoint = ref({ x: 0, y: 0 })
|
||||
const dragCurrentPoint = ref({ x: 0, y: 0 })
|
||||
const pickerItemElMap = new Map<string, HTMLElement>()
|
||||
let dragTouchedIds = new Set<string>()
|
||||
let dragAutoScrollRafId: number | null = null
|
||||
|
||||
const DRAG_AUTO_SCROLL_EDGE = 36
|
||||
const DRAG_AUTO_SCROLL_MAX_STEP = 16
|
||||
|
||||
const stopDragAutoScroll = () => {
|
||||
if (dragAutoScrollRafId !== null) {
|
||||
cancelAnimationFrame(dragAutoScrollRafId)
|
||||
dragAutoScrollRafId = null
|
||||
}
|
||||
}
|
||||
|
||||
const resolveDragAutoScrollStep = () => {
|
||||
const scroller = pickerListScrollRef.value
|
||||
if (!scroller) return 0
|
||||
const rect = scroller.getBoundingClientRect()
|
||||
const pointerY = dragCurrentPoint.value.y
|
||||
let step = 0
|
||||
|
||||
if (pointerY > rect.bottom - DRAG_AUTO_SCROLL_EDGE) {
|
||||
const ratio = Math.min(2, (pointerY - (rect.bottom - DRAG_AUTO_SCROLL_EDGE)) / DRAG_AUTO_SCROLL_EDGE)
|
||||
step = Math.max(2, Math.round(ratio * DRAG_AUTO_SCROLL_MAX_STEP))
|
||||
} else if (pointerY < rect.top + DRAG_AUTO_SCROLL_EDGE) {
|
||||
const ratio = Math.min(2, ((rect.top + DRAG_AUTO_SCROLL_EDGE) - pointerY) / DRAG_AUTO_SCROLL_EDGE)
|
||||
step = -Math.max(2, Math.round(ratio * DRAG_AUTO_SCROLL_MAX_STEP))
|
||||
}
|
||||
return step
|
||||
}
|
||||
|
||||
const runDragAutoScroll = () => {
|
||||
if (!dragSelecting.value) {
|
||||
stopDragAutoScroll()
|
||||
return
|
||||
}
|
||||
|
||||
const scroller = pickerListScrollRef.value
|
||||
if (scroller) {
|
||||
const step = resolveDragAutoScrollStep()
|
||||
if (step !== 0) {
|
||||
const prev = scroller.scrollTop
|
||||
scroller.scrollTop += step
|
||||
if (scroller.scrollTop !== prev) {
|
||||
applyDragSelectionByRect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dragAutoScrollRafId = requestAnimationFrame(runDragAutoScroll)
|
||||
}
|
||||
|
||||
const startDragAutoScroll = () => {
|
||||
if (dragAutoScrollRafId !== null) return
|
||||
dragAutoScrollRafId = requestAnimationFrame(runDragAutoScroll)
|
||||
}
|
||||
|
||||
const selectedServiceText = computed(() => {
|
||||
if (selectedIds.value.length === 0) return ''
|
||||
@@ -642,11 +698,15 @@ const applyDragSelectionByRect = () => {
|
||||
const itemRect = el.getBoundingClientRect()
|
||||
const hit = isRectIntersect(rect, itemRect)
|
||||
if (hit) {
|
||||
if (dragSelectChecked) {
|
||||
nextSelectedSet.add(code)
|
||||
} else {
|
||||
nextSelectedSet.delete(code)
|
||||
}
|
||||
dragTouchedIds.add(code)
|
||||
}
|
||||
}
|
||||
|
||||
for (const code of dragTouchedIds) {
|
||||
if (dragSelectChecked) {
|
||||
nextSelectedSet.add(code)
|
||||
} else {
|
||||
nextSelectedSet.delete(code)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,6 +719,8 @@ const stopDragSelect = () => {
|
||||
dragSelecting.value = false
|
||||
dragMoved.value = false
|
||||
dragBaseIds.value = []
|
||||
dragTouchedIds.clear()
|
||||
stopDragAutoScroll()
|
||||
window.removeEventListener('mousemove', onDragSelectingMove)
|
||||
window.removeEventListener('mouseup', stopDragSelect)
|
||||
}
|
||||
@@ -679,10 +741,12 @@ const startDragSelect = (event: MouseEvent, code: string) => {
|
||||
dragSelecting.value = true
|
||||
dragMoved.value = false
|
||||
dragBaseIds.value = [...pickerTempIds.value]
|
||||
dragTouchedIds = new Set([code])
|
||||
dragSelectChecked = !pickerTempIds.value.includes(code)
|
||||
dragStartPoint.value = { x: event.clientX, y: event.clientY }
|
||||
dragCurrentPoint.value = { x: event.clientX, y: event.clientY }
|
||||
applyTempChecked(code, dragSelectChecked)
|
||||
startDragAutoScroll()
|
||||
window.addEventListener('mousemove', onDragSelectingMove)
|
||||
window.addEventListener('mouseup', stopDragSelect)
|
||||
}
|
||||
@@ -821,7 +885,7 @@ onBeforeUnmount(() => {
|
||||
</DialogClose>
|
||||
</div>
|
||||
|
||||
<div class="max-h-[420px] overflow-auto px-5 py-4">
|
||||
<div ref="pickerListScrollRef" class="max-h-[420px] overflow-auto px-5 py-4">
|
||||
<div class="mb-3">
|
||||
<input v-model="pickerSearch" type="text" placeholder="输入编码或名称过滤"
|
||||
class="h-9 w-full rounded-md border bg-background px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring" />
|
||||
|
||||
+3
-10
@@ -2,7 +2,6 @@ import {
|
||||
CellStyleModule,
|
||||
ClientSideRowModelModule,
|
||||
ColumnAutoSizeModule,
|
||||
CsvExportModule,
|
||||
LargeTextEditorModule,
|
||||
LocaleModule,
|
||||
ModuleRegistry,
|
||||
@@ -12,17 +11,15 @@ import {
|
||||
TextEditorModule,
|
||||
TooltipModule,
|
||||
UndoRedoEditModule,
|
||||
ValidationModule
|
||||
|
||||
} from 'ag-grid-community'
|
||||
import {
|
||||
AggregationModule,
|
||||
CellSelectionModule,
|
||||
ClipboardModule,
|
||||
ContextMenuModule,
|
||||
LicenseManager,
|
||||
MenuModule,
|
||||
RowGroupingModule,
|
||||
TreeDataModule
|
||||
TreeDataModule,ContextMenuModule
|
||||
} from 'ag-grid-enterprise'
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
@@ -37,10 +34,9 @@ LicenseManager.setLicenseKey(
|
||||
const AG_GRID_MODULES = [
|
||||
ClientSideRowModelModule,
|
||||
ColumnAutoSizeModule,
|
||||
CsvExportModule,
|
||||
TextEditorModule,
|
||||
NumberEditorModule,
|
||||
RowAutoHeightModule,
|
||||
RowAutoHeightModule,ContextMenuModule,
|
||||
LargeTextEditorModule,
|
||||
UndoRedoEditModule,
|
||||
CellStyleModule,
|
||||
@@ -49,12 +45,9 @@ const AG_GRID_MODULES = [
|
||||
TreeDataModule,
|
||||
AggregationModule,
|
||||
RowGroupingModule,
|
||||
MenuModule,
|
||||
CellSelectionModule,
|
||||
ContextMenuModule,
|
||||
ClipboardModule,
|
||||
LocaleModule,
|
||||
ValidationModule
|
||||
]
|
||||
|
||||
const pinia = createPinia()
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
@@ -126,6 +130,7 @@
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
margin: 0;
|
||||
}
|
||||
input,
|
||||
textarea,
|
||||
@@ -234,3 +239,10 @@
|
||||
height:100%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Laptop screens often need a slightly denser desktop layout. */
|
||||
@media (max-width: 1536px) {
|
||||
html {
|
||||
font-size: 14.4px;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user