diff --git a/backend/src/plugins/tracker.js b/backend/src/plugins/tracker.js index 71e61d0..9074621 100644 --- a/backend/src/plugins/tracker.js +++ b/backend/src/plugins/tracker.js @@ -66,17 +66,25 @@ async function trackerPlugin(fastify) { return null; } - // 이벤트 정리 - const events = (trackInfo.events?.edges || []).map((edge) => { - const node = edge.node; - return { - status: node.status?.code || 'UNKNOWN', - statusName: node.status?.name || '', - description: node.description || '', - location: node.location?.name || '', - time: node.time || null, - }; - }); + // 이벤트 정리 (한진택배 테이블 헤더 필터링) + const events = (trackInfo.events?.edges || []) + .map((edge) => { + const node = edge.node; + return { + status: node.status?.code || 'UNKNOWN', + statusName: node.status?.name || '', + description: node.description || '', + location: node.location?.name || '', + time: node.time || null, + }; + }) + .filter((event) => { + if (event.status === 'UNKNOWN' && + (event.description === '배송 진행상황' || event.location === '상품위치')) { + return false; + } + return true; + }); // 마지막 이벤트 const lastEvent = trackInfo.lastEvent diff --git a/backend/src/routes/parcels.js b/backend/src/routes/parcels.js index 843c0e9..95c6b76 100644 --- a/backend/src/routes/parcels.js +++ b/backend/src/routes/parcels.js @@ -198,7 +198,9 @@ function toMysqlDatetime(isoString) { if (!isoString) return null; const d = new Date(isoString); if (isNaN(d.getTime())) return null; - return d.toISOString().slice(0, 19).replace('T', ' '); + // KST(+09:00) 기준으로 변환 + const kst = new Date(d.getTime() + 9 * 60 * 60 * 1000); + return kst.toISOString().slice(0, 19).replace('T', ' '); } async function refreshParcel(fastify, parcelId) { diff --git a/backend/src/services/cron.js b/backend/src/services/cron.js index 3314604..c4a799d 100644 --- a/backend/src/services/cron.js +++ b/backend/src/services/cron.js @@ -4,7 +4,9 @@ function toMysqlDatetime(isoString) { if (!isoString) return null; const d = new Date(isoString); if (isNaN(d.getTime())) return null; - return d.toISOString().slice(0, 19).replace('T', ' '); + // KST(+09:00) 기준으로 변환 + const kst = new Date(d.getTime() + 9 * 60 * 60 * 1000); + return kst.toISOString().slice(0, 19).replace('T', ' '); } export function startCronJobs(fastify) { diff --git a/frontend/src/components/ParcelDialog.jsx b/frontend/src/components/ParcelDialog.jsx index db9dc48..3aa05c3 100644 --- a/frontend/src/components/ParcelDialog.jsx +++ b/frontend/src/components/ParcelDialog.jsx @@ -1,7 +1,7 @@ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { AnimatePresence, motion } from "framer-motion"; import { X, Trash2, RefreshCw, Pencil, Check, Loader2, Copy } from "lucide-react"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import useToastStore from "@/stores/useToastStore"; import dayjs from "dayjs"; import { @@ -20,6 +20,12 @@ function ParcelDialog({ parcelId, onClose }) { const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const showToast = useToastStore((s) => s.show); + useEffect(() => { + setEditing(false); + setEditLabel(""); + setShowDeleteConfirm(false); + }, [parcelId]); + const { data: parcel, isLoading } = useQuery({ queryKey: ["parcel", parcelId], queryFn: () => fetchParcel(parcelId), @@ -114,7 +120,7 @@ function ParcelDialog({ parcelId, onClose }) { type="text" value={editLabel} onChange={(e) => setEditLabel(e.target.value)} - className="h-full border-0 border-b-2 border-primary bg-transparent px-0 text-lg lg:text-xl font-semibold text-gray-900 flex-1 focus:outline-none focus:border-primary-dark placeholder:text-gray-300" + className="h-full border-0 border-b-2 border-primary bg-transparent px-0 text-lg lg:text-xl font-semibold text-gray-900 flex-1 min-w-0 focus:outline-none focus:border-primary-dark placeholder:text-gray-300" placeholder="별칭을 입력하세요" autoFocus onKeyDown={(e) =>