fix(pdf-import): 분석 중 라우팅 이탈 시 늦은 결과 적용·플랜 덮어쓰기 차단
[작업내용] : - 진행 중인 PDF 분석 요청을 pdfRunRef 로 추적, 모달 언마운트 시 AbortController.abort() 호출 - fetch 완료 후·저신뢰 confirm 후 두 지점에서 컨트롤러 동일성 가드 — 언마운트로 무효화된 늦은 결과가 비워진 canvas 에 적용되고 saveCanvas 가 이전 플랜 DB 를 outline-only 로 덮어쓰던 데이터 손실 경로 차단 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
c7757fabda
commit
29fd4cbd59
@ -107,6 +107,16 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
const [pdfAnalyzing, setPdfAnalyzing] = useState(false)
|
const [pdfAnalyzing, setPdfAnalyzing] = useState(false)
|
||||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
const pdfInputRef = useRef(null)
|
const pdfInputRef = useRef(null)
|
||||||
|
// 진행 중인 PDF 분석 요청 추적 — 언마운트(라우팅 이탈) 시 abort 하고, 늦게 도착한 결과가
|
||||||
|
// 이미 비워진 canvas 에 적용되거나 이전 플랜으로 저장되는 것을 차단한다.
|
||||||
|
const pdfRunRef = useRef(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
pdfRunRef.current?.controller?.abort()
|
||||||
|
pdfRunRef.current = null
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
/**
|
/**
|
||||||
* 치수 입력방법(복시도입력/실측값입력/도면 파일 업로드)
|
* 치수 입력방법(복시도입력/실측값입력/도면 파일 업로드)
|
||||||
*/
|
*/
|
||||||
@ -165,6 +175,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
setPdfAnalyzing(true)
|
setPdfAnalyzing(true)
|
||||||
setIsGlobalLoading(true)
|
setIsGlobalLoading(true)
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
|
pdfRunRef.current = { controller }
|
||||||
const timeoutId = setTimeout(() => controller.abort(), PDF_ANALYZE_TIMEOUT_MS)
|
const timeoutId = setTimeout(() => controller.abort(), PDF_ANALYZE_TIMEOUT_MS)
|
||||||
|
|
||||||
let response = null
|
let response = null
|
||||||
@ -188,6 +199,11 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
setIsGlobalLoading(false)
|
setIsGlobalLoading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 언마운트로 abort 됐거나 다른 실행으로 대체된 경우 — 늦은 결과를 적용하거나 알림을 띄우지 않는다.
|
||||||
|
if (pdfRunRef.current?.controller !== controller) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// alert/confirm 은 스피너 해제 후 표시한다(스피너 z-index 가 alert 보다 높아 가려지는 것 방지).
|
// alert/confirm 은 스피너 해제 후 표시한다(스피너 z-index 가 alert 보다 높아 가려지는 것 방지).
|
||||||
if (errorKey) {
|
if (errorKey) {
|
||||||
swalFire({ text: getMessage(errorKey), type: 'alert' })
|
swalFire({ text: getMessage(errorKey), type: 'alert' })
|
||||||
@ -216,6 +232,11 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
if (!proceed) return false
|
if (!proceed) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 저신뢰 confirm 대기 중 언마운트된 경우까지 커버하는 최종 가드
|
||||||
|
if (pdfRunRef.current?.controller !== controller) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const applied = await applyOuterline(payload.outerline, { unit: payload.unit || 'mm' })
|
const applied = await applyOuterline(payload.outerline, { unit: payload.unit || 'mm' })
|
||||||
if (!applied) {
|
if (!applied) {
|
||||||
swalFire({ text: getMessage('pdf.import.error.apply'), type: 'alert' })
|
swalFire({ text: getMessage('pdf.import.error.apply'), type: 'alert' })
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user