diff --git a/src/app/(main)/m/admin/orders/page.tsx b/src/app/(main)/m/admin/orders/page.tsx index 69f9a88..0054856 100644 --- a/src/app/(main)/m/admin/orders/page.tsx +++ b/src/app/(main)/m/admin/orders/page.tsx @@ -96,6 +96,8 @@ export default function AdminOrdersPage() { const [myUserId, setMyUserId] = useState(""); const heartbeatRef = useRef(null); const lockedOrderRef = useRef(""); // 현재 락 보유 중인 발주 id + // 최근 release 한 발주 5초간 추적 — 자동 list 갱신이 가져오는 stale me 결과를 무시하기 위함 + const recentlyReleasedRef = useRef>(new Set()); // 본인 user_id 1회 확보 useEffect(() => { @@ -104,9 +106,11 @@ export default function AdminOrdersPage() { }).catch(() => {}); }, []); - // 락 해제 헬퍼 (best-effort) + // 락 해제 헬퍼 — recentlyReleased 에 5초간 등록해서 자동 갱신의 stale 결과를 무시 const releaseLock = useCallback(async (orderObjid: string) => { if (!orderObjid) return; + recentlyReleasedRef.current.add(orderObjid); + setTimeout(() => recentlyReleasedRef.current.delete(orderObjid), 5000); try { await fetch("/api/m/admin/orders/lock", { method: "POST", headers: { "Content-Type": "application/json" }, @@ -131,18 +135,36 @@ export default function AdminOrdersPage() { }); const j = await res.json(); const list: Order[] = j.RESULTLIST ?? []; - setOrders(list); - setSelected((prev) => new Set(Array.from(prev).filter((id) => list.some((o) => o.OBJID === id)))); - if (list.length && !list.some((o) => o.OBJID === activeId)) { - setActiveId(list[0].OBJID); - } else if (!list.length) { + // 클라이언트 락 추적과 list 결과 정합화: + // - 최근 release 한 발주는 DB stale (me 로 보이는 경우) 무시 → null 처리 + // - 내가 보유 중인 발주는 me 로 보정 (혹시 누락된 경우) + const released = recentlyReleasedRef.current; + const myLocked = lockedOrderRef.current; + const adjusted: Order[] = list.map((o) => { + if (released.has(o.OBJID)) { + return { ...o, EDITING_BY: null, EDITING_BY_NAME: null }; + } + if (myLocked && o.OBJID === myLocked) { + return { + ...o, + EDITING_BY: myUserId || (o.EDITING_BY ?? "me"), + EDITING_BY_NAME: o.EDITING_BY_NAME || "(나)", + }; + } + return o; + }); + setOrders(adjusted); + setSelected((prev) => new Set(Array.from(prev).filter((id) => adjusted.some((o) => o.OBJID === id)))); + if (adjusted.length && !adjusted.some((o) => o.OBJID === activeId)) { + setActiveId(adjusted[0].OBJID); + } else if (!adjusted.length) { setActiveId(""); setDetail(null); } } finally { setLoading(false); } - }, [status, dateFrom, dateTo, keyword, activeId]); + }, [status, dateFrom, dateTo, keyword, activeId, myUserId]); // 최초 로드만 자동, 검색 조건 변경은 [조회] 버튼으로 // eslint-disable-next-line react-hooks/exhaustive-deps