From fd801ae92a5ab943a4d8fba4ac07b3f68762a387 Mon Sep 17 00:00:00 2001 From: hx <190679152@qq.com> Date: Wed, 6 May 2026 10:46:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/device/TrajectoryDialog.vue | 37 +++++++++++++++++++ src/views/device/device/history/index.vue | 39 +++++++++++++++++++- src/views/device/device/trajectory/index.vue | 37 ++++++++++++++++++- 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/components/device/TrajectoryDialog.vue b/src/components/device/TrajectoryDialog.vue index af17af8..49651a6 100644 --- a/src/components/device/TrajectoryDialog.vue +++ b/src/components/device/TrajectoryDialog.vue @@ -32,6 +32,8 @@ :start-placeholder="$t('device.trajectory.filter.startPlaceholder')" :end-placeholder="$t('device.trajectory.filter.endPlaceholder')" :clearable="false" + :editable="false" + :picker-options="locationTimePickerOptions" unlink-panels class="trajectory-filter__picker" /> @@ -133,6 +135,7 @@ import { getDeviceTrajectory, getDeviceTrajectoryMapConfig } from "@/api/device/ import { loadAMap } from "@/utils/loadAMap"; import { loadGoogleMaps } from "@/utils/loadGoogleMaps"; import { loadLeaflet } from "@/utils/loadLeaflet"; +import { getQueryDayLimitDays } from "@/utils/queryDayLimit"; // Default map centers before trajectory points load. const AMAP_DEFAULT_CENTER = [121.4737, 31.2304]; @@ -186,6 +189,7 @@ export default { mapsApi: null, mapConfig: null, locationTimeRange: [], + queryDayLimitDays: null, viewportHeight: typeof window !== "undefined" ? window.innerHeight : 900, dialogWrapperEl: null, }; @@ -220,6 +224,11 @@ export default { tableMaxHeight() { return TRAJECTORY_TABLE_HEIGHT; }, + locationTimePickerOptions() { + return { + disabledDate: (time) => this.isDateOutOfQueryDayLimit(time), + }; + }, }, beforeDestroy() { this.unbindViewportResize(); @@ -230,6 +239,7 @@ export default { this.bindViewportResize(); this.bindDialogWrapper(); this.activePanel = "map"; + await this.loadQueryDayLimitConfig(); this.initDefaultLocationTimeRange(); if (!this.device || !this.device.id) { this.loadError = this.$t("device.trajectory.message.missingDevice"); @@ -258,6 +268,33 @@ export default { this.mapConfig = null; this.locationTimeRange = []; }, + async loadQueryDayLimitConfig() { + const limitDays = await getQueryDayLimitDays(); + this.queryDayLimitDays = Number.isFinite(limitDays) ? limitDays : null; + }, + getHistoryMinTime() { + if (!Number.isFinite(this.queryDayLimitDays) || this.queryDayLimitDays <= 0) { + return null; + } + const now = new Date(); + return new Date(now.getFullYear(), now.getMonth(), now.getDate() - this.queryDayLimitDays + 1, 0, 0, 0).getTime(); + }, + getTodayEndTime() { + const now = new Date(); + return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999).getTime(); + }, + isDateOutOfQueryDayLimit(time) { + if (!(time instanceof Date)) { + return false; + } + const minTime = this.getHistoryMinTime(); + if (minTime === null) { + return false; + } + const current = time.getTime(); + const endTime = this.getTodayEndTime(); + return current < minTime || current > endTime; + }, bindViewportResize() { this.handleViewportResize(); if (typeof window !== "undefined") { diff --git a/src/views/device/device/history/index.vue b/src/views/device/device/history/index.vue index a4b6ab0..d0cf82b 100644 --- a/src/views/device/device/history/index.vue +++ b/src/views/device/device/history/index.vue @@ -41,6 +41,8 @@ :start-placeholder="$t('device.trajectory.filter.startPlaceholder')" :end-placeholder="$t('device.trajectory.filter.endPlaceholder')" :clearable="true" + :editable="false" + :picker-options="rangePickerOptions" class="range" /> @@ -107,6 +109,7 @@