From 261941452afc5ed0db447804e1f67d511136adea Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 2 Sep 2026 16:41:12 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[ST]=20fix=20-=202-2=20=EC=A7=80=ED=91=9C?= =?UTF-8?q?=20=EC=BB=AC=EB=9F=BC=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=A0=9C=EC=B6=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/statistics/input/SewagePipeInp.tsx | 2 -- .../util/column/input/sewagePipe/FactInstallStatusInpColumn.ts | 2 +- .../model/input/statistics-sewage-pipe-input-interface.ts | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index 3fed52ee6..2d0eac4f3 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1289,7 +1289,6 @@ const SewagePipeInp = () => { fcltSn: nullableTrimmedString(d.fcltSn), swtrmtFcltCd: nullableTrimmedString(d.swtrmtFcltCd), swtrmtFcltNm: nullableTrimmedString(d.swtrmtFcltNm), - prcsFcltCpct: formatNumber(d.prcsFcltCpct, "prcsFcltCpct"), prcsZoneArea: formatNumber(d.prcsZoneArea, "prcsZoneArea"), cbsysPrcsZoneArea: formatNumber(d.cbsysPrcsZoneArea, "cbsysPrcsZoneArea"), sprsysPrcsZoneArea: formatNumber(d.sprsysPrcsZoneArea, "sprsysPrcsZoneArea"), @@ -1772,7 +1771,6 @@ const SewagePipeInp = () => { fcltSn: nullableTrimmedString(d.fcltSn), swtrmtFcltCd: nullableTrimmedString(d.swtrmtFcltCd), swtrmtFcltNm: nullableTrimmedString(d.swtrmtFcltNm), - prcsFcltCpct: formatNumber(d.prcsFcltCpct, "prcsFcltCpct"), prcsZoneArea: formatNumber(d.prcsZoneArea, "prcsZoneArea"), cbsysPrcsZoneArea: formatNumber(d.cbsysPrcsZoneArea, "cbsysPrcsZoneArea"), sprsysPrcsZoneArea: formatNumber(d.sprsysPrcsZoneArea, "sprsysPrcsZoneArea"), diff --git a/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts index 1d06827ab..4e8117f33 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts @@ -14,7 +14,7 @@ export const FactInstallStatusInpColumn = { // 하수처리장 정보 { name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' }, { name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly' }, - { name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' }, // 처리구역면적(km²) { diff --git a/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts b/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts index 81b8cf17c..086a50124 100644 --- a/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts +++ b/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts @@ -114,6 +114,7 @@ export type SeweragePipeInputFactInstallStatusSaveItem = Omit< | "fcltSn" | "swtrmtFcltCd" | "swtrmtFcltNm" + | "prcsFcltCpct" | "rmrk" > & { admdstCd: string | null; From afca685fd46cf82bf21f36ef457e44769a45d96e Mon Sep 17 00:00:00 2001 From: rsone001 Date: Thu, 3 Sep 2026 11:26:23 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[ST]=20-=20fix:=202-3=20=EB=A7=A4=EC=84=A4?= =?UTF-8?q?=EC=97=B0=EC=9E=A5=20=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=BC?= =?UTF-8?q?=EC=8B=9C=20=EC=88=98=EC=A0=95=20=EA=B0=80=EB=8A=A5=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=A0=81=EC=9A=A9,=20SearchFrom=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/SearchForm.tsx | 75 ++++++++++++------- .../statistics/input/SewagePipeInp.tsx | 9 ++- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index 50e7ae828..cf953ca51 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -28,7 +28,7 @@ import { SelectValue, } from "@common/components"; -import { doList } from "@/components/util/column/input/DoList"; +import { doList, doNameList } from "@/components/util/column/input/DoList"; import { defaultSearchFormProps, @@ -41,12 +41,27 @@ function isDoListBsnm(bsnmCd: string | undefined): boolean { return Boolean(bsnmCd && doList.includes(bsnmCd)); } +function isDoSido(sido?: { bsnmCd?: string; sido?: string }): boolean { + if (!sido) return false; + if (isDoListBsnm(sido.bsnmCd)) return true; + return Boolean(sido.sido && doNameList.includes(sido.sido)); +} + +function isAllGugunValue(gugun: string | undefined): boolean { + const value = (gugun ?? "").trim(); + return !value || value === "ALL" || value === "전체"; +} + +function firstConcreteSgg(list: Sgg[] | undefined): Sgg | undefined { + return (list ?? []).find((sgg) => !isAllGugunValue(sgg.gugun)); +} + const getSggListFetcher = async ( key: [string, string, string, "Y" | "N"], ): Promise> => { - const [, sidoName, instSeCd, gugunSkipYn] = key; + const [kind, sidoName, instSeCd, gugunSkipYn] = key; const params = { instSeCd, gugunSkipYn }; - if (gugunSkipYn === "N") { + if (kind === "sgg-all") { return statisticsApi.getSggAllList(sidoName, params); } return statisticsApi.getSggList(sidoName, params); @@ -69,7 +84,7 @@ function buildSearchFormValues( ); const gugun = d.gugun || - (sidoItem && !isDoListBsnm(sidoItem.bsnmCd) ? "ALL" : ""); + (sidoItem && !isDoSido(sidoItem) ? "ALL" : ""); return { sido: d.sido, gugun, @@ -105,7 +120,7 @@ function buildSearchFormValues( return { sido: useFirstSido ? first.sido : "", gugun: - useFirstSido && first && !isDoListBsnm(first.bsnmCd) ? "ALL" : "", + useFirstSido && first && !isDoSido(first) ? "ALL" : "", year: d?.year || defaultYear.toString(), order: d?.order || "", fctName: d?.fctName || "", @@ -171,7 +186,7 @@ const SearchForm = (props: SearchFormProps = {}) => { : { ...prev, sido: first.sido, - gugun: isDoListBsnm(first.bsnmCd) ? "" : "ALL", + gugun: isDoSido(first) ? "" : "ALL", bsnmCd: first.bsnmCd, }, ); @@ -186,10 +201,12 @@ const SearchForm = (props: SearchFormProps = {}) => { (item) => item.sido === values.sido, ); const gugunSkipYn = selectedSido?.gugunSkipYn ?? "Y"; + const useSggAllList = + gugunSkipYn === "N" && !isDoListBsnm(selectedSido?.bsnmCd); const sggKey: [string, string, string, "Y" | "N"] | null = values.sido && values.sido !== "ALL" && sidoList?.data ? [ - gugunSkipYn === "N" ? "sgg-all" : "sgg-list", + useSggAllList ? "sgg-all" : "sgg-list", values.sido, instSeCd, gugunSkipYn, @@ -217,45 +234,49 @@ const SearchForm = (props: SearchFormProps = {}) => { }, ); const sggOptions = sggList?.data ?? []; + const isDoSelected = isDoSido(selectedSido); + const firstConcreteSggOption = firstConcreteSgg(sggOptions); + const gugunSelectValue = + isDoSelected && isAllGugunValue(values.gugun) + ? (firstConcreteSggOption?.gugun ?? undefined) + : values.gugun || undefined; - // 도(doList): 시군구 목록 첫 항목. 광역시·세종·제주: 전체 + // 도: 전체(ALL/"")가 아니라 그 다음 시군구. 그 외: 전체 useEffect(() => { if (!mergedProps.gugun) return; if (props.defaultRegionAll) return; - if (props.defaultValues?.gugun) return; if (!values.sido || values.sido === "ALL") return; if (!selectedSido) return; - if (!isDoListBsnm(selectedSido.bsnmCd)) { + if (!isDoSelected) { setValues((prev) => { if (prev.gugun) return prev; return { ...prev, gugun: "ALL", - bsnmCd: selectedSido?.bsnmCd || prev.bsnmCd, + bsnmCd: selectedSido.bsnmCd || prev.bsnmCd, }; }); return; } - const firstSgg = sggList?.data?.[0]; - if (!firstSgg) return; + if (!firstConcreteSggOption) return; setValues((prev) => { - if (prev.gugun) return prev; + if (!isAllGugunValue(prev.gugun)) return prev; return { ...prev, - gugun: firstSgg.gugun, - bsnmCd: firstSgg.bsnmCd, + gugun: firstConcreteSggOption.gugun, + bsnmCd: firstConcreteSggOption.bsnmCd, }; }); }, [ - sggList, - values.sido, - selectedSido?.bsnmCd, + firstConcreteSggOption, + isDoSelected, mergedProps.gugun, - props.defaultValues?.gugun, props.defaultRegionAll, + selectedSido, + values.sido, ]); const handleSubmit = (e: React.FormEvent) => { @@ -269,15 +290,13 @@ const SearchForm = (props: SearchFormProps = {}) => { }; const handleSidoChange = (value: string) => { - const selectedBsnm = + const selected = value === "ALL" - ? "" - : sidoList?.data?.sidoList?.find((v) => v.sido === value) - ?.bsnmCd || ""; + ? undefined + : sidoList?.data?.sidoList?.find((v) => v.sido === value); + const selectedBsnm = selected?.bsnmCd || ""; const gugunAll = - props.defaultRegionAll || - value === "ALL" || - !isDoListBsnm(selectedBsnm); + props.defaultRegionAll || value === "ALL" || !isDoSido(selected); setValues((prev) => ({ ...prev, sido: value, @@ -341,7 +360,7 @@ const SearchForm = (props: SearchFormProps = {}) => {