This commit is contained in:
zwgczx committed 2026-03-02 18:12:32 +08:00
1 parent a10359f7e0
commit 62546bc937
5 files changed
+107 -22

No files matched your search

+70 -6
View File
@@ -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" />