diff --git a/apps/dm/app/(with-layout)/apply/status/page.tsx b/apps/dm/app/(with-layout)/apply/status/page.tsx index bad342e20..f184beb50 100644 --- a/apps/dm/app/(with-layout)/apply/status/page.tsx +++ b/apps/dm/app/(with-layout)/apply/status/page.tsx @@ -185,7 +185,9 @@ export default function DemandStatusPage() { const userData = JSON.parse(user) as SessionUser; const dmdInfoId = userData.dmdInfoId?.trim(); if (dmdInfoId) { - getSdmInfoStatusList(dmdInfoId); + void getSdmInfoStatusList(dmdInfoId).then((active) => { + if (!active) window.location.href = "/"; + }); } } catch (error) { console.error("Error parsing user data:", error); @@ -341,7 +343,9 @@ export default function DemandStatusPage() { if (res) { const user = JSON.parse(sessionStorage.getItem("user") || "{}"); if (user?.dmdInfoId) { - getSdmInfoStatusList(user.dmdInfoId); + void getSdmInfoStatusList(user.dmdInfoId).then((active) => { + if (!active) window.location.href = "/"; + }); } setIsEditMode(false); } diff --git a/apps/dm/app/store/common/index.tsx b/apps/dm/app/store/common/index.tsx index 3e54da15f..b50d6517a 100644 --- a/apps/dm/app/store/common/index.tsx +++ b/apps/dm/app/store/common/index.tsx @@ -211,18 +211,32 @@ const selectMiddleRegionData: SelectDataType[] = [ * STORE - API */ +/** API 선택 목록의 빈 값과 중복 값을 제거하고 전체 항목을 한 번만 추가한다. */ +function normalizeSelectData(items: T[], allItem: T): T[] { + const uniqueItems = new Map(); + + items.forEach((item) => { + const val = String(item.val ?? '').trim(); + + if (!val || val === '0' || uniqueItems.has(val)) return; + uniqueItems.set(val, { ...item, val }); + }); + + return [allItem, ...uniqueItems.values()]; +} + // 시도 API 호출 함수 추가 const fetchSidoData = async (): Promise => { try { const res = await getFetch(fetchType.FO, '/addr/city'); const data = res.data; - selectSidoData = [ - { text: "전체", val: '0'}, - ...data.map((item: sidoDataType) => ({ - text: item.sido || '', - val: String(item.adstDstrCd) || '' - })) - ]; + selectSidoData = normalizeSelectData( + data.map((item: sidoDataType) => ({ + text: item.sido || '', + val: String(item.adstDstrCd) || '' + })), + { text: "전체", val: '0' } + ); return selectSidoData; } catch (error) { console.error('시도 데이터를 가져오는데 실패했습니다:', error); @@ -235,14 +249,13 @@ const fetchSigunData = async (): Promise => { try { const res = await getFetch(fetchType.FO, '/addr/sgg'); const data = res.data; - selectSigunData = [ - { text: "전체", val: '0' }, - ...data - .map((item: sigunDataType) => ({ - text: item.gugun || '', - val: String(item.adstDstrCd) || '' - })) - ]; + selectSigunData = normalizeSelectData( + data.map((item: sigunDataType) => ({ + text: item.gugun || '', + val: String(item.adstDstrCd) || '' + })), + { text: "전체", val: '0' } + ); return selectSigunData; } catch (error) { console.error('시군구 데이터를 가져오는데 실패했습니다:', error); @@ -255,13 +268,13 @@ const fetchRegionData = async (): Promise => { try { const res = await getFetch(fetchType.FO, '/addr/sarea'); const data = res.data; - return [ - { text: "전체", val: '0'}, - ...data.map((item: regionDataType) => ({ + return normalizeSelectData( + data.map((item: regionDataType) => ({ text: item.rvbsn || '', val: String(item.rvbsnCd) || '' - })) - ]; + })), + { text: "전체", val: '0' } + ); } catch (error) { console.error('권역 데이터를 가져오는데 실패했습니다:', error); return selectRegionData; @@ -273,14 +286,13 @@ const fetchMiddleRegionData = async (): Promise => { try { const res = await getFetch(fetchType.FO, '/addr/midArea'); const data = res.data; - return [ - { text: "전체", val: '0' }, - ...data - .map((item: middleRegionDataType) => ({ + return normalizeSelectData( + data.map((item: middleRegionDataType) => ({ text: item.mdmbsn || '', val: String(item.rvbsnCd) || '' - })) - ]; + })), + { text: "전체", val: '0' } + ); } catch (error) { console.error('중권역 데이터를 가져오는데 실패했습니다:', error); return selectMiddleRegionData; @@ -292,14 +304,13 @@ const fetchUnitWaterShedData = async (): Promise => { try { const res = await getFetch(fetchType.FO, '/addr/largeArea'); const data = res.data; - return [ - { text: "전체", val: '0' }, - ...data - .map((item: unitWaterShedDataType) => ({ + return normalizeSelectData( + data.map((item: unitWaterShedDataType) => ({ text: item.lgbsn || '', val: String(item.rvbsnCd) || '' - })) - ]; + })), + { text: "전체", val: '0' } + ); } catch (error) { console.error('단위유역 데이터를 가져오는데 실패했습니다:', error); return selectUnitWaterShedData; @@ -311,15 +322,14 @@ const fetchEnvPartData = async (): Promise => { try { const res = await getFetch(fetchType.FO, '/addr/govArea'); const data = res.data; - selectEnvPartData = [ - { text: "전체", val: '0', adstDliStrCd: '' }, - ...data - .map((item: envPartDataType) => ({ + selectEnvPartData = normalizeSelectData( + data.map((item: envPartDataType) => ({ text: item.lclgvrnmntNm || '', val: String(item.lclgvrnmntCd) || '', adstDliStrCd: item.adstDliStrCd || '' - })) - ]; + })), + { text: "전체", val: '0', adstDliStrCd: '' } + ); return selectEnvPartData; } catch (error) { console.error('환경청 데이터를 가져오는데 실패했습니다:', error); diff --git a/apps/dm/app/store/sdmMng/index.tsx b/apps/dm/app/store/sdmMng/index.tsx index 904c0a6b0..45c8a2dca 100644 --- a/apps/dm/app/store/sdmMng/index.tsx +++ b/apps/dm/app/store/sdmMng/index.tsx @@ -134,22 +134,23 @@ export type SupplyCandidate = { export type DemandMatchings = { - splyFcltFk: string | ''; - splyFcltFlg: string | ''; - pbnstRuseFcltBizFk: number | ''; - splyBgngDay: string | ''; - splyEndDay: string | ''; - splyCpct: number | ''; - splyFmYn: string | ''; - useUsgCd: string | ''; - dmdInfoSn: number | ''; - splyCndtList: string | ''; - mtchnCmptnYmd: string | ''; - rvwCmptnYmd: string | ''; - regDt: string | ''; - rgtr: string | ''; - mdfcnDt: string | ''; - mdfr: string | ''; + splyFcltFk: string | ''; // 공급시설 외래키 + splyFcltFlg: string | ''; // 공급시설 진행상태 + pbnstRuseFcltBizFk: number | ''; // 공공하수 재이용시설 사업 외래키 + splyBgngDay: string | ''; // 공급시작일 + splyEndDay: string | ''; // 공급종료일 + splyCpct: number | ''; // 계약 공급량 + splyFmYn: string | ''; // 공급 유량계 유무 + useUsgCd: string | ''; // 사용용도 코드 + dmdInfoSn: number | ''; // 수요정보 일련번호 + ruseUtztnFcltNm?: string | ''; // 재이용시설명 + splyCndtList: string | ''; // 공급 후보지 목록 + mtchnCmptnYmd: string | ''; // 매칭 완료일자 + rvwCmptnYmd: string | ''; // 검토 완료일자 + regDt: string | ''; // 등록일시 + rgtr: string | ''; // 등록자 + mdfcnDt: string | ''; // 수정일시 + mdfr: string | ''; // 수정자 } // 유사사례 @@ -503,6 +504,14 @@ const postSdmData = async (data: DemandCompType) => { // 수요정보 등록 const postSdmInfoData = async (data: SdmInfoFormData): Promise => { try { + const activeDemand = data.dmdInfoId + ? await getSdmInfoStatusList(data.dmdInfoId) + : null; + if (!activeDemand?.dmdInfoId) { + sessionStorage.removeItem("user"); + alert('사용 중지되었거나 등록되지 않은 수요처입니다. 다시 로그인해 주세요.'); + return false; + } await postFetch("/reuseFc/request/demandInfo", data); alert('수요 정보 등록에 성공하였습니다.'); return true; @@ -516,6 +525,14 @@ const postSdmInfoData = async (data: SdmInfoFormData): Promise => { // 수요정보 수정 const fetchUpdateSdmInfoData = async (data: SdmInfoFormData): Promise => { try { + const activeDemand = data.dmdInfoId + ? await getSdmInfoStatusList(data.dmdInfoId) + : null; + if (!activeDemand?.dmdInfoId) { + sessionStorage.removeItem("user"); + alert('사용 중지되었거나 등록되지 않은 수요처입니다. 다시 로그인해 주세요.'); + return false; + } await postFetch("/reuseFc/request/updateDemandInfo", data); alert('수요 정보 수정에 성공하였습니다.'); return true; @@ -584,14 +601,19 @@ const getDemandCompList = async (searchText: string, pageCnt: number) => { } } -const getSdmInfoStatusList = async (dmdInfoId: string) => { +type DemandStatusResponse = DemandCompType & { + demandInfo?: DemandCompBizType[]; + demandMatchings?: DemandMatchings[]; +}; + +const getSdmInfoStatusList = async (dmdInfoId: string): Promise => { try { const url = '/reuseFc/request/' + dmdInfoId + '?infoListYn=Y'; const res = await getFetch(fetchType.WR, url); - return res?.data || []; + return res?.data ?? null; } catch (error) { console.error(error + ' 수요정보 신청현황을 불러오지 못했습니다.'); - return []; + return null; } } @@ -620,7 +642,7 @@ export type SdmActions = { updateSdmInfoData: (data: SdmInfoFormData) => Promise; getDemandCompList: (searchText: string, pageCnt: number) => Promise; actionLogin: (data: DemandCompType) => Promise; - getSdmInfoStatusList: (dmdInfoId: string) => Promise; + getSdmInfoStatusList: (dmdInfoId: string) => Promise; getSimilarCaseList: (part: string, value: number | string) => Promise; actionLogout: () => Promise; @@ -736,19 +758,25 @@ export const SdmReducer = (set: any): SdmActions => { getSdmInfoStatusList: async (dmdInfoId: string) => { const res = await getSdmInfoStatusList(dmdInfoId); - if (res.length === 0) { + if (!res?.dmdInfoId) { + sessionStorage.removeItem("user"); set((state: SdmType) => ({ Sdm: { ...state.Sdm, sdmInfoStatusList: [], + successLogin: false, + loginUser: null, } })) - return; + toast.error("사용 중지되었거나 등록되지 않은 수요처입니다."); + return false; } //const sdmInfoStatusList : DemandCompBizType[] = []; - const sdmInfoStatusList: DemandCompBizType[] = res.demandInfo.map((el: DemandCompBizType, index: number) => { - const matchingInfo = res.demandMatchings.find((matching: DemandMatchings) => matching.dmdInfoSn === el.dmdInfoSn); + const demandInfo = Array.isArray(res.demandInfo) ? res.demandInfo : []; + const demandMatchings = Array.isArray(res.demandMatchings) ? res.demandMatchings : []; + const sdmInfoStatusList: DemandCompBizType[] = demandInfo.map((el: DemandCompBizType, index: number) => { + const matchingInfo = demandMatchings.find((matching: DemandMatchings) => matching.dmdInfoSn === el.dmdInfoSn); const status = matchingInfo?.splyFcltFlg?.trim() === 'Sub' ? '검토' : matchingInfo?.splyFcltFlg?.trim() === 'matched' ? '매칭완료' : '신청'; const ruseUtztnFcltNm = matchingInfo?.ruseUtztnFcltNm ? matchingInfo.ruseUtztnFcltNm : ''; @@ -781,6 +809,7 @@ export const SdmReducer = (set: any): SdmActions => { sdmInfoStatusList: sdmInfoStatusList, } })) + return true; }, actionLogin: async (data: DemandCompType): Promise => { diff --git a/apps/wr/app/(with-layout)/matMng/coMng/coSttn/page.tsx b/apps/wr/app/(with-layout)/matMng/coMng/coSttn/page.tsx index 6cdef62db..19f1fdb83 100644 --- a/apps/wr/app/(with-layout)/matMng/coMng/coSttn/page.tsx +++ b/apps/wr/app/(with-layout)/matMng/coMng/coSttn/page.tsx @@ -48,9 +48,10 @@ export default function CoSttn() { coSttnTxtSearch, demandCompList, coSttnPwInit, + coSttnDelete, getMyUUID } = useWrStore((state) => state); - const { regAuthrtYn, mdfcnAuthrtYn } = auth; + const { regAuthrtYn, mdfcnAuthrtYn, delAuthrtYn } = auth; const alert = useAlertStore((state) => state.setMessage); const { confirm } = useConfirm(); const [bdstTable, setBdstTable] = useState(); @@ -69,6 +70,7 @@ export default function CoSttn() { const [seartchTxt, setSearchTxt] = useState(); const [updateData, setUpdateData] = useState(); const [isResetSelection, setIsResetSelection] = useState(false); + const [isDeleting, setIsDeleting] = useState(false); const sanitizeDemandForPopup = useCallback((data?: DemandCompType) => { if (!data) { @@ -242,6 +244,52 @@ export default function CoSttn() { }); }; + /** + * 선택한 수요처를 논리삭제하고 현재 검색조건으로 목록을 다시 조회한다. + * @param data 삭제 대상 수요처 + */ + const handleDeleteDemand = async (data: DemandCompType) => { + if (!data.dmdCoSn) { + alert("수요처 식별값이 없어 삭제할 수 없습니다."); + return; + } + + const confirmed = await confirm( + `${data.dmdCoNm || "선택한 수요처"}를 삭제하시겠습니까? 삭제 후 목록과 로그인, 지도에서 조회되지 않습니다.`, + ); + if (!confirmed) return; + + const modifier = data.mdfr || await getMyUUID(); + if (typeof modifier !== "string" || !modifier) { + alert("수정자 정보를 확인할 수 없어 삭제할 수 없습니다."); + return; + } + + setIsDeleting(true); + try { + const deleted = await coSttnDelete(Number(data.dmdCoSn), modifier); + if (!deleted) { + alert("수요처 삭제에 실패하였습니다."); + return; + } + + alert("수요처가 삭제되었습니다."); + setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); + setUpdateData(undefined); + setIsResetSelection(true); + + const con = + objSearch.sgg && objSearch.sgg !== "0" ? objSearch.sgg : objSearch.city; + if (seartchTxt && seartchTxt.trim().length > 0) { + await coSttnTxtSearch(String(pageNation), "13", String(con), seartchTxt); + } else { + await coSttnSearch(String(pageNation), "13", String(con)); + } + } finally { + setIsDeleting(false); + } + }; + return ( <> @@ -388,6 +436,8 @@ export default function CoSttn() { getDemandCompList(searchText, pageCnt); }} rtnInputData={handleRtnInputData} + onDelete={handleDeleteDemand} + deleteDisabled={delAuthrtYn === "N" || isDeleting} bodyClassNm={"w-full mx-auto bg-background rounded-lg shadow-md p-6"} updateList={updateData} openNetwork={true} diff --git a/apps/wr/app/api/common-codes/route.ts b/apps/wr/app/api/common-codes/route.ts index ae0c175cd..cd4261ece 100644 --- a/apps/wr/app/api/common-codes/route.ts +++ b/apps/wr/app/api/common-codes/route.ts @@ -1,5 +1,6 @@ export const dynamic = "force-dynamic"; import { SITE_ID } from "@/src/shared/config"; +import { normalizeSelectData } from "@/app/store/common/code/normalizeSelectData"; import { NextResponse } from "next/server"; export const revalidate = 86400; //60 * 60 * 24; @@ -143,13 +144,12 @@ export async function GET(request: Request) { val: String(item.adstDstrCd) || "", })) as SelectDataType[]), ], - cityCd: [ - { val: "0", text: "전체" }, - ...((city ?? []).map((item: any) => ({ + cityCd: normalizeSelectData( + (city ?? []).map((item: any) => ({ val: item.adstDstrCd, text: item.sido, - })) as SelectDataType[]), - ], + })), + ), rvbsnCd: [ { val: "0", text: "전체" }, ...((rvbsn ?? []).map((item: any) => ({ diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index 66f66126a..59b944a35 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -11,6 +11,7 @@ import { ruseSeCd, yn, } from "./basicCode"; +import { normalizeSelectData } from "./normalizeSelectData"; export const btnClass = "p-4 m-2 rounded-sm text-lg font-medium text-primary-foreground "; const laeSecd = "41"; @@ -133,11 +134,12 @@ export const getSggCd = async (set: any) => { }; export const getCityCd = async (set: any) => { const city = await getFetch("common", "/addr/city"); - const cityCd = city.map((item: any) => ({ - val: item.adstDstrCd, - text: item.sido, - })); - cityCd.unshift({ val: "0", text: "전체" }); + const cityCd = normalizeSelectData( + city.map((item: any) => ({ + val: item.adstDstrCd, + text: item.sido, + })), + ); set((state: comCodeState) => ({ code: { ...state.code, diff --git a/apps/wr/app/store/common/code/normalizeSelectData.ts b/apps/wr/app/store/common/code/normalizeSelectData.ts new file mode 100644 index 000000000..4f8db2d6d --- /dev/null +++ b/apps/wr/app/store/common/code/normalizeSelectData.ts @@ -0,0 +1,28 @@ +type SelectDataInput = { + text?: string | null; + val?: string | number | null; +}; + +export type NormalizedSelectData = { + text: string; + val: string; +}; + +/** 선택 목록을 값 기준으로 중복 제거하고 프런트 표준 전체 항목을 한 번만 추가한다. */ +export const normalizeSelectData = ( + items: readonly SelectDataInput[], +): NormalizedSelectData[] => { + const uniqueItems = new Map(); + + items.forEach((item) => { + const val = String(item.val ?? "").trim(); + if (!val || val === "0" || uniqueItems.has(val)) return; + + uniqueItems.set(val, { + text: String(item.text ?? ""), + val, + }); + }); + + return [{ text: "전체", val: "0" }, ...uniqueItems.values()]; +}; diff --git a/apps/wr/app/store/matDmd/coSttn/index.tsx b/apps/wr/app/store/matDmd/coSttn/index.tsx index fd9baab73..f926ca96a 100644 --- a/apps/wr/app/store/matDmd/coSttn/index.tsx +++ b/apps/wr/app/store/matDmd/coSttn/index.tsx @@ -1,5 +1,5 @@ import type { CommonTableProps } from "@/app/store/common/type/header"; -import { fetchType, getFetchWithCount, putFectch } from "@/components/lib/api"; +import { deleteFectch, fetchType, getFetchWithCount, putFectch } from "@/components/lib/api"; import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; import { sha512 } from "js-sha512"; import { coSttHeadListExport, coSttNodeListExport } from "./headList"; @@ -26,6 +26,7 @@ type coSttnActions = { coSttnSearch: (pageNo: string, pageCnt: string, con: string) => void; coSttnTxtSearch: (pageNo: string, pageCnt: string, con: string, txt: string) => void; coSttnPwInit: (dmdCoSn: number, dmdInfoId: string) => Promise; + coSttnDelete: (dmdCoSn: number, mdfr: string) => Promise; }; export type coSttnType = coSttnState & coSttnActions; @@ -148,6 +149,23 @@ export const coSttnActionsExport: (set: any) => coSttnActions = ( } }); } - } + }, + // 수요처를 물리삭제하지 않고 미사용 상태로 변경한다. + coSttnDelete: async (dmdCoSn: number, mdfr: string) => { + try { + const responseText = await deleteFectch( + `/reuseFc/request/${dmdCoSn}`, + { mdfr }, + ); + const response = JSON.parse(responseText) as { + status?: number; + data?: number; + }; + return response.status === 200 && Number(response.data) > 0; + } catch (error) { + console.error("수요처 삭제 중 오류가 발생했습니다.", error); + return false; + } + }, } } diff --git a/packages/common/business_components/src/ui/map/searchBar/utils.ts b/packages/common/business_components/src/ui/map/searchBar/utils.ts index 5c9aef350..84918a3ca 100644 --- a/packages/common/business_components/src/ui/map/searchBar/utils.ts +++ b/packages/common/business_components/src/ui/map/searchBar/utils.ts @@ -188,8 +188,9 @@ export const sigunguCenter: Record = { "11530": [943255.85156361, 1944224.7496726601], // 구로구 "41310": [967836.346287095, 1955821.725581055], // 구리시 "47190": [1076297.5737083051, 1801900.2253747801], // 구미시 - "45130": [904674.42544751, 1767715.183037305], // 군산시 - "27720": [1103849.611897755, 1797204.1944948], // 군위군 + "45130": [931167.80, 1774809.14], // 군산시 (육지(시청·군청) 기준, 도서지역 제외) + "27720": [1096402.36, 1805597.71], // 군위군 (군청 기준) + "47720": [1096402.36, 1805597.71], // 군위군 경북 구코드 (군청 기준) "41410": [948411.5776788951, 1927135.757437655], // 군포시 "44710": [998110.87580872, 1792026.97835628], // 금산군 "26410": [1144696.85330015, 1697028.92074261], // 금정구 @@ -214,7 +215,8 @@ export const sigunguCenter: Record = { "27290": [1092874.923985485, 1758802.075636735], // 달서구 "27710": [1092556.27778919, 1753550.63671916], // 달성군 "46710": [953252.8048743049, 1699620.87304459], // 담양군 - "44270": [922626.193186825, 1879100.4990195702], // 당진시 + "44270": [923895.22, 1877173.14], // 당진시 (육지(시청·군청) 기준, 도서지역 제외) + "44830": [923895.22, 1877173.14], // 당진시 신코드 (육지(시청·군청) 기준, 도서지역 제외) "30230": [995239.980794815, 1823508.474804295], // 대덕구 "11320": [958705.07469343, 1963040.273132075], // 도봉구 "26170": [1140792.941703185, 1682445.908553165], // 동구 @@ -235,7 +237,7 @@ export const sigunguCenter: Record = { "47280": [1055620.11152262, 1855147.380883595], // 문경시 "28170": [926226.3594373399, 1940093.5607894901], // 미추홀구 "48270": [1117632.749546145, 1722736.830743895], // 밀양시 - "44180": [896412.984839845, 1817364.412693855], // 보령시 + "44180": [920366.76, 1815478.75], // 보령시 (육지(시청·군청) 기준, 도서지역 제외) "46780": [974939.082074685, 1646364.3864357], // 보성군 "43720": [1018843.696119875, 1832681.50774474], // 보은군 "47920": [1125627.975921425, 1881676.019098885], // 봉화군 @@ -284,7 +286,8 @@ export const sigunguCenter: Record = { "45770": [962532.77503817, 1714757.02288094], // 순창군 "46150": [989441.17839757, 1668074.09581569], // 순천시 "41390": [934025.6249972349, 1932609.450570995], // 시흥시 - "46910": [837068.838454425, 1628081.7615658198], // 신안군 + "46910": [894983.16, 1649365.33], // 신안군 (군청 압해도 기준, 목포 인접) + "12870": [894983.16, 1649365.33], // 신안군 전남광주통합특별시 코드 (군청 압해도 기준, 목포 인접) "44200": [953095.1457245699, 1866467.6723041101], // 아산시 "47170": [1108716.740335165, 1841036.9856003649], // 안동시 "41273": [921146.8917017151, 1914174.551465955], // 안산시 단원구 @@ -298,7 +301,8 @@ export const sigunguCenter: Record = { "41710": [957059.65493005, 1978556.8707086649], // 양주시 "11470": [943115.85871501, 1947726.50098438], // 양천구 "41830": [1006799.81121338, 1946640.3454016], // 양평군 - "46130": [1005710.6789662449, 1606473.622557845], // 여수시 + "46130": [1014844.04, 1640669.82], // 여수시 (육지(시청·군청) 기준, 도서지역 제외) + "12130": [1014844.04, 1640669.82], // 여수시 전남광주통합특별시 코드 (육지(시청·군청) 기준, 도서지역 제외) "41730": [1007389.488139985, 1920986.5590416798], // 여주시 "28185": [924301.1973107599, 1932716.5874987599], // 연수구 "26470": [1143967.4104618952, 1688206.29479672], // 연제구 @@ -318,13 +322,14 @@ export const sigunguCenter: Record = { "41370": [959957.253397675, 1907245.6871241601], // 오산시 "43730": [1016925.1630849349, 1812306.15335931], // 옥천군 "28720": [831017.06725137, 1941763.7671776651], // 옹진군 - "46890": [934681.072970785, 1580260.96434381], // 완도군 + "46890": [931461.10, 1591076.05], // 완도군 (육지(시청·군청) 기준, 도서지역 제외) + "12850": [931461.10, 1591076.05], // 완도군 전남광주통합특별시 코드 (육지(시청·군청) 기준, 도서지역 제외) "45710": [971714.974980355, 1764297.860421155], // 완주군 "11170": [954152.265892775, 1948105.11473188], // 용산구 "41463": [966362.167328945, 1919086.059435395], // 용인시 기흥구 "41465": [962751.309054115, 1926067.760215145], // 용인시 수지구 "41461": [979413.39966679, 1913728.657159615], // 용인시 처인구 - "47940": [1339459.86503077, 1939972.251018405], // 울릉군 + "47940": [1297396.76, 1949622.47], // 울릉군 (울릉도 본섬 중심, 독도 제외) "31710": [1152103.383022245, 1727062.6953479801], // 울주군 "47930": [1158508.6557213152, 1879083.142978875], // 울진군 "42130": [1042675.604280725, 1925192.470561375], // 원주시 @@ -382,7 +387,7 @@ export const sigunguCenter: Record = { "43130": [1034982.8699803599, 1889790.67989893], // 충주시 "47850": [1086736.697665845, 1779277.075473485], // 칠곡군 "42190": [1131634.14282853, 1912631.8063723398], // 태백시 - "44825": [864678.84145598, 1854929.12571281], // 태안군 + "44825": [892666.48, 1861510.33], // 태안군 (육지(시청·군청) 기준, 도서지역 제외) "48220": [1085316.421521755, 1640596.827168765], // 통영시 "41480": [941812.744809255, 1983528.9263305948], // 파주시 "42760": [1088652.567431635, 1949959.4658569149], // 평창군 diff --git a/packages/common/business_components/src/ui/sdmInsertForm/index.tsx b/packages/common/business_components/src/ui/sdmInsertForm/index.tsx index 6616954c5..0fc0bf9e3 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/index.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/index.tsx @@ -15,6 +15,8 @@ type thisProps = { dataList: DemandCompType[]; rtnValue: (searchText: string, pageCnt: number) => void; rtnInputData: (data: DemandCompType) => void; + onDelete?: (data: DemandCompType) => void | Promise; + deleteDisabled?: boolean; bodyClassNm?: string; updateList?: DemandCompType; readOnly?: boolean; @@ -122,6 +124,8 @@ export default function SdmInsertForm({ dataList, rtnValue, rtnInputData, + onDelete, + deleteDisabled, bodyClassNm, updateList, readOnly, @@ -227,16 +231,28 @@ export default function SdmInsertForm({ readOnly={readOnly} openNetwork={openNetwork} /> -
+
{readOnly == true ? ( <> ) : ( - + <> + {updateList && onDelete ? ( + + ) : null} + + )}