feat: RDII 분석결과 화면 구현
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
'use client'
|
||||
import { getData, deleteData } 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: 'analysis no', title: '분석번호' },
|
||||
{ id: 'hasu', title: '하수처리장' },
|
||||
{ id: 'guyeok', title: '처리구역' },
|
||||
{ id: 'sangsu', title: '상수 사용량' },
|
||||
{ id: 'rate', title: '오수 전환율' },
|
||||
{ id: 'rtx', title: 'RTX 계수 출처' },
|
||||
{ id: 'rdii', title: 'RDII 기여면적' },
|
||||
{ id: 'rdii analysis info', title: 'RDII 분석정보' },
|
||||
{ id: 'date', title: '분석일자' },
|
||||
{ id: 'usr', 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/rdiiAnls${queryString ? `?${queryString}` : ''}`);
|
||||
try {
|
||||
const data = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`);
|
||||
setTableData(data.content || []);
|
||||
setTotalData(tableData.length);
|
||||
console.log("response:", data);
|
||||
console.log("response data:", data.content || []);
|
||||
} catch (error) {
|
||||
console.error("Error fetching analysis result data:", error);
|
||||
alert("분석결과 조회 중 오류가 발생했습니다.");
|
||||
setTableData([]);
|
||||
setTotalData(0);
|
||||
} finally {
|
||||
setIsLoadingResult(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 테이블 셀 클릭 핸들러 추가
|
||||
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 () => {
|
||||
console.log("Selected row data for download:", selectedRowData);
|
||||
if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) {
|
||||
alert('다운로드할 데이터를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await getData(`v1/rdiiAnlsRslt/ppl/${selectedRowData.inftwtAnlsSn}`);
|
||||
|
||||
// 선택된 행 데이터를 Excel 다운로드 형식으로 변환
|
||||
const excelData = data.content; // 배열로 감싸서 전달
|
||||
|
||||
// 파일명 생성 (분석번호 기반)
|
||||
const fileName = `RDII분석결과_${selectedRowData.inftwtAnlsSn}_${selectedRowData.aplcnYm}`;
|
||||
|
||||
downloadExcel({
|
||||
data: excelData as JSON[],
|
||||
fileName: fileName,
|
||||
sheetNameArray: ["RDII 분석결과"],
|
||||
headerRange: "A1:D1" // 테이블 컬럼 수에 맞춰 조정
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Excel 다운로드 중 오류 발생:", error);
|
||||
alert("Excel 다운로드 중 오류가 발생했습니다. 다시 시도해주세요.");
|
||||
}
|
||||
};
|
||||
|
||||
// 파일 삭제 핸들러 추가
|
||||
const handleFileDelete = async () => {
|
||||
console.log("Selected row data for deletion:", selectedRowData);
|
||||
if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) {
|
||||
alert('삭제할 파일을 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
// 삭제 확인 대화상자
|
||||
const confirmDelete = window.confirm('선택된 분석 결과를 삭제하시겠습니까?');
|
||||
if (!confirmDelete) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 삭제 API 호출
|
||||
const response1 = await deleteData(`v1/rdiiAnlsRslt/${selectedRowData.inftwtAnlsSn}`);
|
||||
const response2 = await deleteData(`v1/rdiiAnls/${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);
|
||||
|
||||
alert('삭제가 완료되었습니다.');
|
||||
} catch (error) {
|
||||
console.error("분석결과 파일 삭제 중 오류 발생:", error);
|
||||
alert("분석결과 파일 삭제 중 오류가 발생했습니다. 다시 시도해주세요.");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseLayout
|
||||
selectBox={{ title: '분석 대상지역 선택', searchChk: true, onSearchClick: handleSearchButtonClick }}
|
||||
titleName={{ mainTitle: '분석결과', firstCardTitle: 'RDII 산정결과 현황' }}
|
||||
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))
|
||||
}
|
||||
}}
|
||||
// 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">○ RDII 분석결과 현황</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
|
||||
@@ -7,10 +7,6 @@ import { useForm } from 'react-hook-form'
|
||||
import { z } from 'zod'
|
||||
import BaseLayout from '../BaseLayout'
|
||||
|
||||
interface ApiSelectOption {
|
||||
text: string;
|
||||
val: string;
|
||||
}
|
||||
|
||||
const formSchema = z.object({
|
||||
enoCd: z.string().default('0'), // 환경청코드
|
||||
@@ -37,19 +33,6 @@ const tableColumn = [
|
||||
{ id: 'regDt', title: '분석일자' },
|
||||
{ id: 'rgtrNm', title: '분석자' }
|
||||
]
|
||||
const tableColumn2 = [
|
||||
{ id: 'no', title: '번호' },
|
||||
{ id: 'analysis no', title: '분석번호' },
|
||||
{ id: 'hasu', title: '하수처리장' },
|
||||
{ id: 'guyeok', title: '처리구역' },
|
||||
{ id: 'sangsu', title: '상수 사용량' },
|
||||
{ id: 'rate', title: '오수 전환율' },
|
||||
{ id: 'rtx', title: 'RTX 계수 출처' },
|
||||
{ id: 'rdii', title: 'RDII 기여면적' },
|
||||
{ id: 'rdii analysis info', title: 'RDII 분석정보' },
|
||||
{ id: 'date', title: '분석일자' },
|
||||
{ id: 'usr', title: '분석자' }
|
||||
]
|
||||
|
||||
const Result = () => {
|
||||
const form = useForm<ResultFormValues>({
|
||||
@@ -151,7 +134,6 @@ const Result = () => {
|
||||
const excelData = data.content; // 배열로 감싸서 전달
|
||||
|
||||
// 파일명 생성 (분석번호 기반)
|
||||
const formValues = form.getValues();
|
||||
const fileName = `침입수분석결과_${selectedRowData.inftwtAnlsSn}_${selectedRowData.aplcnYm}`;
|
||||
|
||||
downloadExcel({
|
||||
@@ -210,7 +192,7 @@ const Result = () => {
|
||||
return (
|
||||
<BaseLayout
|
||||
selectBox={{ title: '분석 대상지역 선택', searchChk: true, onSearchClick: handleSearchButtonClick }}
|
||||
titleName={{ mainTitle: '분석결과', firstCardTitle: '분석이력', secondCardTitle: 'RDII 산정결과 현황' }}
|
||||
titleName={{ mainTitle: '분석결과', firstCardTitle: '분석이력' }}
|
||||
form={form} // form 인스턴스 전달
|
||||
onSubmitEvent={() => { }} // BaseLayout의 form 태그에 연결될 onSubmit
|
||||
graphBtn={true}
|
||||
@@ -252,19 +234,7 @@ const Result = () => {
|
||||
onPageChange={(e) => { }}
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
// <div key='table2'>
|
||||
// <UiTable
|
||||
// headName=''
|
||||
// headlist={tableColumn2}
|
||||
// tableData={rdiiResultData}
|
||||
// total={rdiiResultData.length}
|
||||
// pageSize={10}
|
||||
// children={undefined}
|
||||
// cellClick={(e) => { }}
|
||||
// onPageChange={(e) => { }}
|
||||
// />
|
||||
// </div>
|
||||
</div>
|
||||
]}
|
||||
</BaseLayout>
|
||||
)
|
||||
|
||||
@@ -20,7 +20,8 @@ export default function Home() {
|
||||
<div className="flex flex-row gap-4 p-4">
|
||||
<Link href={"/ii/irsetting"}><Button>침입수 분석</Button></Link>
|
||||
<Link href={"/ii/rdii"}><Button>RDII 분석</Button></Link>
|
||||
<Link href={"/ii/result"}><Button>분석결과</Button></Link>
|
||||
<Link href={"/ii/result"}><Button>침입수 분석 결과</Button></Link>
|
||||
<Link href={"/ii/rdii_result"}><Button>RDII 분석 결과</Button></Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user