From 2611f304d9e442579fdeb76e879b379381c70fc1 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Wed, 27 Aug 2025 13:45:13 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EB=8C=80=EB=AF=BC=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=ED=94=BC=EC=BB=A4=EB=A5=BC=20input=20date=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD(=ED=96=A5=ED=9B=84=20=EB=82=A0=EC=A7=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/components/ui/common/utils/utils.ts | 38 ++++++++++++++++++- .../ui/sdmInfoInsertForm/component.tsx | 38 ++++++++++++------- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/apps/dm/components/ui/common/utils/utils.ts b/apps/dm/components/ui/common/utils/utils.ts index f66437553..19c92bff2 100644 --- a/apps/dm/components/ui/common/utils/utils.ts +++ b/apps/dm/components/ui/common/utils/utils.ts @@ -15,4 +15,40 @@ export const sanitizeInput = (val: string, allowDecimal = false) => { // 정수만 허용 return val.replace(/[^0-9]/g, ""); -}; \ No newline at end of file +}; + + + +// utils: format Date <-> "YYYY-MM-DD" without moment +export const formatDateToYMD=(value: Date): string => { + if (!value) return ""; + // value can be Date | string ("YYYY-MM-DD") + if (typeof value === "string") { + // assume already in yyyy-mm-dd + if (/^\d{4}-\d{2}-\d{2}$/.test(value)) return value; + const d = new Date(value); + if (isNaN(d.getTime())) return ""; + return toYMD(d); + } + if (value instanceof Date) { + if (isNaN(value.getTime())) return ""; + return toYMD(value); + } + return ""; +} + +const toYMD=(date: Date): string => { + // avoid timezone shift by normalizing to local date parts + const y = date.getFullYear(); + const m = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + return `${y}-${m}-${day}`; +} + +// const parseYMDToDate=(ymd: string): Date | null => { +// if (!/^\d{4}-\d{2}-\d{2}$/.test(ymd)) return null; +// const [y, m, d] = ymd.split("-").map(Number); +// const date = new Date(y, (m - 1), d); +// // validate round-trip +// return (date.getFullYear() === y && date.getMonth() === m - 1 && date.getDate() === d) ? date : null; +// } \ No newline at end of file diff --git a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx index 69514da41..7c6c13b32 100644 --- a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx +++ b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx @@ -2,7 +2,7 @@ import ModalSimilarPage from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/mod import { useDmStore } from "@/app/store"; import { CANDIDATE, - DatePicker, + // DatePicker, FormField, FormLabel, FormUi, @@ -10,7 +10,7 @@ import { UiModal, } from "@common/business_components"; import { Input } from "@common/components"; -import { Button, Label } from "@common/components/ui"; +import { Button, Label } from "@common/components/ui"; import { useSearchParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; import { AccessibleFormField } from "./AccessibleFormField"; @@ -22,7 +22,7 @@ import { } from "react-hook-form"; import SearchInputText from "../common/searhDemandInput/component"; import React from "react"; -import { sanitizeInput } from "../common/utils/utils"; +import { formatDateToYMD, sanitizeInput } from "../common/utils/utils"; import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; import type { SdmInfoFormData } from "@/app/store/sdmMng"; @@ -161,7 +161,9 @@ export function SdmInfoRegForm({ if (defaults) { Object.entries(defaults).forEach(([field, value]) => { - form.setValue(field as keyof SdmInfoFormData, value, { shouldDirty: true }); + form.setValue(field as keyof SdmInfoFormData, value, { + shouldDirty: true, + }); }); } }, [form.getValues("usePurpose")]); @@ -208,8 +210,8 @@ export function SdmInfoRegForm({ formIndex: 0, required: true, component: (field) => ( -
- + {/* { @@ -224,8 +226,18 @@ export function SdmInfoRegForm({ }, }} showOutsideDays={true} - selectClass={undefined} - /> + selectClass={undefined} + /> */} + {/* 네이티브 input */} + { + const selectedDate = e.target.value ? new Date(e.target.value) : null; + field.onChange(selectedDate); + }} + value={ formatDateToYMD(field.value as Date) } + />
), }, @@ -363,13 +375,11 @@ export function SdmInfoRegForm({ render={({ field }) => name === "money" ? (
- - { component(field)} + + {component(field)}
- // {component(field)} ) : ( + // {component(field)} { field.onChange(val.toString()); }} - value={field.value } + value={field.value} readOnly={isDisabled} onBlur={field.onBlur} ref={field.ref} From cc9389b91c93f60bce2c933fcea48c8c4c98c5e4 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Fri, 29 Aug 2025 13:40:15 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EB=8C=80=EB=AF=BC=20=EC=A3=BC=EC=86=8C?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dm/.env.development | 3 ++ apps/dm/.env.local | 3 ++ apps/dm/.env.production | 3 ++ apps/dm/middleware.ts | 83 ++++++++++++++++++++++++++-------------- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/apps/dm/.env.development b/apps/dm/.env.development index 581a639c5..66f910fbe 100644 --- a/apps/dm/.env.development +++ b/apps/dm/.env.development @@ -17,3 +17,6 @@ NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/ap #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정 + +NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do +NEXT_PUBLIC_WR_ADDRESS_KEY = devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM= diff --git a/apps/dm/.env.local b/apps/dm/.env.local index f6000ca82..1c3474d11 100644 --- a/apps/dm/.env.local +++ b/apps/dm/.env.local @@ -20,3 +20,6 @@ NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/ap #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정 + +NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do +NEXT_PUBLIC_WR_ADDRESS_KEY = devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM= diff --git a/apps/dm/.env.production b/apps/dm/.env.production index 4ce1ba027..358de43c9 100644 --- a/apps/dm/.env.production +++ b/apps/dm/.env.production @@ -16,3 +16,6 @@ NEXT_PUBLIC_NGII_URL = http://10.98.25.94:18080/openapi/Gettile.do?apiKey=BDE2BE NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-dev.svc.cluster.local:8000/sewerage-service/api + +NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do +NEXT_PUBLIC_WR_ADDRESS_KEY = U01TXOFVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA= diff --git a/apps/dm/middleware.ts b/apps/dm/middleware.ts index 8fcfd4167..6b37ac02e 100644 --- a/apps/dm/middleware.ts +++ b/apps/dm/middleware.ts @@ -7,6 +7,8 @@ const serverApiUrl = process.env.NEXT_PUBLIC_CS_SERVER_API_URL; const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || ""; const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || ""; const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || ""; +const BUSINESS_JUSO_API_URL = process.env.NEXT_PUBLIC_FINDADRESS_URL || ""; +const AdressKey = process.env.NEXT_PUBLIC_WR_ADDRESS_KEY || ""; export function middleware(req: NextRequest) { const pathname = req.nextUrl.pathname; @@ -24,8 +26,8 @@ export function middleware(req: NextRequest) { if (pathname.startsWith("/server")) { const decodedParams = Array.from(searchParams.entries()) - .map(([key, value]) => `${key}=${decodeURIComponent(value)}`) - .join("&"); + .map(([key, value]) => `${key}=${decodeURIComponent(value)}`) + .join("&"); const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${ decodedParams ? `?${decodedParams}` : "" @@ -38,7 +40,6 @@ export function middleware(req: NextRequest) { return NextResponse.redirect(new URL("/pages/wrStatus", req.url)); } - if (pathname.startsWith("/attach-service")) { const requestHeaders = new Headers(req.headers); // const token = @@ -69,7 +70,7 @@ export function middleware(req: NextRequest) { `[Middleware] Rewriting from '/user-service' path to: ${newUrl}` ); return NextResponse.rewrite(new URL(newUrl), { - headers: requestHeaders + headers: requestHeaders, }); } @@ -81,33 +82,31 @@ export function middleware(req: NextRequest) { let newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`; if ( - typename == "hasudo:tb_il_swage_prcs_fclt" //하수처리시설 - || typename == "hasudo:tb_ms_swage_prcs_zone" //하수처리구역 - || typename == "hasudo:tb_ms_sbmrg_dngr_map" //침수위험지도 - || typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도 + typename == "hasudo:tb_il_swage_prcs_fclt" || //하수처리시설 + typename == "hasudo:tb_ms_swage_prcs_zone" || //하수처리구역 + typename == "hasudo:tb_ms_sbmrg_dngr_map" || //침수위험지도 + typename == "hasudo:tb_ms_flood_dngr_map" //도시침수지도 ) { newUrl = `${GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`; - } - else if ( - typename == "hasudo:tb_ms_swage_ppl" //관로 - || typename == "hasudo:tb_ms_swage_mhl" //맨홀 - || typename == "hasudo:tb_ms_swage_pmstn" //펌프장 - || typename == "hasudo:tb_ms_stofcbr" //우수토실 + } else if ( + typename == "hasudo:tb_ms_swage_ppl" || //관로 + typename == "hasudo:tb_ms_swage_mhl" || //맨홀 + typename == "hasudo:tb_ms_swage_pmstn" || //펌프장 + typename == "hasudo:tb_ms_stofcbr" //우수토실 ) { newUrl = `${LX_GEOSERVER_URL}${pathname.replace("/geoserver", "")}${queryParams ? `?${queryParams}` : ""}`; - } - else if ( - typename == "hasudo:om_dt_untrt_swg_rain" //중점우수토실 - || typename == "hasudo:om_wqlt_station" //관측소 - || typename == "hasudo:tb_wr_bdst_ruse_fclt" //재이용시설 - || typename == "hasudo:tb_wr_rnwtr_utztn_fclt" //빗물이용시설 - || typename == "hasudo:tb_wr_rswtr_fclt" //중수도시설 - || typename == "hasudo:tb_wr_htdfl_fclt" //온배수시설 - || typename == "hasudo:tb_wr_ruse_fclt_dmd_co" //수요처 - || typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처 - ){ + } else if ( + typename == "hasudo:om_dt_untrt_swg_rain" || //중점우수토실 + typename == "hasudo:om_wqlt_station" || //관측소 + typename == "hasudo:tb_wr_bdst_ruse_fclt" || //재이용시설 + typename == "hasudo:tb_wr_rnwtr_utztn_fclt" || //빗물이용시설 + typename == "hasudo:tb_wr_rswtr_fclt" || //중수도시설 + typename == "hasudo:tb_wr_htdfl_fclt" || //온배수시설 + typename == "hasudo:tb_wr_ruse_fclt_dmd_co" || //수요처 + typename == "hasudo:tb_wr_tmpr_dmd_co" //잠재수요처 + ) { const url = req.nextUrl.clone(); - url.searchParams.set('TYPENAME', typename.replace("hasudo:","")); + url.searchParams.set("TYPENAME", typename.replace("hasudo:", "")); queryParams = url.searchParams.toString(); newUrl = `${SEWERAGE_API_URL}/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`; } @@ -118,15 +117,41 @@ export function middleware(req: NextRequest) { if (pathname.startsWith("/sewerage-service")) { const queryParams = searchParams.toString(); - const newUrl = `${SEWERAGE_API_URL}${pathname.replace("/sewerage-service/api", "")}${queryParams ? `?${queryParams}` : "" - }`; + const newUrl = `${SEWERAGE_API_URL}${pathname.replace("/sewerage-service/api", "")}${ + queryParams ? `?${queryParams}` : "" + }`; console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`); return NextResponse.rewrite(new URL(newUrl)); } + if (pathname.startsWith("/bussiness-juso-service")) { + console.log("AdressKey ", AdressKey); + const params = new URLSearchParams({ + currentPage: "1", // 원하는 페이지 + countPerPage: "5", // 페이지당 결과 수 + keyword: searchParams.get("keyword") || "", // 검색어(주소) + confmKey: AdressKey, // 인증키 인터넷용 패쇄망용은 따로 발급 필요 즉 middleware에서 치환해서 사용해야할듯 + resultType: "json", // 결과 형식 기본은 xml + }); + const newUrl = `${BUSINESS_JUSO_API_URL}?${params.toString()}`; + console.log(`[Middleware] Request to business.juso.go.kr`); + console.log(req.url); + console.log( + `[Middleware] Rewriting from '/business.juso.go.kr' path to: ${newUrl}` + ); + return NextResponse.rewrite(new URL(newUrl)); + } return NextResponse.next(); } export const config = { - matcher: ["/server/:path*", "/user-service/:path*", "/attach-service/:path*", "/geoserver/:path*", "/sewerage-service/:path*", "/"], + matcher: [ + "/server/:path*", + "/user-service/:path*", + "/attach-service/:path*", + "/geoserver/:path*", + "/sewerage-service/:path*", + "/bussiness-juso-service/:path*", + "/", + ], };