feat:
- 분석 대상지역 선택 기능 구현 (API 연동) - SearchModal.tsx 주석 삭제
This commit is contained in:
@@ -53,7 +53,7 @@ type SearchFormLeftProps = {
|
||||
setRtnMiddleRegionValue?: (value: string) => void;
|
||||
setRtnEnvPartValue?: (value: string) => void;
|
||||
setRtnEnvPartSidoValue?: (value: string) => void;
|
||||
setRtnEnvPartSigunValue?: (value: string) => void;
|
||||
setRtnEnvPartSigunValue?: (value: { val: string, text: string }) => void; // setRtnEnvPartSigunValue prop 타입을 객체로 변경
|
||||
resetTrigger?: boolean;
|
||||
}
|
||||
|
||||
@@ -169,24 +169,10 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
|
||||
}
|
||||
}, [isShowPart]); // isShowPart가 변경될 때 데이터를 다시 로드
|
||||
|
||||
// 시군구 세팅 (행정구역별)
|
||||
const initializeSigunData = (sidoCd: string) => {
|
||||
if (sidoCd === '0') {
|
||||
// setSigunValue('0');
|
||||
setFilteredEnvPartSigunData([{ text: "전체", val: '0' }, ...allSigunOptions]); // 전체 시군구
|
||||
} else {
|
||||
const newFilteredData = [
|
||||
{ text: "전체", val: '0' },
|
||||
...allSigunOptions.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd)
|
||||
];
|
||||
// setSigunValue('0');
|
||||
setFilteredEnvPartSigunData(newFilteredData);
|
||||
}
|
||||
}
|
||||
|
||||
// 환경청 세팅 - 시도
|
||||
const initializeCityDataByEnvPartSido = (envPartCd: string) => {
|
||||
const foundEnvPart = allEnvPartOptions.find((item: EnvPartSelectDataType) => item.val === envPartCd);
|
||||
console.log('foundEnvPart:', foundEnvPart);
|
||||
|
||||
let relevantSidos: SelectDataType[] = []; // 기본값을 빈 배열로 설정
|
||||
let relevantSigunsForSidoDerivation: SelectDataType[] = []; // 기본값을 빈 배열로 설정
|
||||
@@ -258,18 +244,36 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
|
||||
initializeCityDataByEnvPartSido(val);
|
||||
setEnvPartSidoValue('0'); // 시도 "전체"로 초기화
|
||||
setEnvPartSigunValue('0'); // 시군구 "전체"로 초기화
|
||||
// onSelectValue(filteredEnvPartSidoData[0]?.val || '0', 'envPartSido'); // 이 부분은 setEnvPartSidoValue('0')와 initializeCityDataByEnvPartSigun('0')으로 대체됨
|
||||
// 부모에게도 초기화된 값 전달 (text 포함)
|
||||
if (setRtnEnvPartSidoValue) {
|
||||
const sidoDefault = filteredEnvPartSidoData.find(item => item.val === '0') || { val: '0', text: '전체' };
|
||||
// setRtnEnvPartSidoValue(sidoDefault.val); // 이전 방식: 값만 전달
|
||||
// TODO: 만약 시도 값도 객체로 전달해야 한다면 아래와 같이 수정
|
||||
// setRtnEnvPartSidoValue({ val: sidoDefault.val, text: sidoDefault.text });
|
||||
}
|
||||
if (setRtnEnvPartSigunValue) {
|
||||
const sigunDefault = filteredEnvPartSigunData.find(item => item.val === '0') || { val: '0', text: '전체' };
|
||||
setRtnEnvPartSigunValue({ val: sigunDefault.val, text: sigunDefault.text });
|
||||
}
|
||||
break;
|
||||
case 'envPartSido': // 환경청별 - 시도 선택
|
||||
setEnvPartSidoValue(val);
|
||||
setRtnEnvPartSidoValue?.(val);
|
||||
initializeCityDataByEnvPartSigun(val);
|
||||
setEnvPartSigunValue('0'); // 시군구 "전체"로 초기화
|
||||
// onSelectValue(filteredEnvPartSigunData[0]?.val || '0', 'envPartSigun');
|
||||
if (setRtnEnvPartSigunValue) {
|
||||
const sigunDefault = filteredEnvPartSigunData.find(item => item.val === '0') || { val: '0', text: '전체' };
|
||||
setRtnEnvPartSigunValue({ val: sigunDefault.val, text: sigunDefault.text });
|
||||
}
|
||||
break;
|
||||
case 'envPartSigun': // 환경청별 - 시군구 선택
|
||||
setEnvPartSigunValue(val);
|
||||
setRtnEnvPartSigunValue?.(val);
|
||||
const selectedSigun = filteredEnvPartSigunData.find(item => item.val === val);
|
||||
if (setRtnEnvPartSigunValue && selectedSigun) {
|
||||
setRtnEnvPartSigunValue({ val: selectedSigun.val, text: selectedSigun.text });
|
||||
} else if (setRtnEnvPartSigunValue && val === '0') { // "전체"를 명시적으로 처리 (find 실패 대비)
|
||||
setRtnEnvPartSigunValue({ val: '0', text: '전체' });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -298,7 +302,7 @@ function GovSidoSigunguSearchForm({ isShowPart = false, children, selectSidoData
|
||||
setRtnMiddleRegionValue?.('0');
|
||||
setRtnEnvPartValue?.('0');
|
||||
setRtnEnvPartSidoValue?.('0');
|
||||
setRtnEnvPartSigunValue?.('0');
|
||||
setRtnEnvPartSigunValue?.({ val: '0', text: '전체' });
|
||||
};
|
||||
|
||||
// 리셋 트리거 변경 감지
|
||||
|
||||
+125
-26
@@ -1,4 +1,5 @@
|
||||
'use client'
|
||||
import { getData } from '@/components/lib/api'
|
||||
import ContentLayout from '@/components/ui/contentLayout'
|
||||
import { GovSidoSigunguSearchForm } from '@/components/ui/govSidoSigunguSearchForm'
|
||||
import { Form, SearchFormRight, SelectBox } from '@common/business_components/ui'
|
||||
@@ -6,7 +7,7 @@ import { SidoSigunguSelectBox } from '../components/ui/SidoSigunguSelectBox'
|
||||
import { SelectBox2 } from '@common/business_components/ui/select/index-2'
|
||||
import ListDiv from '@common/business_components/ui/list_div'
|
||||
import { Button, Label } from '@common/components/ui'
|
||||
import { type ReactNode } from 'react'
|
||||
import { useEffect, useState, type ReactNode } from 'react'
|
||||
|
||||
type TitleName = {
|
||||
mainTitle: string
|
||||
@@ -24,6 +25,11 @@ type Label = {
|
||||
third: string
|
||||
fourth: string
|
||||
}
|
||||
// API로부터 받아올 데이터 타입을 정의 (SelectBox에 사용될 형태)
|
||||
interface ApiSelectOption {
|
||||
text: string;
|
||||
val: string;
|
||||
}
|
||||
type BaseLayout = {
|
||||
children?: ReactNode[]
|
||||
titleName: TitleName
|
||||
@@ -32,10 +38,16 @@ type BaseLayout = {
|
||||
graphBtn?: boolean
|
||||
firstDivBtn?: boolean
|
||||
searchBox?: SelectBox
|
||||
sido?: number
|
||||
setSido?: (sido: number) => void
|
||||
sigungu?: number
|
||||
setSigungu?: (sigungu: number) => void
|
||||
enoCd?: string | number
|
||||
setEnoCd?: (enoCd: string) => void
|
||||
ctpvCd?: string | number
|
||||
setCtpvCd?: (ctpvCd: string) => void
|
||||
sigungu?: ApiSelectOption
|
||||
setSigungu?: (sigungu: ApiSelectOption) => void
|
||||
selectedSwageTreatmentPlant?: string | number;
|
||||
onSwageTreatmentPlantChange?: (value: string | number) => void;
|
||||
selectedSwageProcessingZone?: string | number;
|
||||
onSwageProcessingZoneChange?: (value: string | number) => void;
|
||||
}
|
||||
// TODO: 나중에 이벤트 추가되면 파라미터 추가 필요 ?
|
||||
/**
|
||||
@@ -47,7 +59,106 @@ type BaseLayout = {
|
||||
* @param graphBtn : 하단에 그래프 버튼 유무 처리
|
||||
* @returns
|
||||
*/
|
||||
const BaseLayout = ({ children, titleName, form, onSubmitEvent, graphBtn = false, searchBox, sido, setSido, sigungu, setSigungu }: BaseLayout) => {
|
||||
const BaseLayout = ({
|
||||
children,
|
||||
titleName,
|
||||
form,
|
||||
onSubmitEvent,
|
||||
graphBtn = false,
|
||||
searchBox,
|
||||
enoCd,
|
||||
setEnoCd,
|
||||
ctpvCd,
|
||||
setCtpvCd,
|
||||
sigungu,
|
||||
setSigungu,
|
||||
selectedSwageTreatmentPlant,
|
||||
onSwageTreatmentPlantChange,
|
||||
selectedSwageProcessingZone,
|
||||
onSwageProcessingZoneChange,
|
||||
}: BaseLayout) => {
|
||||
|
||||
const defaultOption: ApiSelectOption = { val: '0', text: '선택' };
|
||||
|
||||
const [processingZoneOptions, setProcessingZoneOptions] = useState<ApiSelectOption[]>([]);
|
||||
const [treatmentFacilityOptions, setTreatmentFacilityOptions] = useState<ApiSelectOption[]>([]);
|
||||
const [isLoadingAreaData, setIsLoadingAreaData] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
if (!sigungu || sigungu.val === '0' || !sigungu.val) {
|
||||
console.log("BaseLayout: Skipping fetchData because sigungu.val is:", sigungu?.val);
|
||||
setProcessingZoneOptions([defaultOption]);
|
||||
setTreatmentFacilityOptions([defaultOption]);
|
||||
setIsLoadingAreaData(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoadingAreaData(true);
|
||||
try {
|
||||
const queryParamsZone = new URLSearchParams({
|
||||
lyrTypeNm: 'tb_ms_swage_prcs_zone',
|
||||
page: '0',
|
||||
size: '100000',
|
||||
sort: 'string',
|
||||
});
|
||||
const cqlFiltersZone: string[] = [];
|
||||
if (sigungu.val && sigungu.val !== '0') {
|
||||
cqlFiltersZone.push(`sgg_cd='${sigungu.val}'`);
|
||||
}
|
||||
if (cqlFiltersZone.length > 0) {
|
||||
queryParamsZone.append('cqlFiter', cqlFiltersZone.join(' and '));
|
||||
}
|
||||
|
||||
const queryParamsFacility = new URLSearchParams({
|
||||
lyrTypeNm: 'tb_il_swage_prcs_fclt',
|
||||
page: '0',
|
||||
size: '100000', // 요청하신 URL에 맞게 50으로 변경 가능
|
||||
sort: 'string',
|
||||
});
|
||||
const cqlFiltersFacility: string[] = [];
|
||||
if (sigungu.text && sigungu.val !== '0') {
|
||||
cqlFiltersFacility.push(`sgg_nm ILIKE '%${sigungu.text}%'`);
|
||||
}
|
||||
if (cqlFiltersFacility.length > 0) {
|
||||
queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and ')); // API 명세에 따라 cqlFilter 또는 cqlFiter
|
||||
}
|
||||
|
||||
console.log("BaseLayout API URL for Zones:", `v1/fclts?${queryParamsZone.toString()}`);
|
||||
console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`);
|
||||
|
||||
const [zoneRes, facilityRes] = await Promise.all([
|
||||
getData(`v1/fclts?${queryParamsZone.toString()}`),
|
||||
getData(`v1/fclts?${queryParamsFacility.toString()}`)
|
||||
]);
|
||||
|
||||
const zones = (zoneRes.data || []).map((item: any) => ({
|
||||
text: item.swtrmtZoneNm || item.name || `구역 ${item.id || item.gid || item.objectid}`,
|
||||
val: item.fid || item.id || item.gid || item.objectid
|
||||
}));
|
||||
setProcessingZoneOptions([defaultOption, ...zones]);
|
||||
console.log("BaseLayout Fetched Processing Zones:", [defaultOption, ...zones]);
|
||||
|
||||
|
||||
const facilities = (facilityRes.data || []).map((item: any) => ({
|
||||
text: item.swtrmtFcltNm || item.name || `시설 ${item.id || item.gid || item.objectid}`,
|
||||
val: item.fid || item.id || item.gid || item.objectid
|
||||
}));
|
||||
setTreatmentFacilityOptions([defaultOption, ...facilities]);
|
||||
console.log("BaseLayout Fetched Treatment Facilities:", [defaultOption, ...facilities]);
|
||||
|
||||
} catch (error) {
|
||||
console.error("BaseLayout: 지역/시설 데이터 조회 중 오류 발생:", error);
|
||||
setProcessingZoneOptions([defaultOption]);
|
||||
setTreatmentFacilityOptions([defaultOption]);
|
||||
} finally {
|
||||
setIsLoadingAreaData(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [sigungu]); // sigungu 상태가 변경될 때마다 실행
|
||||
|
||||
return (
|
||||
<ContentLayout title={titleName.mainTitle}>
|
||||
<ListDiv>
|
||||
@@ -63,27 +174,15 @@ const BaseLayout = ({ children, titleName, form, onSubmitEvent, graphBtn = false
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center w-full">
|
||||
{/* <div className="flex-1">
|
||||
<div className="grid grid-cols-8 gap-5 m-4"> */}
|
||||
{/* <SelectBox2 label={"환경청"} selectArray={[{ text: '한강 유역청', val: '1' }]} className="col-span-2" selectClass="rounded-lg bg-white truncate" onSelectValue={(val) => { }} />
|
||||
<SidoSigunguSelectBox
|
||||
className='col-span-2'
|
||||
sido={sido ?? 0}
|
||||
sigungu={sigungu ?? 0}
|
||||
onSidoChange={(sido) => {
|
||||
setSido?.(sido);
|
||||
setSigungu?.(sigungu ?? 0);
|
||||
}}
|
||||
onSigunguChange={setSigungu ?? (() => { })}
|
||||
/>
|
||||
<SelectBox2 label={"하수처리장"} selectArray={[{ text: '양평하수처리장', val: '1' }]} className="col-span-2" selectClass="rounded-lg bg-white truncate" onSelectValue={() => { }} />
|
||||
<SelectBox2 label={"하수처리구역"} selectArray={[{ text: '하수처리구역', val: '1' }]} className="col-span-2" selectClass="rounded-lg bg-white truncate" onSelectValue={() => { }} /> */}
|
||||
<GovSidoSigunguSearchForm isShowPart={true} >
|
||||
<SelectBox2 label={"하수처리장"} selectArray={[{ text: '양평하수처리장', val: '1' }]} className="col-span-2" selectClass="rounded-lg bg-white truncate" onSelectValue={() => { }} />
|
||||
<SelectBox2 label={"하수처리구역"} selectArray={[{ text: '하수처리구역', val: '1' }]} className="col-span-2" selectClass="rounded-lg bg-white truncate" onSelectValue={() => { }} />
|
||||
<GovSidoSigunguSearchForm
|
||||
isShowPart={true}
|
||||
setRtnEnvPartValue={(val) => setEnoCd?.(val)}
|
||||
setRtnEnvPartSidoValue={(val) => setCtpvCd?.(val)}
|
||||
setRtnEnvPartSigunValue={setSigungu} // 선택된 시군구 값을 받을 콜백 함수 전달
|
||||
>
|
||||
<SelectBox2 label={"하수처리장"} value={selectedSwageTreatmentPlant} selectArray={treatmentFacilityOptions} className="col-span-3" selectClass="rounded-lg bg-white truncate" onSelectValue={(val) => onSwageTreatmentPlantChange?.(val)} />
|
||||
<SelectBox2 label={"하수처리구역"} value={selectedSwageProcessingZone} selectArray={processingZoneOptions} className="col-span-3" selectClass="rounded-lg bg-white truncate" onSelectValue={(val) => onSwageProcessingZoneChange?.(val)} />
|
||||
</GovSidoSigunguSearchForm>
|
||||
{/* </div>
|
||||
</div> */}
|
||||
{searchBox?.searchChk ? <SearchFormRight><Button>조회</Button></SearchFormRight> : null}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { postData } from '@/components/lib/api'
|
||||
import FileUploadForm from '@/components/ui/fileUploadForm'
|
||||
import FormSection from '@/components/ui/formSection'
|
||||
import { filePicked, DatePicker } from '@common/business_components/ui'
|
||||
import { DatePicker, filePicked } from '@common/business_components/ui'
|
||||
import { Button, Input } from '@common/components/ui'
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { useState } from 'react'
|
||||
@@ -29,11 +29,13 @@ interface UploadedFileInfo {
|
||||
// 필요하다면 파일 이름 등 추가 정보 저장 가능
|
||||
// fileName: string;
|
||||
}
|
||||
|
||||
// 초기 파일 정보 상태
|
||||
const initialFileInfo: UploadedFileInfo = { file: null, atflCd: null, atflId: null };
|
||||
|
||||
const region: { text: string, val: number }[] = [{ text: '양평', val: 1 }, { text: '강남', val: 2 }, { text: 'test', val: 3 }];
|
||||
interface ApiSelectOption {
|
||||
text: string;
|
||||
val: string;
|
||||
}
|
||||
|
||||
const IrSetting = () => {
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
@@ -49,9 +51,6 @@ const IrSetting = () => {
|
||||
}
|
||||
})
|
||||
|
||||
// FileUploadForm에서 전달받은 파일 정보를 저장할 상태 배열
|
||||
// 각 인덱스는 FileUploadForm의 fileIdx와 매칭됨
|
||||
// 예: 0: 오수관망도, 1: 수용가-맨홀, 2: 오수량 시간패턴, 3: 유량자료
|
||||
const [uploadedFilesData, setUploadedFilesData] = useState<UploadedFileInfo[]>([
|
||||
initialFileInfo, // 0: 오수관망도
|
||||
initialFileInfo, // 1: 수용가-맨홀 매칭결과
|
||||
@@ -62,11 +61,11 @@ const IrSetting = () => {
|
||||
const [selectedDate, setSelectedDate] = useState(new Date());
|
||||
const [input1, setInput1] = useState('');
|
||||
const [input2, setInput2] = useState('');
|
||||
const [select1, setSelect1] = useState(0);
|
||||
const [select2, setSelect2] = useState(0);
|
||||
const [select3, setSelect3] = useState(0);
|
||||
const [select4, setSelect4] = useState(0);
|
||||
const [select5, setSelect5] = useState(0);
|
||||
const [select1, setSelect1] = useState('0'); // 환경청코드
|
||||
const [select2, setSelect2] = useState('0'); // 시도코드
|
||||
const [select3, setSelect3] = useState<ApiSelectOption>({ val: '0', text: '전체' }); // 시군구 상태를 객체로 변경
|
||||
const [select4, setSelect4] = useState<string | number>('0'); // 하수처리장코드
|
||||
const [select5, setSelect5] = useState<string | number>('0'); // 하수처리구역코드
|
||||
const [formResetKey, setFormResetKey] = useState(0); // FileUploadForm 리셋을 위한 key 상태
|
||||
|
||||
// 폼 초기화 함수
|
||||
@@ -89,9 +88,9 @@ const IrSetting = () => {
|
||||
setSelectedDate(new Date()); // 날짜 선택 초기화
|
||||
setInput1(''); // 입력 필드 초기화
|
||||
setInput2(''); // 입력 필드 초기화
|
||||
setSelect1(0); // 선택 필드 초기화
|
||||
setSelect2(0);
|
||||
setSelect3(0);
|
||||
setSelect1('0'); // 선택 필드 초기화
|
||||
setSelect2('0');
|
||||
setSelect3({ val: '0', text: '전체' });
|
||||
setSelect4(0);
|
||||
setSelect5(0);
|
||||
setFormResetKey(prevKey => prevKey + 1); // FileUploadForm 재마운트를 위해 key 변경
|
||||
@@ -191,11 +190,11 @@ const IrSetting = () => {
|
||||
|
||||
// 새로운 JSON 데이터 생성
|
||||
const combinedAnalysisData = {
|
||||
enoCd: "select1", // 환경청코드
|
||||
ctpvCd: "select2", // 시도코드
|
||||
sggCd: "select3", // 시군구코드
|
||||
swageTmplntCd: "select4", // 하수처리장코드
|
||||
swtrmtZoneCd: "select5", // 하수처리구역코드
|
||||
enoCd: select1.toString(), // 환경청코드
|
||||
ctpvCd: select2.toString(), // 시도코드
|
||||
sggCd: select3.val.toString(), // 시군구코드
|
||||
swageTmplntCd: select4.toString(), // 하수처리장코드
|
||||
swtrmtZoneCd: select5.toString(), // 하수처리구역코드
|
||||
aplcnYm: new Date(selectedDate).toISOString().substring(0, 7).replace("-", ""), // 적용연월
|
||||
dtrwSwtcRt: parseFloat(input1) || null, // 오수전환율 (숫자로 변환)
|
||||
anlsInfo: input2, // 분석정보
|
||||
@@ -230,10 +229,16 @@ const IrSetting = () => {
|
||||
onSubmitEvent={() => { }}
|
||||
graphBtn={false}
|
||||
searchBox={{ title: '분석 대상지역 선택' }}
|
||||
sido={select2}
|
||||
setSido={setSelect2}
|
||||
enoCd={select1}
|
||||
setEnoCd={setSelect1}
|
||||
ctpvCd={select2}
|
||||
setCtpvCd={setSelect2}
|
||||
sigungu={select3}
|
||||
setSigungu={setSelect3}>
|
||||
setSigungu={setSelect3}
|
||||
selectedSwageTreatmentPlant={select4}
|
||||
onSwageTreatmentPlantChange={setSelect4}
|
||||
selectedSwageProcessingZone={select5}
|
||||
onSwageProcessingZoneChange={setSelect5}>
|
||||
<div className="grid gap-4">
|
||||
<FormSection name='suyeongaPlace' form={form} titleNm='▷ 오수관망도'>
|
||||
<FileUploadForm
|
||||
@@ -266,25 +271,17 @@ const IrSetting = () => {
|
||||
name='inputdate'
|
||||
form={form}
|
||||
titleNm='▷ 상수사용량 적용기간'>
|
||||
{/* <DatePicker
|
||||
className="ml-5"
|
||||
selected={selectedDate}
|
||||
onSelect={(date: Date | undefined) => { if (date) setSelectedDate(date) }}
|
||||
mode={"single"} /> */}
|
||||
<DatePicker
|
||||
mode={"single"} // mode는 DayPickerSingleProps에서 오므로 그대로 사용 가능
|
||||
mode={"single"}
|
||||
field={{
|
||||
value: selectedDate, // 현재 페이지의 selectedDate 상태 사용
|
||||
onChange: (date: Date | undefined) => {
|
||||
if (date) {
|
||||
setSelectedDate(date);
|
||||
// react-hook-form의 inputdate 필드도 업데이트 (선택 사항)
|
||||
form.setValue('inputdate', date, { shouldValidate: true });
|
||||
}
|
||||
}
|
||||
}}
|
||||
// className을 직접 사용하거나, DatePicker 내부에서 selectClass를 처리하도록 수정 필요
|
||||
// 여기서는 DatePicker의 selectClass prop을 사용한다고 가정
|
||||
selectClass="ml-5 date-picker-trigger" // date-picker.css의 스타일 적용
|
||||
/>
|
||||
</FormSection>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useState } from "react"
|
||||
import { useFieldArray, useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
import { excelToMatchingResultData, excelToRainData } from '../../components/lib/utils/excelToJson'
|
||||
import { EditableFormTable, type EditableTableHeadItem } from '../../components/ui/EditableFormTable'
|
||||
import { EditableFormTable, type EditableTableHeadItem } from '../../components/ui/editableFormTable'
|
||||
|
||||
|
||||
// zod 스키마 정의
|
||||
@@ -85,6 +85,11 @@ interface UploadedFileInfo {
|
||||
// 초기 파일 정보 상태
|
||||
const initialFileInfo: UploadedFileInfo = { file: null, atflCd: null, atflId: null };
|
||||
|
||||
interface ApiSelectOption {
|
||||
text: string;
|
||||
val: string;
|
||||
}
|
||||
|
||||
export default function RTKForm() {
|
||||
const [formResetKey, setFormResetKey] = useState(0); // FileUploadForm 리셋을 위한 key 상태
|
||||
|
||||
@@ -96,6 +101,12 @@ export default function RTKForm() {
|
||||
initialFileInfo, // 2: 강우자료
|
||||
]);
|
||||
|
||||
const [select1, setSelect1] = useState('0'); // 환경청코드 (enoCd)
|
||||
const [select2, setSelect2] = useState('0'); // 시도코드 (ctpvCd)
|
||||
const [select3, setSelect3] = useState<ApiSelectOption>({ val: '0', text: '전체' }); // 시군구 (sggCd)
|
||||
const [select4, setSelect4] = useState<string | number>('0'); // 하수처리장 (swageTmplntCd)
|
||||
const [select5, setSelect5] = useState<string | number>('0'); // 하수처리구역 (swtrmtZoneCd)
|
||||
|
||||
// form 인스턴스 생성
|
||||
const form = useForm<FormSchemaType>({
|
||||
resolver: zodResolver(formSchema),
|
||||
@@ -111,6 +122,11 @@ export default function RTKForm() {
|
||||
initialFileInfo,
|
||||
]);
|
||||
setFormResetKey(prevKey => prevKey + 1); // FileUploadForm 재마운트를 위해 key 변경
|
||||
setSelect1('0');
|
||||
setSelect2('0');
|
||||
setSelect3({ val: '0', text: '전체' });
|
||||
setSelect4('0');
|
||||
setSelect5('0');
|
||||
};
|
||||
|
||||
// FileUploadForm의 onFileSelect prop으로 전달될 콜백 함수
|
||||
@@ -202,12 +218,12 @@ export default function RTKForm() {
|
||||
|
||||
// 새로운 JSON 데이터 생성
|
||||
const combinedAnalysisData = {
|
||||
enoCd: "환경청코드", // 환경청코드
|
||||
enoCd: select1.toString(), // 환경청코드
|
||||
aplcnYm: new Date(formData.date).toISOString().substring(0, 7).replace("-", ""), // 적용연월 (YYYYMM 형식)
|
||||
ctpvCd: "시도코드", // 시도코드
|
||||
sggCd: "시군구코드", // 시군구코드
|
||||
swageTmplntCd: "하수처리장코드", // 하수처리장코드
|
||||
swtrmtZoneCd: "하수처리구역코드", // 하수처리구역코드
|
||||
ctpvCd: select2.toString(), // 시도코드
|
||||
sggCd: select3.val.toString(), // 시군구코드
|
||||
swageTmplntCd: select4.toString(), // 하수처리장코드
|
||||
swtrmtZoneCd: select5.toString(), // 하수처리구역코드
|
||||
atflCd: file1?.atflCd, // 첨부파일CD (오수관망도)
|
||||
atflId: file1?.atflId, // 첨부파일ID (오수관망도)
|
||||
atflInpNm: file1?.file?.name || "", // 오수관망도 파일명
|
||||
@@ -295,7 +311,25 @@ export default function RTKForm() {
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseLayout searchBox={{ title: '분석 대상지역 선택' }} titleName={{ mainTitle: 'RDII 분석', firstCardTitle: 'RDII 분석자료 입력', secondCardTitle: '실측자료 등록' }} form={form} onSubmitEvent={() => { }} graphBtn={false} >
|
||||
// <BaseLayout searchBox={{ title: '분석 대상지역 선택' }} titleName={{ mainTitle: 'RDII 분석', firstCardTitle: 'RDII 분석자료 입력', secondCardTitle: '실측자료 등록' }} form={form} onSubmitEvent={() => { }} graphBtn={false} >
|
||||
<BaseLayout
|
||||
searchBox={{ title: '분석 대상지역 선택' }}
|
||||
titleName={{ mainTitle: 'RDII 분석', firstCardTitle: 'RDII 분석자료 입력', secondCardTitle: '실측자료 등록' }}
|
||||
form={form} // react-hook-form 인스턴스 전달
|
||||
onSubmitEvent={() => { }} // BaseLayout의 form 태그에 연결될 onSubmit
|
||||
graphBtn={false}
|
||||
// select 상태 및 핸들러 전달
|
||||
enoCd={select1}
|
||||
setEnoCd={setSelect1}
|
||||
ctpvCd={select2}
|
||||
setCtpvCd={setSelect2}
|
||||
sigungu={select3}
|
||||
setSigungu={setSelect3}
|
||||
selectedSwageTreatmentPlant={select4}
|
||||
onSwageTreatmentPlantChange={setSelect4}
|
||||
selectedSwageProcessingZone={select5}
|
||||
onSwageProcessingZoneChange={setSelect5}
|
||||
>
|
||||
{[<div className="space-y-[1.2rem] overflow-x-auto" key="form-section">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<FormSection name="rtkSource" form={form} titleNm="○ RTK계수 출처">
|
||||
|
||||
@@ -1121,8 +1121,6 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
z-[101]
|
||||
`}
|
||||
body={renderBody()}
|
||||
// headerTitle="검색"
|
||||
// 필요시 footerContent 등 추가
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user