From 38537d9a118e056bab92afdce1c0b27f671cadf1 Mon Sep 17 00:00:00 2001 From: JIeunhuh Date: Mon, 19 May 2025 14:29:17 +0900 Subject: [PATCH 1/2] =?UTF-8?q?modal=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=ED=8C=9D=EC=97=85=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20api=20=EC=9E=91=EC=97=85=20=EC=9A=B0?= =?UTF-8?q?=EC=84=A0=20=EC=99=84=EB=A3=8C(=EC=B6=94=ED=9B=84=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=20=EC=B6=94=EA=B0=80=20=EC=8B=9C=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=ED=95=84=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/components/ui/modal.tsx | 10 ++-- apps/sn/app/map/components/common/index.ts | 3 +- .../app/map/components/popupComponent/Ssc.tsx | 2 +- .../components/popupComponent/sewagePump.tsx | 4 +- apps/sn/app/map/featureClickEventPopup.tsx | 54 ++++++++++++------- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/apps/sn/app/components/ui/modal.tsx b/apps/sn/app/components/ui/modal.tsx index e860ed7b9..f1dda48a6 100644 --- a/apps/sn/app/components/ui/modal.tsx +++ b/apps/sn/app/components/ui/modal.tsx @@ -7,20 +7,24 @@ interface ModalProps { title?: string; children: React.ReactNode; closeModal: () => void; + saveModal?: () => void } -const Modal: React.FC = ({ isModalOpen, setIsModalOpen, title, children, closeModal }) => { +const Modal: React.FC = ({ isModalOpen, setIsModalOpen, title, children, closeModal,saveModal }) => { return ( - - + + {title ? {title} : null} {children} +
+ {saveModal ? : null} +
diff --git a/apps/sn/app/map/components/common/index.ts b/apps/sn/app/map/components/common/index.ts index 5e2826e33..eecfd7b29 100644 --- a/apps/sn/app/map/components/common/index.ts +++ b/apps/sn/app/map/components/common/index.ts @@ -17,9 +17,10 @@ type LayerContentMap = { const layerContentMap: LayerContentMap = { // TODO: gis데이터 추가되면 추가 작업 필요 "하수처리시설": { - component: StormWaterPump, + component: SwtrmtFclt, }, "하수처리구역": { }, + "우수토실":{component: Ssc,}, "중점우수토실":{component: Ssc,}, "하수관로":{component: MsSwagePpl,}, "하수맨홀":{component: smh,}, diff --git a/apps/sn/app/map/components/popupComponent/Ssc.tsx b/apps/sn/app/map/components/popupComponent/Ssc.tsx index e085251f7..8b139de4e 100644 --- a/apps/sn/app/map/components/popupComponent/Ssc.tsx +++ b/apps/sn/app/map/components/popupComponent/Ssc.tsx @@ -5,7 +5,7 @@ import { UiTable } from '@common/business_components/ui'; import { Button, TableHead, TableRow } from '@common/components/ui'; import React from 'react' const inputColumn = [ - { id: "guyeok", title: "처리구역", type: "select", options: ["구역1", "구역2"] }, + { id: "swtrmt_zone_cd", title: "처리구역", type: "input" }, { id: "mainSscYn", title: "중점우수토실 대상여부", type: "select", options: ['Y', 'N'] }, ]; const headlist = [ diff --git a/apps/sn/app/map/components/popupComponent/sewagePump.tsx b/apps/sn/app/map/components/popupComponent/sewagePump.tsx index 9c62762d9..5776df5b2 100644 --- a/apps/sn/app/map/components/popupComponent/sewagePump.tsx +++ b/apps/sn/app/map/components/popupComponent/sewagePump.tsx @@ -1,8 +1,8 @@ import { VerticalTable } from '@/components/ui/verticalTable'; import React from 'react' const inputColumn = [ - { id: "guyeok", title: "처리구역", type: "select", options: ["구역1", "구역2"] }, - { id: "bungu", title: "배수분구", type: "input" }, + { id: "swtrmt_zone_cd", title: "처리구역", type: "select", options: ["구역1", "구역2"] }, + { id: "mltv_dtdv_nm", title: "배수분구", type: "input" }, { id: "freq", title: "설계빈도", type: "input" }, ] // 오수펌프 diff --git a/apps/sn/app/map/featureClickEventPopup.tsx b/apps/sn/app/map/featureClickEventPopup.tsx index 1932bcb14..4056f6130 100644 --- a/apps/sn/app/map/featureClickEventPopup.tsx +++ b/apps/sn/app/map/featureClickEventPopup.tsx @@ -6,6 +6,7 @@ import { SwtrmtFcltCol, SwtrmtPrcsZoneCol } from "./components/common/table"; import { useGisContext } from "@common/business_components/ui/map/Gis"; import { getData, putData } from "@/components/lib/api"; import { getLayerContentComponent } from "./components/common"; +import Modal from "@/components/ui/modal"; // TODO: const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => { const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; }; @@ -19,6 +20,7 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, const [buttonChk, setButtonChk] = useState(true) const [fetchData, setfetchData] = useState(); // api 호출여부 const contentRef = useRef(null); + const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열기 상태 // 피쳐데이터의 현재 레이어 이름 가져오는 함수 const getSelectedLayers = () => { let result = null; @@ -46,8 +48,8 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, if (featureId) { const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기 setLayerNm(selectedLayerName); // 상태 업데이트 - - const data = await getData(`v1/fclts/${featureId}`); + const layerId = featureId.split('.')[0] + const data = await getData(`v1/fclts/${featureId}?lyrTypeNm=${layerId}`); setfetchData(data) switch (selectedLayerName) { case '하수처리시설': @@ -73,6 +75,9 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, case '빗물펌프': setButtonChk(true) break; + case '하수맨홀': + setButtonChk(true) + break; default: break; } @@ -81,34 +86,46 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, } fetchData(); }, [featureId]); - // TODO: api 호출작업 필요(사용자 입력부분) + // 저장 시 모달 띄우기 + const handleSaveClick = () => { + setIsModalOpen(true); // 모달 열기 + }; + const handleModalSave = () => { + setIsModalOpen(false); // 모달 닫기 + btnClickEvent(); // 저장 이벤트 실행 + }; + const handleModalClose = () => { + setIsModalOpen(false); // 모달 닫기 + }; const btnClickEvent = async() => { const bodyData: Record = {} if (buttonChk && contentRef.current) { const inputElements = contentRef.current.querySelectorAll('input'); const selectElements = contentRef.current.querySelectorAll('select'); + // 카멜케이스 변환 함수 + const toCamelCase = (str: string) => + str.replace(/_([a-z])/g, (_, char) => char.toUpperCase()); // select 태그의 값 가져오기 selectElements.forEach((select) => { - bodyData[select.id] = select.value; + const camelCaseId = toCamelCase(select.id); + bodyData[camelCaseId] = select.value; }); // input 태그의 값 가져오기 inputElements.forEach((input) => { - bodyData[input.id] = input.value; + const camelCaseId = toCamelCase(input.id); + bodyData[camelCaseId] = input.value; }); - if (layerNm === '하수관로' || layerNm === '하수처리시설') { - bodyData['lyrTypeNm'] = 'tb_ms_swage_ppl' - } else if (layerNm === '우수토실') { - bodyData['lyrTypeNm'] = 'tb_ms_stofcbr' - } else if (layerNm === '오수펌프') { - bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' - } - else if (layerNm === '빗물펌프') { - bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' - } + if (layerNm === '하수관로') bodyData['lyrTypeNm'] = 'tb_ms_swage_ppl' + else if (layerNm === '우수토실') bodyData['lyrTypeNm'] = 'tb_ms_stofcbr' + else if (layerNm === '오수펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' + else if (layerNm === '빗물펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn' + else if(layerNm === '하수맨홀')bodyData['lyrTypeNm'] = 'tb_ms_swage_mnhl' bodyData['fid'] = featureId const data = await putData(`v1/fclts/${featureId}`, bodyData); - if(data){ - console.log('저장완료', data); + if(data.status==200){ + alert('저장되었습니다') + setTableData(data) + setfetchData(data) } } } @@ -133,10 +150,11 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, throw new Error("Function not implemented."); }}>
- {buttonChk ? : null}
+
정보를 저장하시겠습니까?
{ContentComponent && } From 427de70399e16e9a2d253ad86f5403fa1621993c Mon Sep 17 00:00:00 2001 From: yschoi Date: Tue, 20 May 2025 15:07:26 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/sn/app/oper/floodPre/page.tsx | 33 +++++++++++++++++++++++++++++- apps/sn/next.config.ts | 10 +++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/apps/sn/app/oper/floodPre/page.tsx b/apps/sn/app/oper/floodPre/page.tsx index d2c5fb848..62ecd15b8 100644 --- a/apps/sn/app/oper/floodPre/page.tsx +++ b/apps/sn/app/oper/floodPre/page.tsx @@ -11,6 +11,37 @@ const Page = () => { const [selectedDate, setSelectedDate] = useState(new Date()) const [company, setCompany] = useState('') const [pjNm, setpjNm] = useState('') + + + const handleDownload = async () => { + try { + const response = await fetch('/sn/attach-service/api/v1/download/6066b08c-2a55-438c-b8ff-2aed9739a0c6', { + method: 'GET', + }); + + if (!response.ok) { + throw new Error('파일 다운로드 실패'); + } + + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + + // 다운로드를 트리거할 가짜 태그 생성 + const link = document.createElement('a'); + link.href = url; + link.download = 'test.jpg'; // 원하는 파일명 지정 + document.body.appendChild(link); + link.click(); + + // 메모리 해제 + link.remove(); + window.URL.revokeObjectURL(url); + } catch (error) { + console.error('다운로드 중 오류 발생:', error); + } + }; + + return ( @@ -53,7 +84,7 @@ const Page = () => {

사업정보 등록현황

- +
{ }} onPageChange={function (page: number): void { diff --git a/apps/sn/next.config.ts b/apps/sn/next.config.ts index bc9505fef..12162c0a0 100644 --- a/apps/sn/next.config.ts +++ b/apps/sn/next.config.ts @@ -1,7 +1,9 @@ import type { NextConfig } from "next"; import webpack from "webpack"; -const geoserverUrl = process.env.NEXT_PUBLIC_GEOSERVER_URL?.replace(/\/$/, '') ?? ''; +const geoServerUrl = process.env.NEXT_PUBLIC_GEOSERVER_URL?.replace(/\/$/, '') ?? ''; +const cnServerUrl = process.env.NEXT_PUBLIC_SERVER_API_URL?.replace(/\/$/, '') ?? ''; + const nextConfig: NextConfig = { basePath: "/sn", @@ -46,7 +48,11 @@ const nextConfig: NextConfig = { return [ { source: '/geoserver/:hasudo*', - destination: `${geoserverUrl}/:hasudo*`, + destination: `${geoServerUrl}/:hasudo*`, + }, + { + source: '/attach-service/:path*', + destination: `${cnServerUrl}/attach-service/:path*`, }, ]; },