iipbs_sn / build (push) Waiting to run
- I/I 분석 LoadingBar 적용 - rdii 분석 페이지 오타 수정 및 테스트용 기본값 입력 (추후 삭제)
252 lines
10 KiB
TypeScript
252 lines
10 KiB
TypeScript
'use client'
|
|
import { deleteData, getData } from '@/components/lib/api'
|
|
import { UiTable, downloadExcel } from '@common/business_components/ui'
|
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
import { useState } from 'react'
|
|
import { useForm } from 'react-hook-form'
|
|
import { z } from 'zod'
|
|
import BaseLayout from '../BaseLayout'
|
|
|
|
|
|
const formSchema = z.object({
|
|
enoCd: z.string().default('0'), // 환경청코드
|
|
ctpvCd: z.string().default('0'), // 시도코드
|
|
sggCd: z.object({ // 시군구
|
|
val: z.string().default('0'),
|
|
text: z.string().default('전체'),
|
|
}).default({ val: '0', text: '전체' }),
|
|
swageTmplntCd: z.string().default('0'), // 하수처리장
|
|
swtrmtZoneCd: z.string().default('0'), // 하수처리구역
|
|
aplcnYm: z.date().default(new Date()), // 분석일자 (DatePicker와 연동)
|
|
})
|
|
|
|
type ResultFormValues = z.infer<typeof formSchema>
|
|
|
|
const tableColumn = [
|
|
// { id: 'no', title: '번호' },
|
|
{ id: 'inftwtAnlsSn', title: '분석번호' },
|
|
{ id: 'swageTmplntNm', title: '하수처리장' },
|
|
{ id: 'swtrmtZoneNm', title: '처리구역' },
|
|
{ id: 'aplcnYm', title: '적용연월' },
|
|
{ id: 'drtwSwtcRt', title: '오수 전환율' },
|
|
{ id: 'anlsInfo', title: '침입수 분석정보' },
|
|
{ id: 'regDt', title: '분석일자' },
|
|
{ id: 'rgtrNm', title: '분석자' }
|
|
]
|
|
|
|
const Result = () => {
|
|
const form = useForm<ResultFormValues>({
|
|
resolver: zodResolver(formSchema),
|
|
defaultValues: {
|
|
enoCd: '0',
|
|
ctpvCd: '0',
|
|
sggCd: { val: '0', text: '전체' },
|
|
swageTmplntCd: '0',
|
|
swtrmtZoneCd: '0',
|
|
aplcnYm: new Date(),
|
|
}
|
|
})
|
|
|
|
|
|
const [tableData, setTableData] = useState<any[]>([]); // API 조회 결과 저장 상태
|
|
const [totalData, setTotalData] = useState(0) //총 데이터 수
|
|
const [isLoadingResult, setIsLoadingResult] = useState<boolean>(false); // 로딩 상태
|
|
const [selectedRowData, setSelectedRowData] = useState<any>(null);
|
|
const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined);
|
|
|
|
|
|
const handleSearchButtonClick = async (customFormValues?: Partial<ResultFormValues>) => {
|
|
setIsLoadingResult(true);
|
|
const formValues = customFormValues || form.getValues(); // react-hook-form에서 현재 값 가져오기
|
|
console.log("formValues", formValues);
|
|
|
|
let inftwtAnlsSearchDto;
|
|
|
|
if (customFormValues) {
|
|
inftwtAnlsSearchDto = {
|
|
"aplcnYm": formValues.aplcnYm,
|
|
"enoCd": formValues.enoCd,
|
|
"ctpvCd": formValues.ctpvCd,
|
|
"sggCd": formValues.sggCd,
|
|
"swtrmtZoneCd": formValues.swtrmtZoneCd,
|
|
};
|
|
} else {
|
|
inftwtAnlsSearchDto = {
|
|
"aplcnYm": formValues.aplcnYm ? formValues.aplcnYm.toISOString().substring(0, 7).replace("-", "") : null,
|
|
"enoCd": formValues.enoCd === '0' ? null : formValues.enoCd,
|
|
"ctpvCd": formValues.ctpvCd === '0' ? null : formValues.ctpvCd,
|
|
"sggCd": formValues.sggCd?.val === '0' ? null : formValues.sggCd?.val,
|
|
"swtrmtZoneCd": formValues.swtrmtZoneCd === '0' ? null : formValues.swtrmtZoneCd,
|
|
};
|
|
}
|
|
console.log("Search DTO:", inftwtAnlsSearchDto);
|
|
|
|
const queryParams = new URLSearchParams({
|
|
page: '0',
|
|
size: '10',
|
|
sort: 'inftwtAnlsSn'
|
|
});
|
|
Object.entries(inftwtAnlsSearchDto).forEach(([key, value]) => {
|
|
if (value !== undefined && value !== null && String(value).trim() !== '') { // undefined, null, 빈 문자열이 아닌 경우에만 추가
|
|
queryParams.append(key, String(value));
|
|
}
|
|
});
|
|
const queryString = queryParams.toString();
|
|
|
|
console.log("API: ", `v1/inftwtAnls${queryString ? `?${queryString}` : ''}`);
|
|
try {
|
|
const data = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`);
|
|
setTableData(data.content || []);
|
|
setTotalData(tableData.length);
|
|
console.log("response:", data);
|
|
console.log("response data:", data.content || []);
|
|
setIsLoadingResult(false);
|
|
} catch (error) {
|
|
setIsLoadingResult(false);
|
|
console.error("Error fetching analysis result data:", error);
|
|
alert("분석결과 조회 중 오류가 발생했습니다.");
|
|
setTableData([]);
|
|
setTotalData(0);
|
|
}
|
|
};
|
|
|
|
// 테이블 셀 클릭 핸들러 추가
|
|
const handleCellClick = (index: number | undefined, headId: string) => {
|
|
if (index !== undefined && tableData[index]) {
|
|
setSelectedRowData(tableData[index]);
|
|
setSelectedRowIndex(index);
|
|
console.log("Selected row data:", tableData[index]);
|
|
}
|
|
};
|
|
|
|
// Excel 다운로드 핸들러 추가
|
|
const handleExcelDownload = async () => {
|
|
setIsLoadingResult(true);
|
|
console.log("Selected row data for download:", selectedRowData);
|
|
if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) {
|
|
setIsLoadingResult(false);
|
|
alert('다운로드할 데이터를 선택해주세요.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const data = await getData(`v1/inftwtAnlsRslt/ppl/${selectedRowData.inftwtAnlsSn}`);
|
|
|
|
// 선택된 행 데이터를 Excel 다운로드 형식으로 변환
|
|
const excelData = data.content; // 배열로 감싸서 전달
|
|
|
|
// 파일명 생성 (분석번호 기반)
|
|
const fileName = `침입수분석결과_${selectedRowData.inftwtAnlsSn}_${selectedRowData.aplcnYm}`;
|
|
|
|
downloadExcel({
|
|
data: excelData as JSON[],
|
|
fileName: fileName,
|
|
sheetNameArray: ["침입수 분석결과"],
|
|
headerRange: "A1:D1" // 테이블 컬럼 수에 맞춰 조정
|
|
});
|
|
setIsLoadingResult(false);
|
|
} catch (error) {
|
|
setIsLoadingResult(false);
|
|
console.error("Excel 다운로드 중 오류 발생:", error);
|
|
alert("Excel 다운로드 중 오류가 발생했습니다. 다시 시도해주세요.");
|
|
}
|
|
};
|
|
|
|
// 파일 삭제 핸들러 추가
|
|
const handleFileDelete = async () => {
|
|
setIsLoadingResult(true);
|
|
console.log("Selected row data for deletion:", selectedRowData);
|
|
if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) {
|
|
setIsLoadingResult(false);
|
|
alert('삭제할 파일을 선택해주세요.');
|
|
return;
|
|
}
|
|
// 삭제 확인 대화상자
|
|
const confirmDelete = window.confirm('선택된 분석 결과를 삭제하시겠습니까?');
|
|
if (!confirmDelete) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// 삭제 API 호출
|
|
const response1 = await deleteData(`v1/inftwtAnlsRslt/${selectedRowData.inftwtAnlsSn}`);
|
|
const response2 = await deleteData(`v1/inftwtAnls/${selectedRowData.inftwtAnlsSn}`);
|
|
console.log("File delete response1:", response1);
|
|
console.log("File delete response2:", response2);
|
|
|
|
// 삭제 후 테이블 새로고침을 위해 재검색
|
|
const customFormValues: Partial<ResultFormValues> = {
|
|
aplcnYm: selectedRowData.aplcnYm || '0',
|
|
enoCd: selectedRowData.enoCd || '0',
|
|
ctpvCd: selectedRowData.ctpvCd || '0',
|
|
sggCd: selectedRowData.sggCd || '0',
|
|
swtrmtZoneCd: selectedRowData.swtrmtZoneCd || '0',
|
|
};
|
|
await handleSearchButtonClick(customFormValues);
|
|
|
|
// 선택된 행 초기화
|
|
setSelectedRowData(null);
|
|
setSelectedRowIndex(undefined);
|
|
setIsLoadingResult(false);
|
|
|
|
alert('삭제가 완료되었습니다.');
|
|
} catch (error) {
|
|
setIsLoadingResult(false);
|
|
console.error("분석결과 파일 삭제 중 오류 발생:", error);
|
|
alert("분석결과 파일 삭제 중 오류가 발생했습니다. 다시 시도해주세요.");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<BaseLayout
|
|
selectBox={{ title: '분석 대상지역 선택', searchChk: true, onSearchClick: handleSearchButtonClick }}
|
|
titleName={{ mainTitle: '분석결과', firstCardTitle: '분석이력' }}
|
|
form={form} // form 인스턴스 전달
|
|
onSubmitEvent={() => { }} // BaseLayout의 form 태그에 연결될 onSubmit
|
|
graphBtn={true}
|
|
showDatePicker={true}
|
|
enoCd={form.watch("enoCd")}
|
|
setEnoCd={(val) => form.setValue("enoCd", val)}
|
|
ctpvCd={form.watch("ctpvCd")}
|
|
setCtpvCd={(val) => form.setValue("ctpvCd", val)}
|
|
sigungu={form.watch("sggCd")}
|
|
setSigungu={(val) => form.setValue("sggCd", val)}
|
|
selectedSwageTreatmentPlant={form.watch("swageTmplntCd")}
|
|
onSwageTreatmentPlantChange={(val) => form.setValue("swageTmplntCd", String(val))}
|
|
selectedSwageProcessingZone={form.watch("swtrmtZoneCd")}
|
|
onSwageProcessingZoneChange={(val) => form.setValue("swtrmtZoneCd", String(val))}
|
|
aplcnYm={form.watch("aplcnYm")}
|
|
setAplcnYm={(val) => {
|
|
if (val instanceof Date) {
|
|
form.setValue("aplcnYm", val)
|
|
} else if (val) {
|
|
form.setValue("aplcnYm", new Date(val))
|
|
}
|
|
}}
|
|
isLoading={isLoadingResult} // 로딩 상태 전달
|
|
// Excel 다운로드 핸들러 추가
|
|
onExcelDownload={handleExcelDownload}
|
|
onDeleteFile={handleFileDelete}
|
|
selectedRowData={selectedRowData}
|
|
>
|
|
{[<div key='table1' className="h-[55vh] flex flex-col p-4 border rounded-lg bg-white shadow-md">
|
|
<div className="mb-[1.2rem] text-xl font-medium">○ 침입수 산정결과 현황</div>
|
|
<div className="flex-grow overflow-auto">
|
|
<UiTable
|
|
headName=''
|
|
headlist={tableColumn}
|
|
tableData={tableData}
|
|
total={totalData}
|
|
pageSize={10}
|
|
children={undefined}
|
|
cellClick={handleCellClick}
|
|
onPageChange={(e) => { }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
]}
|
|
</BaseLayout>
|
|
)
|
|
}
|
|
|
|
export default Result |