- fileUploadForm 첨부 시가 아닌 등록 시에 업로드 되도록 수정
- rdii 분석 오수관망도 inp 파일이 마인드원 DB에 저장되도록 수정
This commit is contained in:
swcho
2025-08-26 11:37:58 +09:00
parent 1ac7c97041
commit 2db685b533
3 changed files with 111 additions and 73 deletions
@@ -1,12 +1,12 @@
'use client'
import { postData, postMutiPart } from '@/components/lib/api'
import { postMutiPart } from '@/components/lib/api'
import FileUploadForm from '@/components/ui/fileUploadForm'
import FormSection from '@/components/ui/formSection'
import { DateMonthPicker, filePicked, downloadExcel } from '@common/business_components/ui'
import { DateMonthPicker, filePicked } from '@common/business_components/ui'
import ListDiv from '@common/business_components/ui/list_div'
import { Input, Button } from '@common/components/ui'
import { Input } from '@common/components/ui'
import { zodResolver } from '@hookform/resolvers/zod'
import { useState, useCallback } from 'react'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { z } from 'zod'
import { excelToFlowRateData, excelToMatchingResultData, excelToTimePatternData, excelToRcptrInfoData } from '@/components/lib/utils'
@@ -135,16 +135,16 @@ const IrSetting = () => {
const registFile = async (analysisData: any) => {
setIsLoadingResult(true); // 로딩 상태 시작
setIsLoadingResult(true);
console.log("Submitting combined analysis data to backend:", analysisData);
const data = await postMutiPart('v1/inftwtAnls/savewithfile', analysisData);
console.log("Response from backend:", data);
if (data) {
setIsLoadingResult(false); // 로딩 상태 시작
setIsLoadingResult(false);
alert("분석 데이터가 성공적으로 제출되었습니다.");
resetAllForms(); // 성공 시 폼 초기화 함수 호출
} else {
setIsLoadingResult(false); // 로딩 상태 시작
setIsLoadingResult(false);
alert("분석 데이터 제출 중 오류가 발생했습니다.");
}
};
@@ -327,18 +327,15 @@ const IrSetting = () => {
tbSnRcptrInfo: rcptrInfoData, // 수용가 상수사용량 (없을 수 있음)
};
console.log("통합 분석 데이터 (JSON):", jsonData);
const jsonBlob = new Blob([JSON.stringify(jsonData)], {
type: 'application/json'
});
const combinedAnalysisData = new FormData();
combinedAnalysisData.append('data', jsonBlob);
if (file1?.file) {
combinedAnalysisData.append('inpFile', file1.file);
}
if (file1?.file) combinedAnalysisData.append('inpFile', file1.file);
console.log("통합 분석 데이터 (JSON):", jsonData);
// 수정된 registFile 함수를 호출하여 combinedAnalysisData를 전송합니다.
await registFile(combinedAnalysisData);
setIsLoadingResult(false);
} catch (error) {
+25 -14
View File
@@ -1,11 +1,11 @@
"use client"
import { postData } from '@/components/lib/api'
import { postMutiPart } from '@/components/lib/api'
import FileUploadForm from "@/components/ui/fileUploadForm"
import FormSection from "@/components/ui/formSection"
import BaseLayout from "../BaseLayout"
import { DateMonthPicker, filePicked } from "@common/business_components/ui"
import { Input, Button } from "@common/components/ui"
import { Input } from "@common/components/ui"
import { zodResolver } from "@hookform/resolvers/zod"
import { Label } from '@radix-ui/react-label'
import { useState } from "react"
@@ -157,13 +157,18 @@ export default function RTKForm() {
};
const registFile = async (analysisData: any) => {
console.log("Submitting combined analysis data to backend");
// 추후 API 엔드포인트에 맞게 URL 수정 필요
const data = await postData('v1/rdiiAnls', analysisData);
setIsLoadingResult(true);
console.log("Submitting combined analysis data to backend", analysisData);
const data = await postMutiPart('v1/rdiiAnls/savewithfile', analysisData);
console.log("Response from backend:", data);
if (data) {
setIsLoadingResult(false);
alert("분석 데이터가 성공적으로 제출되었습니다.");
resetAllForms(); // 성공 시 폼 초기화 함수 호출
} else alert("분석 데이터 제출 중 오류가 발생했습니다.");
} else {
setIsLoadingResult(false);
alert("분석 데이터 제출 중 오류가 발생했습니다.");
}
};
// 침입수 분석 실행 버튼 클릭 핸들러
@@ -182,7 +187,7 @@ export default function RTKForm() {
}
const formData = form.getValues();
console.log(uploadedFilesData);
console.log('uploadedFilesData', uploadedFilesData);
const file1 = uploadedFilesData[0]; // 오수관망도
const file2 = uploadedFilesData[1]; // 수용가-맨홀 매칭결과
const file3 = uploadedFilesData[2]; // 강우자료
@@ -253,9 +258,9 @@ export default function RTKForm() {
if (!file || !file.file) return null; // fileInfo 객체 및 file 객체 null 체크
// filePicked 함수에 File 객체와 headerNum 전달
const jsonData = await filePicked(file.file, 0);
const ExcelToJsonData = await filePicked(file.file, 0);
if (jsonData === undefined) {
if (ExcelToJsonData === undefined) {
console.warn(`Warning: filePicked returned undefined for ${file.file.name}`);
return {
fileName: file.file.name,
@@ -265,9 +270,9 @@ export default function RTKForm() {
};
}
// jsonData를 각 parser 함수로 처리
// ExcelToJsonData를 각 parser 함수로 처리
// parser 함수가 filePicked가 반환하는 JSON 형식을 직접 처리한다고 가정
const parsedDataBySpecificFunction = parser(jsonData);
const parsedDataBySpecificFunction = parser(ExcelToJsonData);
return {
fileName: file.file.name,
@@ -300,7 +305,7 @@ export default function RTKForm() {
// 새로운 JSON 데이터 생성
const combinedAnalysisData = {
const jsonData = {
aplcnYm: formData.date, // 적용연월 (YYYYMM 형식)
ctpvCd: ctpvCd !== '0' ? String(ctpvCd).trim() : null, // 시도코드 (선택값)
sggCd: sggCd !== '0' ? String(sggCd) : null, // 시군구코드 (선택값)
@@ -346,9 +351,15 @@ export default function RTKForm() {
tbSnRainData: rainData, // 강우자료
};
console.log("통합 분석 데이터 (JSON):", combinedAnalysisData);
console.log("통합 분석 데이터 (JSON):", jsonData);
const jsonBlob = new Blob([JSON.stringify(jsonData)], {
type: 'application/json'
});
const combinedAnalysisData = new FormData();
combinedAnalysisData.append('data', jsonBlob);
if (file1?.file) combinedAnalysisData.append('inpFile', file1.file);
// 수정된 registFile 함수를 호출하여 combinedAnalysisData를 전송합니다.
await registFile(combinedAnalysisData);
setIsLoadingResult(false);
} catch (error) {
+76 -46
View File
@@ -41,23 +41,84 @@ const FileUploadForm = ({
const [selectedYear, setSelectedYear] = useState<string>(yearOptions[0]?.val || '');
const [selectedQuarter, setSelectedQuarter] = useState<string>(quater[0]?.val || '');
const internalHandleUploadResponse = (file: File) => async (res: HttpResponse) => {
const fileInfo = res.getHeader("X-File-Info");
if (!fileInfo) {
if (onFileSelect) onFileSelect(file, null, null);
function registFile() {
console.log(files?.[0]?.name)
if (!currentFile) {
alert('파일을 선택해주세요.');
return;
}
const { atflCd: newAtflCd, atflId: newAtflId } = JSON.parse(fileInfo) ?? {};
const orgnlFileNm = file.name;
console.log(`FileUploadForm (idx: ${fileIdx ?? 'N/A'}) - orgnlFileNm:`, orgnlFileNm, 'New AtflCd:', newAtflCd, 'New AtflId:', newAtflId);
setFileName(orgnlFileNm);
setInternalAtflCd(newAtflCd);
setInternalAtflId(newAtflId);
if (onFileSelect) {
onFileSelect(file, newAtflCd, newAtflId);
if (!selectedYear) {
alert('등록년도를 선택해주세요.');
return;
}
};
if (!selectedQuarter) {
alert('분기를 선택해주세요.');
return;
}
const fileNm = currentFile.name;
if (onSubmit && files && currentFile) {
// Promise로 handleUpload 완료를 기다림
handleUploadWithResponse(files, currentFile)
.then(({ atflCd, atflId }) => {
// 업로드 완료 후 onSubmit 실행
onSubmit(fileNm, selectedYear, selectedQuarter, atflCd || '', atflId || '');
// UI 초기화
setFiles(null);
setFileName('');
setUploaderKey(prev => prev + 1);
})
.catch((error) => {
console.error('파일 업로드 실패:', error);
alert('파일 업로드 중 오류가 발생했습니다.');
});
}
}
// handleUpload를 Promise로 감싸는 헬퍼 함수
function handleUploadWithResponse(files: FileList, file: File): Promise<{ atflCd: string | null, atflId: string | null }> {
return new Promise((resolve, reject) => {
const uploadResponseHandler = async (res: HttpResponse) => {
try {
const fileInfo = res.getHeader("X-File-Info");
if (!fileInfo) {
resolve({ atflCd: null, atflId: null });
return;
}
const { atflCd: newAtflCd, atflId: newAtflId } = JSON.parse(fileInfo) ?? {};
console.log(`FileUploadForm (idx: ${fileIdx ?? 'N/A'}) - Upload completed:`, newAtflCd, newAtflId);
// 내부 상태도 업데이트 (다른 용도로 사용할 수 있음)
setInternalAtflCd(newAtflCd);
setInternalAtflId(newAtflId);
setFileName(file.name);
if (onFileSelect) {
onFileSelect(file, newAtflCd, newAtflId);
}
// Promise 완료
resolve({ atflCd: newAtflCd, atflId: newAtflId });
} catch (error) {
reject(error);
}
};
const uploadErrorHandler = (error: Error) => {
console.error('Upload failed:', error);
reject(error);
};
// 기존 handleUpload 유틸리티 사용 (수정하지 않음)
handleUpload(files, {
handleUploadStart: setUpload,
handleSuccess: setUpload,
handleResponse: uploadResponseHandler,
});
});
}
return (
@@ -93,14 +154,6 @@ const FileUploadForm = ({
if (onFileSelect) {
onFileSelect(firstFile, internalAtflCd, internalAtflId);
}
// handleUpload(selectedFiles, {
// handleUploadStart: setUpload,
// handleSuccess: setUpload,
// // handleResponse는 tus-js-client의 Upload 인스턴스 콜백과 연동 필요
// // 여기서는 handleUpload 유틸리티가 응답을 직접 처리한다고 가정
// handleResponse: internalHandleUploadResponse(firstFile),
// });
}}
customPreview={
showPreview ? (
@@ -117,30 +170,7 @@ const FileUploadForm = ({
<Button
className="px-4 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700"
size="sm"
onClick={() => {
console.log(files?.[0]?.name)
if (!currentFile) {
alert('파일을 선택해주세요.');
return;
}
if (!selectedYear) {
alert('등록년도를 선택해주세요.');
return;
}
if (!selectedQuarter) {
alert('분기를 선택해주세요.');
return;
}
const fileNm = currentFile.name;
if (onSubmit) {
// 부모에게 전달할 때는 내부 상태인 internalAtflCd, internalAtflId 사용
onSubmit(fileNm, selectedYear, selectedQuarter, internalAtflCd || '', internalAtflId || '');
setFiles(null); // 파일 업로드 후 파일 목록 초기화
setFileName(''); // 파일명 초기화
// 파일 업로드 후 FileUploader 컴포넌트를 재마운트하기 위해 key 값 변경
setUploaderKey(prev => prev + 1);
}
}}
onClick={() => registFile()}
>
등록
</Button>