1
This commit is contained in:
parent
a10359f7e0
commit
62546bc937
@ -162,6 +162,7 @@ function handleSnapHostScroll() {
|
|||||||
const pickerOpen = ref(false)
|
const pickerOpen = ref(false)
|
||||||
const pickerTempIds = ref<string[]>([])
|
const pickerTempIds = ref<string[]>([])
|
||||||
const pickerSearch = ref('')
|
const pickerSearch = ref('')
|
||||||
|
const pickerListScrollRef = ref<HTMLElement | null>(null)
|
||||||
const clearConfirmOpen = ref(false)
|
const clearConfirmOpen = ref(false)
|
||||||
const pendingClearServiceId = ref<string | null>(null)
|
const pendingClearServiceId = ref<string | null>(null)
|
||||||
const dragSelecting = ref(false)
|
const dragSelecting = ref(false)
|
||||||
@ -171,6 +172,61 @@ const dragBaseIds = ref<string[]>([])
|
|||||||
const dragStartPoint = ref({ x: 0, y: 0 })
|
const dragStartPoint = ref({ x: 0, y: 0 })
|
||||||
const dragCurrentPoint = ref({ x: 0, y: 0 })
|
const dragCurrentPoint = ref({ x: 0, y: 0 })
|
||||||
const pickerItemElMap = new Map<string, HTMLElement>()
|
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(() => {
|
const selectedServiceText = computed(() => {
|
||||||
if (selectedIds.value.length === 0) return ''
|
if (selectedIds.value.length === 0) return ''
|
||||||
@ -642,13 +698,17 @@ const applyDragSelectionByRect = () => {
|
|||||||
const itemRect = el.getBoundingClientRect()
|
const itemRect = el.getBoundingClientRect()
|
||||||
const hit = isRectIntersect(rect, itemRect)
|
const hit = isRectIntersect(rect, itemRect)
|
||||||
if (hit) {
|
if (hit) {
|
||||||
|
dragTouchedIds.add(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const code of dragTouchedIds) {
|
||||||
if (dragSelectChecked) {
|
if (dragSelectChecked) {
|
||||||
nextSelectedSet.add(code)
|
nextSelectedSet.add(code)
|
||||||
} else {
|
} else {
|
||||||
nextSelectedSet.delete(code)
|
nextSelectedSet.delete(code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pickerTempIds.value = serviceDict
|
pickerTempIds.value = serviceDict
|
||||||
.map(item => item.id)
|
.map(item => item.id)
|
||||||
@ -659,6 +719,8 @@ const stopDragSelect = () => {
|
|||||||
dragSelecting.value = false
|
dragSelecting.value = false
|
||||||
dragMoved.value = false
|
dragMoved.value = false
|
||||||
dragBaseIds.value = []
|
dragBaseIds.value = []
|
||||||
|
dragTouchedIds.clear()
|
||||||
|
stopDragAutoScroll()
|
||||||
window.removeEventListener('mousemove', onDragSelectingMove)
|
window.removeEventListener('mousemove', onDragSelectingMove)
|
||||||
window.removeEventListener('mouseup', stopDragSelect)
|
window.removeEventListener('mouseup', stopDragSelect)
|
||||||
}
|
}
|
||||||
@ -679,10 +741,12 @@ const startDragSelect = (event: MouseEvent, code: string) => {
|
|||||||
dragSelecting.value = true
|
dragSelecting.value = true
|
||||||
dragMoved.value = false
|
dragMoved.value = false
|
||||||
dragBaseIds.value = [...pickerTempIds.value]
|
dragBaseIds.value = [...pickerTempIds.value]
|
||||||
|
dragTouchedIds = new Set([code])
|
||||||
dragSelectChecked = !pickerTempIds.value.includes(code)
|
dragSelectChecked = !pickerTempIds.value.includes(code)
|
||||||
dragStartPoint.value = { x: event.clientX, y: event.clientY }
|
dragStartPoint.value = { x: event.clientX, y: event.clientY }
|
||||||
dragCurrentPoint.value = { x: event.clientX, y: event.clientY }
|
dragCurrentPoint.value = { x: event.clientX, y: event.clientY }
|
||||||
applyTempChecked(code, dragSelectChecked)
|
applyTempChecked(code, dragSelectChecked)
|
||||||
|
startDragAutoScroll()
|
||||||
window.addEventListener('mousemove', onDragSelectingMove)
|
window.addEventListener('mousemove', onDragSelectingMove)
|
||||||
window.addEventListener('mouseup', stopDragSelect)
|
window.addEventListener('mouseup', stopDragSelect)
|
||||||
}
|
}
|
||||||
@ -821,7 +885,7 @@ onBeforeUnmount(() => {
|
|||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</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">
|
<div class="mb-3">
|
||||||
<input v-model="pickerSearch" type="text" placeholder="输入编码或名称过滤"
|
<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" />
|
class="h-9 w-full rounded-md border bg-background px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring" />
|
||||||
|
|||||||
13
src/main.ts
13
src/main.ts
@ -2,7 +2,6 @@ import {
|
|||||||
CellStyleModule,
|
CellStyleModule,
|
||||||
ClientSideRowModelModule,
|
ClientSideRowModelModule,
|
||||||
ColumnAutoSizeModule,
|
ColumnAutoSizeModule,
|
||||||
CsvExportModule,
|
|
||||||
LargeTextEditorModule,
|
LargeTextEditorModule,
|
||||||
LocaleModule,
|
LocaleModule,
|
||||||
ModuleRegistry,
|
ModuleRegistry,
|
||||||
@ -12,17 +11,15 @@ import {
|
|||||||
TextEditorModule,
|
TextEditorModule,
|
||||||
TooltipModule,
|
TooltipModule,
|
||||||
UndoRedoEditModule,
|
UndoRedoEditModule,
|
||||||
ValidationModule
|
|
||||||
} from 'ag-grid-community'
|
} from 'ag-grid-community'
|
||||||
import {
|
import {
|
||||||
AggregationModule,
|
AggregationModule,
|
||||||
CellSelectionModule,
|
CellSelectionModule,
|
||||||
ClipboardModule,
|
ClipboardModule,
|
||||||
ContextMenuModule,
|
|
||||||
LicenseManager,
|
LicenseManager,
|
||||||
MenuModule,
|
|
||||||
RowGroupingModule,
|
RowGroupingModule,
|
||||||
TreeDataModule
|
TreeDataModule,ContextMenuModule
|
||||||
} from 'ag-grid-enterprise'
|
} from 'ag-grid-enterprise'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||||
@ -37,10 +34,9 @@ LicenseManager.setLicenseKey(
|
|||||||
const AG_GRID_MODULES = [
|
const AG_GRID_MODULES = [
|
||||||
ClientSideRowModelModule,
|
ClientSideRowModelModule,
|
||||||
ColumnAutoSizeModule,
|
ColumnAutoSizeModule,
|
||||||
CsvExportModule,
|
|
||||||
TextEditorModule,
|
TextEditorModule,
|
||||||
NumberEditorModule,
|
NumberEditorModule,
|
||||||
RowAutoHeightModule,
|
RowAutoHeightModule,ContextMenuModule,
|
||||||
LargeTextEditorModule,
|
LargeTextEditorModule,
|
||||||
UndoRedoEditModule,
|
UndoRedoEditModule,
|
||||||
CellStyleModule,
|
CellStyleModule,
|
||||||
@ -49,12 +45,9 @@ const AG_GRID_MODULES = [
|
|||||||
TreeDataModule,
|
TreeDataModule,
|
||||||
AggregationModule,
|
AggregationModule,
|
||||||
RowGroupingModule,
|
RowGroupingModule,
|
||||||
MenuModule,
|
|
||||||
CellSelectionModule,
|
CellSelectionModule,
|
||||||
ContextMenuModule,
|
|
||||||
ClipboardModule,
|
ClipboardModule,
|
||||||
LocaleModule,
|
LocaleModule,
|
||||||
ValidationModule
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|||||||
@ -5,6 +5,10 @@
|
|||||||
height: 100dvh;
|
height: 100dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
@ -126,6 +130,7 @@
|
|||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
input,
|
input,
|
||||||
textarea,
|
textarea,
|
||||||
@ -234,3 +239,10 @@
|
|||||||
height:100%;
|
height:100%;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Laptop screens often need a slightly denser desktop layout. */
|
||||||
|
@media (max-width: 1536px) {
|
||||||
|
html {
|
||||||
|
font-size: 14.4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
{"root":["./src/main.ts","./src/sql.ts","./src/components/ui/button/index.ts","./src/components/ui/card/index.ts","./src/components/ui/scroll-area/index.ts","./src/components/ui/tooltip/index.ts","./src/lib/decimal.ts","./src/lib/diyaggridoptions.ts","./src/lib/numberformat.ts","./src/lib/pricingmethodtotals.ts","./src/lib/utils.ts","./src/lib/xmfactordefaults.ts","./src/lib/zwarchive.ts","./src/lib/zxfwpricingsync.ts","./src/pinia/pricingpanereload.ts","./src/pinia/tab.ts","./src/app.vue","./src/components/ui/button/button.vue","./src/components/ui/card/card.vue","./src/components/ui/card/cardaction.vue","./src/components/ui/card/cardcontent.vue","./src/components/ui/card/carddescription.vue","./src/components/ui/card/cardfooter.vue","./src/components/ui/card/cardheader.vue","./src/components/ui/card/cardtitle.vue","./src/components/ui/scroll-area/scrollarea.vue","./src/components/ui/scroll-area/scrollbar.vue","./src/components/ui/tooltip/tooltipcontent.vue","./src/components/views/contractdetailview.vue","./src/components/views/ht.vue","./src/components/views/xm.vue","./src/components/views/xmconsultcategoryfactor.vue","./src/components/views/xmfactorgrid.vue","./src/components/views/xmmajorfactor.vue","./src/components/views/zxfwview.vue","./src/components/views/htinfo.vue","./src/components/views/xminfo.vue","./src/components/views/zxfw.vue","./src/components/views/pricingview/hourlypricingpane.vue","./src/components/views/pricingview/investmentscalepricingpane.vue","./src/components/views/pricingview/landscalepricingpane.vue","./src/components/views/pricingview/workloadpricingpane.vue","./src/layout/tab.vue","./src/layout/typeline.vue"],"version":"5.9.3"}
|
{"root":["./src/main.ts","./src/sql.ts","./src/components/ui/button/index.ts","./src/components/ui/card/index.ts","./src/components/ui/scroll-area/index.ts","./src/components/ui/tooltip/index.ts","./src/lib/decimal.ts","./src/lib/diyaggridoptions.ts","./src/lib/number.ts","./src/lib/numberformat.ts","./src/lib/pricingmethodtotals.ts","./src/lib/pricingscalefee.ts","./src/lib/utils.ts","./src/lib/xmfactordefaults.ts","./src/lib/zwarchive.ts","./src/lib/zxfwpricingsync.ts","./src/pinia/pricingpanereload.ts","./src/pinia/tab.ts","./src/app.vue","./src/components/ui/button/button.vue","./src/components/ui/card/card.vue","./src/components/ui/card/cardaction.vue","./src/components/ui/card/cardcontent.vue","./src/components/ui/card/carddescription.vue","./src/components/ui/card/cardfooter.vue","./src/components/ui/card/cardheader.vue","./src/components/ui/card/cardtitle.vue","./src/components/ui/scroll-area/scrollarea.vue","./src/components/ui/scroll-area/scrollbar.vue","./src/components/ui/tooltip/tooltipcontent.vue","./src/components/views/contractdetailview.vue","./src/components/views/ht.vue","./src/components/views/xm.vue","./src/components/views/xmconsultcategoryfactor.vue","./src/components/views/xmfactorgrid.vue","./src/components/views/xmmajorfactor.vue","./src/components/views/zxfwview.vue","./src/components/views/htinfo.vue","./src/components/views/xminfo.vue","./src/components/views/zxfw.vue","./src/components/views/pricingview/hourlypricingpane.vue","./src/components/views/pricingview/investmentscalepricingpane.vue","./src/components/views/pricingview/landscalepricingpane.vue","./src/components/views/pricingview/workloadpricingpane.vue","./src/layout/tab.vue","./src/layout/typeline.vue"],"version":"5.9.3"}
|
||||||
@ -29,11 +29,27 @@ export default defineConfig({
|
|||||||
entryFileNames: 'static/js/[name]-[hash].js',
|
entryFileNames: 'static/js/[name]-[hash].js',
|
||||||
// 自定义 css 文件名
|
// 自定义 css 文件名
|
||||||
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
|
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
|
||||||
// 拆分第三方依赖(如 vue、axios 单独打包)
|
codeSplitting: {
|
||||||
manualChunks(id) {
|
minSize: 20 * 1024,
|
||||||
if (id.includes('node_modules')) {
|
groups: [
|
||||||
return id.toString().split('node_modules/')[1].split('/')[0].toString();
|
{
|
||||||
|
name: 'vendor-ag-grid',
|
||||||
|
test: /node_modules[\\/](ag-grid-community|ag-grid-enterprise|ag-grid-vue3|@ag-grid-community)[\\/]/,
|
||||||
|
priority: 30,
|
||||||
|
entriesAware: true,
|
||||||
|
maxSize: 450 * 1024
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'vendor-vue',
|
||||||
|
test: /node_modules[\\/](vue|pinia|@vue|pinia-plugin-persistedstate)[\\/]/,
|
||||||
|
priority: 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'vendor-ui',
|
||||||
|
test: /node_modules[\\/](reka-ui|@floating-ui|lucide-vue-next|@iconify[\\/]vue)[\\/]/,
|
||||||
|
priority: 10
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user