diff --git a/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx b/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx index f9596613f..01503e829 100644 --- a/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx +++ b/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx @@ -2,7 +2,7 @@ import { getData } from '@/components/lib/api' import ContentLayout from '@/components/ui/contentLayout' import { GovSidoSigunguSearchForm } from '@/components/ui/govSidoSigunguSearchForm' -import { DatePicker, Form, SearchFormRight, SelectBox } from '@common/business_components/ui' +import { DatePicker, DateMonthPicker, Form, SearchFormRight, SelectBox } from '@common/business_components/ui' import ListDiv from '@common/business_components/ui/list_div' import { SelectBox2 } from '@common/business_components/ui/select/index-2' import { Button, Label } from '@common/components/ui' @@ -51,8 +51,10 @@ type BaseLayout = { onSwageTreatmentPlantChange?: (value: string | number) => void; selectedSwageProcessingZone?: string | number; onSwageProcessingZoneChange?: (value: string | number) => void; - aplcnYm?: Date - setAplcnYm?: (aplcnYm: Date | undefined) => void; + aplcnYmFrom?: string + setAplcnYmFrom?: (aplcnYmFrom: string) => void; + aplcnYmTo?: string + setAplcnYmTo?: (aplcnYmTo: string) => void; isLoading?: boolean; // Excel 다운로드 관련 props 추가 onExcelDownload?: () => void; @@ -89,8 +91,10 @@ const BaseLayout = ({ onSwageTreatmentPlantChange, selectedSwageProcessingZone, onSwageProcessingZoneChange, - aplcnYm, - setAplcnYm, + aplcnYmFrom, + setAplcnYmFrom, + aplcnYmTo, + setAplcnYmTo, isLoading, // Excel 다운로드 관련 props 추가 onExcelDownload, @@ -216,13 +220,37 @@ const BaseLayout = ({ {showDatePicker && ( // showDatePicker 값에 따라 DatePicker 렌더링 <> - console.log("DatePicker onChange:", date)) + value: aplcnYmFrom || (() => { // aplcnYm이 없으면 현재 연월을 기본값으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), // yyyyMM 형식 + onChange: (value: string) => { + setAplcnYmFrom?.(value); // string 값을 직접 전달 + } }} - selectClass="ml-5 date-picker-trigger" /> + selectClass="ml-5 w-[100px]" + startYear={1900} // 시작 연도 설정 + /> + ~ + { // aplcnYm이 없으면 현재 연월을 기본값으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), // yyyyMM 형식 + onChange: (value: string) => { + setAplcnYmTo?.(value); // string 값을 직접 전달 + } + }} + selectClass="ml-5 w-[100px]" + startYear={1900} // 시작 연도 설정 + /> )} { initialFileInfo // 3: 유량자료 등록 ]); - const [selectedDate, setSelectedDate] = useState(new Date()); + // selectedDate를 yyyyMM 문자열 형식으로 변경 + const [selectedDate, setSelectedDate] = useState(() => { + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + }); const [input1, setInput1] = useState(''); const [input2, setInput2] = useState(''); const [select1, setSelect1] = useState('0'); // 환경청코드 @@ -87,7 +93,11 @@ const IrSetting = () => { initialFileInfo, initialFileInfo ]); - setSelectedDate(new Date()); // 날짜 선택 초기화 + // selectedDate를 현재 연월로 초기화 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + setSelectedDate(`${year}${month}`); setInput1(''); // 입력 필드 초기화 setInput2(''); // 입력 필드 초기화 setSelect1('0'); // 선택 필드 초기화 @@ -138,22 +148,6 @@ const IrSetting = () => { const handleAnalysisClick = async () => { setIsLoadingResult(true); // 로딩 상태 시작 - // 오수전환율 값 0 ~ 1 사이인지 검증 - if (input1 === '' || input1 === null || input1 === undefined) { - setIsLoadingResult(false); - console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); - alert('오수전환율을 입력해주세요.'); - return; - } - - const numericInput1 = parseFloat(input1); - if (isNaN(numericInput1) || numericInput1 < 0 || numericInput1 > 1) { - setIsLoadingResult(false); - console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); - alert('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); - return; - } - console.log(uploadedFilesData); const file1 = uploadedFilesData[0]; // 오수관망도 const file2 = uploadedFilesData[1]; // 수용가-맨홀 매칭결과 @@ -173,6 +167,22 @@ const IrSetting = () => { return; } + // 오수전환율 값 0 ~ 1 사이인지 검증 + if (input1 === '' || input1 === null || input1 === undefined) { + setIsLoadingResult(false); + console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); + alert('오수전환율을 입력해주세요.'); + return; + } + + const numericInput1 = parseFloat(input1); + if (isNaN(numericInput1) || numericInput1 < 0 || numericInput1 > 1) { + setIsLoadingResult(false); + console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); + alert('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); + return; + } + type MatchingResult = { anlsSn: number; mhlMngNo: string; rcptrNo: string; }; type TimePattern = { hrId: number; rt?: number | null | undefined; }; type FlowRate = { pplMngNo: string; mtrngDt: string; oilq?: number | null | undefined; }; @@ -236,7 +246,7 @@ const IrSetting = () => { swtrmtZoneCd: (select5 && select5 !== '0' && select5 !== 0) ? select5.toString().split('.').pop() || null // '.'으로 split해서 마지막 부분만 사용 : null, // 하수처리구역코드 (선택값) - aplcnYm: new Date(selectedDate).toISOString().substring(0, 7).replace("-", ""), // 적용연월 + aplcnYm: selectedDate, // 적용연월 drtwSwtcRt: parseFloat(input1) || null, // 오수전환율 (숫자로 변환) anlsInfo: input2, // 분석정보 atflCd: file1?.atflCd, // 첨부파일CD (오수관망도) @@ -318,18 +328,15 @@ const IrSetting = () => { form={form} titleNm='▷ 상수사용량 적용월'> {/* 연월 선택 라이브러리로 수정 필요 */} - { - if (date) { - setSelectedDate(date); - form.setValue('inputdate', date, { shouldValidate: true }); - } + value: selectedDate, // yyyyMM 형식 + onChange: (value: string) => { + setSelectedDate(value); } }} - selectClass="ml-5 date-picker-trigger" // date-picker.css의 스타일 적용 + selectClass="ml-5 w-[150px]" + startYear={1900} // 시작 연도 설정 /> { // 현재 연월을 yyyyMM 형식으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), }; // 각 파일 업로드 폼의 데이터를 저장할 인터페이스 정의 @@ -108,7 +113,6 @@ export default function RTKForm() { const [select4, setSelect4] = useState('0'); // 하수처리장 (swageTmplntCd) const [select5, setSelect5] = useState('0'); // 하수처리구역 (swtrmtZoneCd) - // form 인스턴스 생성 const form = useForm({ resolver: zodResolver(formSchema), @@ -163,23 +167,6 @@ export default function RTKForm() { // 침입수 분석 실행 버튼 클릭 핸들러 const handleAnalysisClick = async () => { setIsLoadingResult(true); // 로딩 상태 시작 - - // 오수전환율 값 0 ~ 1 사이인지 검증 - const rateValue = form.getValues().rate; - if (rateValue === '' || rateValue === null || rateValue === undefined) { - setIsLoadingResult(false); - console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); - alert('오수전환율을 입력해주세요.'); - return; - } - - const numericInput1 = parseFloat(rateValue); - if (isNaN(numericInput1) || numericInput1 < 0 || numericInput1 > 1) { - setIsLoadingResult(false); - console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); - alert('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); - return; - } const formData = form.getValues(); console.log(uploadedFilesData); @@ -198,6 +185,23 @@ export default function RTKForm() { return; } + // 오수전환율 값 0 ~ 1 사이인지 검증 + const rateValue = form.getValues().rate; + if (rateValue === '' || rateValue === null || rateValue === undefined) { + setIsLoadingResult(false); + console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); + alert('오수전환율을 입력해주세요.'); + return; + } + + const numericInput1 = parseFloat(rateValue); + if (isNaN(numericInput1) || numericInput1 < 0 || numericInput1 > 1) { + setIsLoadingResult(false); + console.error('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); + alert('오수전환율은 0에서 1 사이의 값으로 입력해야 합니다.'); + return; + } + const filePickers = [ { file: file2, parser: excelToMatchingResultData }, { file: file3, parser: excelToRainData }, @@ -241,7 +245,7 @@ export default function RTKForm() { // 새로운 JSON 데이터 생성 const combinedAnalysisData = { enoCd: (select1 && select1 !== '0') ? select1.toString() : null, // 환경청코드 (선택값) - aplcnYm: new Date(formData.date).toISOString().substring(0, 7).replace("-", ""), // 적용연월 (YYYYMM 형식) + aplcnYm: formData.date, // 적용연월 (YYYYMM 형식) ctpvCd: (select2 && select2 !== '0') ? select2.toString() : null, // 시도코드 (선택값) sggCd: (select3.val && select3.val !== '0') ? select3.val.toString() : null, // 시군구코드 (선택값) swageTmplntCd: (select4 && select4 !== '0' && select4 !== 0) @@ -448,30 +452,15 @@ export default function RTKForm() { /> - {/* 연월 선택 라이브러리로 수정 필요 */} - {/* { - if (date) { - form.setValue("date", date, { shouldValidate: true }); - } - }} - mode={"single"} - className="ml-5" - /> */} - { - if (date) { - form.setValue("date", date, { shouldValidate: true }); - } + value: form.watch("date"), // form의 date 값을 직접 사용 + onChange: (value: string) => { + form.setValue("date", value, { shouldValidate: true }); // form의 date 필드에 직접 설정 } }} - // className을 직접 사용하거나, DatePicker 내부에서 selectClass를 처리하도록 수정 필요 - // 여기서는 DatePicker의 selectClass prop을 사용하고, date-picker.css의 스타일을 적용 - selectClass="ml-5 date-picker-trigger" + selectClass="ml-5 w-[200px]" + startYear={1900} // 시작 연도 설정 /> diff --git a/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx b/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx index f2390cc83..1cf78f6f2 100644 --- a/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx @@ -18,7 +18,18 @@ const formSchema = z.object({ }).default({ val: '0', text: '전체' }), swageTmplntCd: z.string().default('0'), // 하수처리장 swtrmtZoneCd: z.string().default('0'), // 하수처리구역 - aplcnYm: z.date().default(new Date()), // 분석일자 (DatePicker와 연동) + aplcnYmFrom: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + }), // 분석기간 시작연월 + aplcnYmTo: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + }), // 분석기간 종료연월 }) type ResultFormValues = z.infer @@ -49,7 +60,18 @@ const Result = () => { sggCd: { val: '0', text: '전체' }, swageTmplntCd: '0', swtrmtZoneCd: '0', - aplcnYm: new Date(), + aplcnYmFrom: (() => { // 현재 연월을 yyyyMM 형식으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), + aplcnYmTo: (() => { // 현재 연월을 yyyyMM 형식으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), } }) @@ -71,7 +93,8 @@ const Result = () => { if (customFormValues) { inftwtAnlsSearchDto = { - "aplcnYm": formValues.aplcnYm, + "aplcnYmFrom": formValues.aplcnYmFrom, + "aplcnYmTo": formValues.aplcnYmTo, "enoCd": formValues.enoCd, "ctpvCd": formValues.ctpvCd, "sggCd": formValues.sggCd, @@ -79,7 +102,8 @@ const Result = () => { }; } else { inftwtAnlsSearchDto = { - "aplcnYm": formValues.aplcnYm ? formValues.aplcnYm.toISOString().substring(0, 7).replace("-", "") : null, + "aplcnYmFrom": formValues.aplcnYmFrom && formValues.aplcnYmFrom !== '' ? formValues.aplcnYmFrom : null, + "aplcnYmTo": formValues.aplcnYmTo && formValues.aplcnYmTo !== '' ? formValues.aplcnYmTo : null, "enoCd": formValues.enoCd === '0' ? null : formValues.enoCd, "ctpvCd": formValues.ctpvCd === '0' ? null : formValues.ctpvCd, "sggCd": formValues.sggCd?.val === '0' ? null : formValues.sggCd?.val, @@ -208,7 +232,8 @@ const Result = () => { // 삭제 후 테이블 새로고침을 위해 재검색 const customFormValues: Partial = { - aplcnYm: selectedRowData.aplcnYm || null, + aplcnYmFrom: selectedRowData.aplcnYmFrom || null, + aplcnYmTo: selectedRowData.aplcnYmTo || null, enoCd: selectedRowData.enoCd || null, ctpvCd: selectedRowData.ctpvCd || null, sggCd: selectedRowData.sggCd || null, @@ -251,14 +276,10 @@ const Result = () => { 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)) - } - }} + aplcnYmFrom={form.watch("aplcnYmFrom")} + setAplcnYmFrom={(val: string) => {form.setValue("aplcnYmFrom", val)}} + aplcnYmTo={form.watch("aplcnYmTo")} + setAplcnYmTo={(val: string) => {form.setValue("aplcnYmTo", val)}} isLoading={isLoadingResult} // Excel 다운로드 핸들러 추가 onExcelDownload={handleExcelDownload} diff --git a/apps/sn/app/(with-base-layout)/ii/result/page.tsx b/apps/sn/app/(with-base-layout)/ii/result/page.tsx index b35cd5f21..98440398a 100644 --- a/apps/sn/app/(with-base-layout)/ii/result/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/result/page.tsx @@ -18,7 +18,18 @@ const formSchema = z.object({ }).default({ val: '0', text: '전체' }), swageTmplntCd: z.string().default('0'), // 하수처리장 swtrmtZoneCd: z.string().default('0'), // 하수처리구역 - aplcnYm: z.date().default(new Date()), // 분석일자 (DatePicker와 연동) + aplcnYmFrom: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + }), // 분석기간 시작연월 + aplcnYmTo: z.string().default(() => { // Date에서 string(yyyyMM 형식)으로 변경 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + }), // 분석기간 종료연월 }) type ResultFormValues = z.infer @@ -47,7 +58,18 @@ const Result = () => { sggCd: { val: '0', text: '전체' }, swageTmplntCd: '0', swtrmtZoneCd: '0', - aplcnYm: new Date(), + aplcnYmFrom: (() => { // 현재 연월을 yyyyMM 형식으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), + aplcnYmTo: (() => { // 현재 연월을 yyyyMM 형식으로 설정 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + return `${year}${month}`; + })(), } }) @@ -69,7 +91,8 @@ const Result = () => { if (customFormValues) { inftwtAnlsSearchDto = { - "aplcnYm": formValues.aplcnYm, + "aplcnYmFrom": formValues.aplcnYmFrom, + "aplcnYmTo": formValues.aplcnYmTo, "enoCd": formValues.enoCd, "ctpvCd": formValues.ctpvCd, "sggCd": formValues.sggCd, @@ -77,7 +100,8 @@ const Result = () => { }; } else { inftwtAnlsSearchDto = { - "aplcnYm": formValues.aplcnYm ? formValues.aplcnYm.toISOString().substring(0, 7).replace("-", "") : null, + "aplcnYmFrom": formValues.aplcnYmFrom && formValues.aplcnYmFrom !== '' ? formValues.aplcnYmFrom : null, + "aplcnYmTo": formValues.aplcnYmTo && formValues.aplcnYmTo !== '' ? formValues.aplcnYmTo : null, "enoCd": formValues.enoCd === '0' ? null : formValues.enoCd, "ctpvCd": formValues.ctpvCd === '0' ? null : formValues.ctpvCd, "sggCd": formValues.sggCd?.val === '0' ? null : formValues.sggCd?.val, @@ -208,7 +232,8 @@ const Result = () => { // 삭제 후 테이블 새로고침을 위해 재검색 const customFormValues: Partial = { - aplcnYm: selectedRowData.aplcnYm || null, + aplcnYmFrom: selectedRowData.aplcnYmFrom || null, + aplcnYmTo: selectedRowData.aplcnYmTo || null, enoCd: selectedRowData.enoCd || null, ctpvCd: selectedRowData.ctpvCd || null, sggCd: selectedRowData.sggCd || null, @@ -251,14 +276,10 @@ const Result = () => { 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)) - } - }} + aplcnYmFrom={form.watch("aplcnYmFrom")} + setAplcnYmFrom={(val: string) => {form.setValue("aplcnYmFrom", val)}} + aplcnYmTo={form.watch("aplcnYmTo")} + setAplcnYmTo={(val: string) => {form.setValue("aplcnYmTo", val)}} isLoading={isLoadingResult} // 로딩 상태 전달 // Excel 다운로드 핸들러 추가 onExcelDownload={handleExcelDownload}