From 05a6ee59ffe4eb5f1b259df3b7d88c42ad3d7dad Mon Sep 17 00:00:00 2001 From: Julian Freeman Date: Thu, 26 Mar 2026 13:08:47 -0400 Subject: [PATCH] fix time duration --- src/App.vue | 8 ++++++-- src/store/dashboardStore.ts | 22 +++++++++++++--------- src/store/index.ts | 24 +++++++++++++++++++++++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/App.vue b/src/App.vue index 9aa13a7..e7c1eeb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -4,7 +4,7 @@ import { load as loadStore } from "@tauri-apps/plugin-store"; import { invoke } from "@tauri-apps/api/core"; import { listen } from "@tauri-apps/api/event"; import { - RefreshCw, Calendar, ChevronLeft, ChevronRight, Play, Pause, SquarePlus, Tag as TagIcon, Download, Settings, Maximize2, X, Image as ImageIcon, BarChart2 + RefreshCw, Calendar, ChevronLeft, ChevronRight, Play, Pause, SquarePlus, Tag as TagIcon, Download, Settings, Maximize2, X, Image as ImageIcon, BarChart2, Trash2 } from "lucide-vue-next"; import { @@ -219,6 +219,10 @@ const calendarDays = computed(() => { }); const saveEvent = async () => { + if (editingEvent.value.end_minute <= editingEvent.value.start_minute) { + showToast("结束时间必须晚于开始时间", "error"); + return; + } try { await invoke("save_event", { event: editingEvent.value }); isEventModalOpen.value = false; await loadEvents(); showToast("事件已保存"); @@ -231,7 +235,7 @@ const deleteEvent = async (id: number) => { const handleQuickAddEvent = () => { let start = dayEvents.value.length ? Math.max(...dayEvents.value.map(e => e.end_minute)) : 0; - let end = currentLogicalMinute.value >= 0 ? currentLogicalMinute.value : 1439; + let end = currentLogicalMinute.value >= 0 ? currentLogicalMinute.value : Math.min(start + 30, 1439); editingEvent.value = { id: 0, date: currentDate.value, start_minute: Math.min(start, end), end_minute: end, main_tag_id: mainTags.value[0]?.id || 0, sub_tag_id: null, content: "" }; isEventModalOpen.value = true; }; diff --git a/src/store/dashboardStore.ts b/src/store/dashboardStore.ts index 6d2634d..f0c2a43 100644 --- a/src/store/dashboardStore.ts +++ b/src/store/dashboardStore.ts @@ -1,7 +1,7 @@ import { ref, computed, watch } from "vue"; import { invoke } from "@tauri-apps/api/core"; import { DBEvent } from "../types"; -import { currentDate, getTagColor, getTagName, formatMinutes } from "./index"; +import { currentDate, getTagColor, getTagName, formatMinutes, parseISODate, toISODate } from "./index"; // Re-export for easier access in Dashboard component export { getTagColor, getTagName, formatMinutes }; @@ -17,12 +17,17 @@ export const loadDashboardEvents = async () => { }; watch([dashboardRange, currentDate], () => { - const end = new Date(currentDate.value); - let start = new Date(currentDate.value); - if (dashboardRange.value === '7days') start.setDate(end.getDate() - 6); - else if (dashboardRange.value === '30days') start.setDate(end.getDate() - 29); - dashboardStartDate.value = start.toLocaleDateString('sv'); - dashboardEndDate.value = end.toLocaleDateString('sv'); + const end = parseISODate(currentDate.value); + let start = parseISODate(currentDate.value); + + if (dashboardRange.value === '7days') { + start.setDate(end.getDate() - 6); + } else if (dashboardRange.value === '30days') { + start.setDate(end.getDate() - 29); + } + + dashboardStartDate.value = toISODate(start); + dashboardEndDate.value = toISODate(end); loadDashboardEvents(); }, { immediate: true }); @@ -32,8 +37,7 @@ export const dashboardStats = computed(() => { const uniqueDays = new Set(); dashboardEvents.value.forEach(ev => { - let diff = ev.end_minute - ev.start_minute; - if (diff < 0) diff += 1440; + const diff = Math.max(0, ev.end_minute - ev.start_minute); totalMinutes += diff; uniqueDays.add(ev.date); diff --git a/src/store/index.ts b/src/store/index.ts index 730b9b1..ebdac0d 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -5,6 +5,28 @@ import { Tag, DBEvent, TimelineItem, Toast } from "../types"; export const TIME_OFFSET_MINUTES = 180; export const TOTAL_MINUTES = 1440; +// --- Date Utils (Logical Day Safe) --- +export const getLogicDateStr = (date: Date = new Date()) => { + // Subtract offset to get logic day + const d = new Date(date.getTime() - TIME_OFFSET_MINUTES * 60000); + const y = d.getFullYear(); + const m = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + return `${y}-${m}-${day}`; +}; + +export const parseISODate = (dateStr: string) => { + const [y, m, d] = dateStr.split('-').map(Number); + return new Date(y, m - 1, d, 12, 0, 0); +}; + +export const toISODate = (date: Date) => { + const y = date.getFullYear(); + const m = String(date.getMonth() + 1).padStart(2, '0'); + const d = String(date.getDate()).padStart(2, '0'); + return `${y}-${m}-${d}`; +}; + // --- Config State --- export const isSetupComplete = ref(false); export const savePath = ref(""); @@ -16,7 +38,7 @@ export const theme = ref("system"); // --- Global UI State --- export const isPaused = ref(false); -export const currentDate = ref(new Date(Date.now() - TIME_OFFSET_MINUTES * 60000).toLocaleDateString('sv')); +export const currentDate = ref(getLogicDateStr()); // Initialize with logic date export const viewMode = ref<'preview' | 'dashboard'>('preview'); export const isFullscreen = ref(false); export const previewSrc = ref("");