diff --git a/apps/dm/app/(base-layout)/pages/sdmMng/sdmInsert/page.tsx b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInsert/page.tsx index 9a68510e3..79eb07830 100644 --- a/apps/dm/app/(base-layout)/pages/sdmMng/sdmInsert/page.tsx +++ b/apps/dm/app/(base-layout)/pages/sdmMng/sdmInsert/page.tsx @@ -58,6 +58,7 @@ export default function MyForm() { dataList={demandCompList} rtnValue={callback} rtnInputData={handleInsertSdmData} + openNetwork={true} /> diff --git a/apps/dm/app/(base-layout)/pages/wrStatus/page.tsx b/apps/dm/app/(base-layout)/pages/wrStatus/page.tsx index 263d9e42e..5a7ca6dbd 100644 --- a/apps/dm/app/(base-layout)/pages/wrStatus/page.tsx +++ b/apps/dm/app/(base-layout)/pages/wrStatus/page.tsx @@ -22,7 +22,10 @@ interface WrStatusChartProps { export default function WrStatusPage() { - const { dmStatus, getDmStatusData} = useDmStore((state) => state); + + + + const { Common, dmStatus, getDmStatusData,initializeCommonData} = useDmStore((state) => state); const { statusData,facilityTotals ,chartData} = dmStatus; const [selectedRegion, setSelectedRegion] = useState(null); const [hoveredRegion, setHoveredRegion] = useState(null); @@ -33,10 +36,9 @@ export default function WrStatusPage() { { label: '하수', color: '#FF6B6B', key: 'sewage' }, { label: '빗물', color: '#4ECDC4', key: 'rainwater' }, { label: '중수도', color: '#45B7D1', key: 'reclaimed' }, - { label: '온배수', color: '#FED16A', key: 'thermal' }, ]; const facilityTotalsColor = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FED16A']; - + const defaultYear= '2023' const handleMarkerClick = (regionId: string) => { @@ -47,6 +49,11 @@ export default function WrStatusPage() { } }; + + useEffect(() => { + initializeCommonData(); + }, [initializeCommonData]); + const createDonutMarker = useCallback((svg: SVGSVGElement, x: number, y: number, name: string, values: number[]) => { const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FED16A']; const radius = 26; @@ -142,8 +149,9 @@ export default function WrStatusPage() { useEffect(() => { - getDmStatusData('2023'); - },[]) + if(Common.selectSidoData&&Common.selectSidoData.length>0) + getDmStatusData(Common.selectSidoData); + },[Common.selectSidoData]) @@ -219,8 +227,8 @@ export default function WrStatusPage() { chartConfig : chartConfig, chartData : chartData, chartTitle : '', - chartClassName : "h-[300px] w-full", - graphSize : 40, + chartClassName : "w-full h-[350px] ", + graphSize : 10, yFieldText : '시설(개소)', showLegend : true } @@ -245,7 +253,7 @@ export default function WrStatusPage() {
{/* 타이틀 영역 */}
-

재이용시설현황(2023)

+

{`재이용시설현황(${defaultYear})`}

행정구역별 재이용시설현황(개소)

@@ -306,7 +314,7 @@ export default function WrStatusPage() { {/* 타이틀 + 버튼 영역 */}
-

재이용시설현황(2023)

+

{`재이용시설현황(${defaultYear})`}

행정구역별 재이용시설현황[개소(천m³/년)]

@@ -321,7 +329,6 @@ export default function WrStatusPage() { 하수재이용시설 빗물이용시설 중수도시설 - 온배수시설 {/* 하수(이용량,천𝓂³/년) 빗물(이용량,천𝓂³/년) 중수도(이용량,천𝓂³/년) @@ -338,7 +345,6 @@ export default function WrStatusPage() { {row.sewage} {row.rainwater} {row.reclaimed} - {row.thermal} ))} @@ -350,7 +356,7 @@ export default function WrStatusPage() { {/* 재이용통계 차트 */}
-

재이용통계(2023)

+

{`재이용통계(${defaultYear})`}

행정구역별 재이용시설 현황 개소수 그래프

diff --git a/apps/dm/app/common/comFunction.ts b/apps/dm/app/common/comFunction.ts index 6d7274b95..ec4894d49 100644 --- a/apps/dm/app/common/comFunction.ts +++ b/apps/dm/app/common/comFunction.ts @@ -1,4 +1,4 @@ -import type { DmStatusChartType, DmStatusDataType, RegionData, } from "../store/wrStatus/type"; +import type { RegionData, } from "../store/wrStatus/type"; @@ -43,7 +43,7 @@ export const regionIdMap: Record = { }; -const makeRegion = (region: string) => { +export const makeRegion = (region: string) => { if (region === '서울특별시') return '서울' if (region === '부산광역시') return '부산' if (region === '대구광역시') return '대구' @@ -56,19 +56,10 @@ const makeRegion = (region: string) => { if (region === '강원특별자치도') return '강원' if (region === '충청북도') return '충북' if (region === '충청남도') return '충남' - if (region === '전라북도') return '전북' + if (region === '전북특별자치도') return '전북' if (region === '전라남도') return '전남' if (region === '경상북도') return '경북' if (region === '경상남도') return '경남' if (region === '제주특별자치도') return '제주' return region; } -export const changeStatusMapData= (data: DmStatusDataType[]) : DmStatusChartType[]=> { - return data.map((item) => ({ - label: makeRegion(item.region??''), - 하수: item.sewage.split('(')[0]??'', - 빗물: item.rainwater.split('(')[0]??'', - 중수도: item.reclaimed.split('(')[0] ??'', - 온배수: item.thermal.split('(')[0] ??'', - })); -} \ No newline at end of file diff --git a/apps/dm/app/layout.tsx b/apps/dm/app/layout.tsx index 152a069f2..462537e09 100644 --- a/apps/dm/app/layout.tsx +++ b/apps/dm/app/layout.tsx @@ -1,4 +1,4 @@ -"use client" +"use client"; import "./globals.css"; export default function RootLayout({ @@ -6,15 +6,13 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode; }>) { + return ( 물재이용 대민 - - {children} - + {children} ); } - diff --git a/apps/dm/app/store/common/index.tsx b/apps/dm/app/store/common/index.tsx index cf4ce14d8..6721d2620 100644 --- a/apps/dm/app/store/common/index.tsx +++ b/apps/dm/app/store/common/index.tsx @@ -214,7 +214,7 @@ const selectMiddleRegionData: SelectDataType[] = [ // 시도 API 호출 함수 추가 const fetchSidoData = async (): Promise => { try { - const res = await getFetch(fetchType.COMMON, '/addr/city'); + const res = await getFetch(fetchType.FO, '/addr/city'); const data = res.data; selectSidoData = [ { text: "전체", val: '0'}, @@ -233,7 +233,7 @@ const fetchSidoData = async (): Promise => { // 시군구 API 호출 함수 추가 const fetchSigunData = async (): Promise => { try { - const res = await getFetch(fetchType.COMMON, '/addr/sgg'); + const res = await getFetch(fetchType.FO, '/addr/sgg'); const data = res.data; selectSigunData = [ { text: "전체", val: '0' }, @@ -253,7 +253,7 @@ const fetchSigunData = async (): Promise => { // 권역 API 호출 함수 추가 const fetchRegionData = async (): Promise => { try { - const res = await getFetch(fetchType.COMMON, '/addr/sarea'); + const res = await getFetch(fetchType.FO, '/addr/sarea'); const data = res.data; return [ { text: "전체", val: '0'}, @@ -271,7 +271,7 @@ const fetchRegionData = async (): Promise => { // 중권역 API 호출 함수 추가 const fetchMiddleRegionData = async (): Promise => { try { - const res = await getFetch(fetchType.COMMON, '/addr/midArea'); + const res = await getFetch(fetchType.FO, '/addr/midArea'); const data = res.data; return [ { text: "전체", val: '0' }, @@ -290,7 +290,7 @@ const fetchMiddleRegionData = async (): Promise => { // 단위유역 API 호출 함수 추가 const fetchUnitWaterShedData = async (): Promise => { try { - const res = await getFetch(fetchType.COMMON, '/addr/largeArea'); + const res = await getFetch(fetchType.FO, '/addr/largeArea'); const data = res.data; return [ { text: "전체", val: '0' }, @@ -309,7 +309,7 @@ const fetchUnitWaterShedData = async (): Promise => { // 환경청 데이터 const fetchEnvPartData = async (): Promise => { try { - const res = await getFetch(fetchType.COMMON, '/addr/govArea'); + const res = await getFetch(fetchType.FO, '/addr/govArea'); const data = res.data; selectEnvPartData = [ { text: "전체", val: '0', adstDliStrCd: '' }, diff --git a/apps/dm/app/store/map/index.tsx b/apps/dm/app/store/map/index.tsx index 7b5eb0cca..5ed066f73 100644 --- a/apps/dm/app/store/map/index.tsx +++ b/apps/dm/app/store/map/index.tsx @@ -1,9 +1,9 @@ -import { getFetch } from "@/components/ui/api"; +import { fetchType, getFetch } from "@/components/ui/api"; import { DEV_URL_FO } from "@/components/ui/config"; import type { FacilityInfo, SubsInfo } from "./type"; const checkWrRegList = async () => { - const wrRegList = await getFetch("wr", `/reuseFc/pubFc`); + const wrRegList = await getFetch(fetchType.WR, `/reuseFc/pubFc`); return wrRegList; }; diff --git a/apps/dm/app/store/wrStatus/index.tsx b/apps/dm/app/store/wrStatus/index.tsx index 417bfab6c..10ef19216 100644 --- a/apps/dm/app/store/wrStatus/index.tsx +++ b/apps/dm/app/store/wrStatus/index.tsx @@ -1,12 +1,14 @@ -import { changeStatusMapData } from "@/app/common/comFunction"; import { fetchType, getFetch } from "@/components/ui/api"; import type { DmStatusDataType, DmStatusChartType, + DmStatusBoardType, } from "./type"; +import type { SelectDataType } from "../common"; +import { makeRegion } from "@/app/common/comFunction"; export type DmStatusActions = { - getDmStatusData(year: string): void; + getDmStatusData(cityCd: SelectDataType[]): void; }; export type DmStatusType = { @@ -28,32 +30,89 @@ export type DmStatusStore = DmStatusType & DmStatusActions; export const DmStatusReducer = (set: any): DmStatusActions => { return { - getDmStatusData: async (year: string) => { - const data = await getFetch(fetchType.WR, "/daemin/" + year); - let isData:DmStatusDataType[] =[] - if(data.data&&data.data.length>0){ - isData=data.data - }else{ - fetch(`data/wrStatusData.json`).then((res) => res.json()).then((json) => isData=json)//만약 백엔드에서 못가져올경우 방어책 - } + getDmStatusData: async (cityCd: SelectDataType[]) => { + const data = await getFetch(fetchType.FO, "/dashBoard/daemin"); - const orgin: DmStatusDataType[] = isData; - const chartData = changeStatusMapData(orgin); + const dataSum = data.data.reduce( + (acc: DmStatusDataType, item: DmStatusDataType) => { + acc.sewage = ( + parseInt(acc.sewage.replaceAll(",", "")) + + parseInt(item.sewage.replaceAll(",", "")) + ).toLocaleString(); + acc.rainwater = ( + parseInt(acc.rainwater.replaceAll(",", "")) + + parseInt(item.rainwater.replaceAll(",", "")) + ).toLocaleString(); + acc.reclaimed = ( + parseInt(acc.reclaimed.replaceAll(",", "")) + + parseInt(item.reclaimed.replaceAll(",", "")) + ).toLocaleString(); + acc.sewageCnt = ( + parseInt(acc.sewageCnt.replaceAll(",", "")) + + parseInt(item.sewageCnt.replaceAll(",", "")) + ).toLocaleString(); + acc.rainwaterCnt = ( + parseInt(acc.rainwaterCnt.replaceAll(",", "")) + + parseInt(item.rainwaterCnt.replaceAll(",", "")) + ).toLocaleString(); + acc.reclaimedCnt = ( + parseInt(acc.reclaimedCnt.replaceAll(",", "")) + + parseInt(item.reclaimedCnt.replaceAll(",", "")) + ).toLocaleString(); + return acc; + }, + { + region: "합계", + sewage: "0", + rainwater: "0", + reclaimed: "0", + sewageCnt: "0", + rainwaterCnt: "0", + reclaimedCnt: "0", + } + ); + data.data.unshift(dataSum); + + console.log("dataSum ", dataSum); const facilityTotals = [ - "하수재이용시설" + "(총" + orgin[0]?.sewage.split("(")[0] + "개소)", - "빗물재이용시설" + "(총" + orgin[0]?.rainwater.split("(")[0] + "개소)", - "중수도재이용시설" + - "(총" + - orgin[0]?.reclaimed.split("(")[0] + - "개소)", - "온배수재이용시설" + "(총" + orgin[0]?.thermal.split("(")[0] + "개소)", + "하수재이용시설" + "(총" + dataSum?.sewageCnt + "개소)", + "빗물재이용시설" + "(총" + dataSum?.rainwaterCnt + "개소)", + "중수도재이용시설" + "(총" + dataSum?.reclaimedCnt + "개소)", ]; + const boardData: DmStatusBoardType[] = data.data.map( + (item: DmStatusDataType) => { + const regionText = cityCd.find((city) => item.region === city.val); + const sewage = item.sewage; + const rainwater = item.rainwater; + const reclaimed = item.reclaimed; + const sewageCnt = item.sewageCnt; + const rainwaterCnt = item.rainwaterCnt; + const reclaimedCnt = item.reclaimedCnt; + + return { + region: regionText ? regionText.text : item.region, + sewage: sewageCnt + "(" + sewage + ")", + rainwater: rainwaterCnt + "(" + rainwater + ")", + reclaimed: reclaimedCnt + "(" + reclaimed + ")", + }; + } + ); + + const chartData = data.data.map((item) => ({ + label: makeRegion( + cityCd.find((city) => item.region === city.val)?.text ?? "" + ), + 하수: item.sewage, + 빗물: item.rainwater, + 중수도: item.reclaimed, + })); + set((state: DmStatusType) => ({ ...state, dmStatus: { ...state.dmStatus, - statusData: data.data, + statusData: boardData, chartData: chartData, facilityTotals: facilityTotals, }, diff --git a/apps/dm/app/store/wrStatus/type.ts b/apps/dm/app/store/wrStatus/type.ts index 3e674227b..513a5fb01 100644 --- a/apps/dm/app/store/wrStatus/type.ts +++ b/apps/dm/app/store/wrStatus/type.ts @@ -3,9 +3,17 @@ export type DmStatusDataType = { sewage: string; rainwater: string; reclaimed: string; - thermal: string; + sewageCnt:string + rainwaterCnt:string + reclaimedCnt:string }; +export type DmStatusBoardType = { + region: string; + sewage: string; + rainwater: string; + reclaimed: string; +}; export type DmStatusFcltType = { sewageFclt: string; @@ -21,7 +29,6 @@ export type DmStatusChartType = { 하수: string, 빗물: string, 중수도: string, - 온배수: string, } export type RegionData = { diff --git a/apps/dm/components/ui/api/index.ts b/apps/dm/components/ui/api/index.ts index 51d06e700..28644b00e 100644 --- a/apps/dm/components/ui/api/index.ts +++ b/apps/dm/components/ui/api/index.ts @@ -3,7 +3,8 @@ import { DEV_URL_FO, DEV_URL_WR } from "../config"; export const fetchType = { COMMON: "common", - WR: "wr" + WR: "wr", + FO:'fo' }; interface RequestParams { @@ -11,7 +12,7 @@ interface RequestParams { } export const getFetch = async (type: string, url: string) => { - const baseUrl = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR; + const baseUrl = type === fetchType.FO ? DEV_URL_FO : DEV_URL_WR; const response = await fetch(baseUrl + url, { method: "GET", headers: { diff --git a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx index 7c6c13b32..5cfa526b8 100644 --- a/apps/dm/components/ui/sdmInfoInsertForm/component.tsx +++ b/apps/dm/components/ui/sdmInfoInsertForm/component.tsx @@ -637,7 +637,7 @@ export function SdmInfoRegForm({ }} />
- +
0){ + return ( +
+ {commentArray.map((item, index) => ( + + + {commentStartPoint} {item} + +
+
+ ))} +
+ ) + } +} + +export default UnderComment; \ No newline at end of file diff --git a/apps/fo/app/intro.md b/apps/fo/app/intro.md new file mode 100644 index 000000000..99be4afd7 --- /dev/null +++ b/apps/fo/app/intro.md @@ -0,0 +1,137 @@ +# 운영실태 인수인계 +## 이력 + written by yjs + 2025- +## 0. 알아두면 좋아요 + - 화면 초기 화면 : 메인 대시보드(표로 보는 대시보드) +
 - API swagger 주소 : http://con.mind-one.co.kr:11082/swagger-ui/index.html# +
 - 단위 : 유량은 정수까지 강우량은 소수점 1자리 반올림한다, 수질은 TN, TP만 소수점 3자리, 나머지는 1자리까지 반올림한다. +
  ▶︎ roundNumber(value:any, decimal:number) 컴포넌트를 활용해보세요!! +
 - 강우영향일 : 강우량이 3mm이상인 날은 강우영향일에 포함되고 하루전, 이틀전에 강우량이 3mm인 날의 경우도 강우량에 포함된다. 팝업의 강우시, 청천시 탭에서 보여주는 리스트를 만들 때 필요한 정보이니 참고한다. +
  ▶︎ 예시 : 1월 13일 강우량이 5일 경우 - 강우영향일 포함됨, 1월 14일, 1월 15일 강우량에 상관없이 ___강우영향일 포함됨___, 1월 16일의 경우 14일, 15일이 3mm미만이면 ___강우영향일 미포함됨___ +
  ▶︎ CalcRainEffect(data:any, weather) 컴포넌트에서 측정일, 강우량이 포함된 데이터를 파라미터로 넘기면 강우영향일(rainEffectDay) 컬럼 및 0,1로 여부 value로 데이터에 추가되어 리턴한다. +
 - 운영실태는 대부분 시설의 정보를 추출해주는 화면이 대다수이며 검색은 행정별, 유역별, 환경청별로 시설을 분류하여 조회하고 엑셀, 초기화, 조회 버튼이 우측에 존재한다. +
 - 메인 대시보드의 경우에는 수질, 유량 등 조회하는 화면의 정보들을 압축해서 보여주는 화면이라고 생각하면 좋다. 그렇기 때문에 대시보드에서의 각각의 데이터와 메인 화면의 데이터가 일치하는지 검증하는 작업이 많이 필요하다. +
 - 하루 단위의 데이터를 보여주는 모달에서 연간, 하절기, 동절기, 청천시, 강우시 등의 1년치 데이터를 필터링 하여 보여주는데 탭을 누를 시 api가 재호출 되는 형식이 아니고 1년치 데이터를 필터링 하여 출력해주고 청천시탭의 경우 강우영향일은 미포함, 강우시탭의 경우 강우영향일 포함된 데이터를 보여줘야 한다. +## 1. 표로 보기(메인 대시보드) +### 1-1) 시설정보 및 운영현황 + - 년도, 시설에 해당하는 시설정보 및 유량, 수질, 물사용량 등의 정보를 표로 표출해주는 화면 +
 - 시설계획 : 알에스원 DC-SERVICE API에서 받은 데이터를 화면에 출력 +
  ▶︎ 주소 : 'https://apigateway.apps.rsonesoft.com/dc-service/api/v1/nowDmgMtncGnsvy'; +
  ▶︎ 파라미터 : swtrmtFcltCd - 시설코드 / ctpvNm - 시도명 / sggNm - 시군구명 / targetYear - 대상년도 +
  ▶︎ 리턴값(사용되는것 위주) +
   /** +
    * 증설계획 +
    */ +
   기승인(당초4단계), 현재, 변경1~4 +
   planSwageQntSumDt4 : number | '', +
   planSwageQntSum : number | '', +
   planSwageQntSumDc1 : number | '', +
   planSwageQntSumDc2 : number | '', +
   planSwageQntSumDc3 : number | '', +
   planSwageQntSumDc4 : number | '', +
   /** +
    * 처리인구 +
    */ +
   // 기승인(당초4단계), 현재, 변경1~4 +
   swtrmtPpltnCntDt4 : number | '', +
   swtrmtPpltnCnt : number | '', +
   swtrmtPpltnCntDc1 : number | '', +
   swtrmtPpltnCntDc2 : number | '', +
   swtrmtPpltnCntDc3 : number | '', +
   swtrmtPpltnCntDc4 : number | '', +
   /** +
    * 처리구역면적 +
    */ +
   // 기승인(당초4단계), 현재, 변경1~4 +
   swtrmtZoneAreaDt4 : number | '', +
   swtrmtZoneArea : number | '', +
   swtrmtZoneAreaDc1 : number | '', +
   swtrmtZoneAreaDc2 : number | '', +
   swtrmtZoneAreaDc3 : number | '', +
   swtrmtZoneAreaDc4 : number | '', +
   // 처리구역 +
   trtDstr : string | '', +
    +
 - 물사용량 : 현재 DB가 없기 때문에 해당 년도의 평균 하수유입량 * 0.65 (65%) +
 - 운영실태 표(우측 표)의 년도는 검색한 년도에 따라 값 설정 +
 - 유입유량 : 순수하수유입량 + 연계처리수 + 총인설비반류수 + +### 1-2) 메인 그래프 + - 1년치 수질항목들의 데이터들을 표출해주는 화면 +
 - lineBarChart, lineChart 컴포넌트를 사용하여 차트를 생성함 + +### 1-3) 강우일 운영현황 + - 1년치 시설의 강우량 데이터를 구간별로 일수와 강우량 정보를 표출해주는 화면 +
 - 순수 하루단위의 강우량에 따라서 데이터를 표출하는 것이 아닌 __강우영향일__ 계산된 후 통계를 구한다. +
  ▶︎ 예시 : 1월 13일 강우량이 5일 경우 - 3~10mm구간 통계포함, 1월 14일 강우량이 0일 경우 - ___3~10mm구간 통계 포함___ +
 - 설계유입수질은 처음 설계 당시의 수질 데이터이기 때문에 한개의 데이터만 추출 +
 - 시설용량 대비는 유입유량/시설용량 * 100 (비율) +
 - 계의 경우 일수는 합계 그 외에는 평균값을 나타낸다. +## 2. 처리시설 현황 +### 2-1) 처리시설 시설정보 + - 처리시설 정보들과 이력들을 조회할 수 있는 화면이다. +
 - 모달 '기본정보' 탭의 시설계획정보는 '이력관리' 탭의 이력 리스트 중 마지막 이력의 수질정보를 표출해준다. +
 - 모달 '이력관리' 탭에서는 이력정보와 해당 차수의 수질정보를 보여준다. (1대1) +### 2-2) 처리구역정보 + - 처리시설의 계획정보를 조회할 수 있는 화면이다. +
 - 1-1)의 시설계획을 참고하도록 한다. 해당 api로 계획정보를 가져온다. +
 - 요구사항 중 원래는 단계별로 년도를 괄호로 표시해달라는 요청사항이 있었으나 시설들마다 다르기 때문에 메인화면에 단계하단에 년도를 넣는게 불가능하다. +
  ▶︎ 대시보드의 계획정보 영역의 경우에는 시설코드를 파라미터로 던져 계획정보를 가져오기 때문에 가능하여 대시보드의 계획정보는 괄호로 년도를 추출하도록 한다. +## 3. 처리시설 연간 운영 현황 +### 3-1) 강수현황 + - 시설별 강수현황을 조회할 수 있는 화면이다. +
 - 메인화면에서의 시설별 1년치 강우일, 강우일수, 강우량 데이터는 백엔드에서 계산되어 출력되는 형식이 아니라 하루치 데이터의 object(rainyDayObjList)를 store에서 계산하여 출력한다. swagger를 참고한다. +
   +
  data": [ +
   { +
    "bscFctCd": "11000SW001R", +
    "bscFctNm": "난지", +
    "sido": "서울특별시", +
    "gugun": " ", +
    "addr": "경기도 고양시 덕양구 현천동 692-2", +
    "fctCpc": 860000, +
    "stnKo": "강서", +
    "rvbsn": "한강", +
    "lgbsn": "한강본류", +
    "mdmbsn": "한강서울", +
    "rgnNm": "한강유역환경청", +
    "totalCount": 0, +
    "rainyDayObjList": [ +
     { +
      "bscFctCd": "11000SW001R", +
      "rainDt": "2024-01-01", +
      "infoRnDay": 0 +
     }, +
     { +
      "bscFctCd": "11000SW001R", +
      "rainDt": "2024-01-02", +
      "infoRnDay": 0 +
     }, +
     ..... +

 - 일별 데이터 object(rainyDayObjList)를 강우영향일 구하는 컴포넌트에 던져 강우영향일을 구한 후 메인화면에 출력해야한다. +
 - 모달 화면에서는 일별 데이터를 추출해 보여준다. +### 3-2) 유량현황 + - 시설별 년도별 유량현황을 조회할 수 있는 화면이다. +
 - 화면의 구성은 강수현황과 같이 메인화면에는 1년치 유량정보, 모달로는 하루 단위의 유량정보를 보여주지만 메인화면에서 데이터는 집계되어 추출된다. +### 3-3) 수질현황 + - 시설별 년도별 수질현황을 조회할 수 있는 화면이다. +
 - 2021년 이전은 COD, 21년부터는 TOC값을 표출한다. 그것을 구분하기 위해 2021년 이전의 TOC값들은 소괄호로 감싸준다. +
 - 모달에서 '수질 TMS'의 경우에는 운영실태 API가 아닌 물재이용 API에서 데이터를 얻으며 getFetch에서 'wr' 파라미터로 물재이용 데이터를 얻는다. +
  ▶︎ api 주소 : http://con.mind-one.co.kr:11080/api/v1/il/getTms/{시설번호} +## 4. 운영실태 +### 4-1) 오수발생량 추정 + - 물사용량 : 원래는 연간 월별 물사용량을 연계받아서 사용해야하지만 현재 연계를 받지 못하여 하수유입량의 65%를 물사용량으로 잡았다. +
 - 오수전환율 : 90%로 고정 +
 - 오수발생량 추정 : 물사용량 * (100/오수전환율) +
 - 연간 하수유입량과 청천시 하수유입량을 구하기 위해서 1년치 하루단위의 데이터를 가져와 계산이 필요(강우영향일 계산필요) +
 - 물 사용량은 월별로 연계를 받기 때문에 모달에서 하수유입량을 월별로 통계를 구해야 한다. +
 - 계산을 해보면 모달에서 월별 사용량의 평균과 1년치 데이터의 평균은 다르다. 직접 계산해보면 다를 수 밖에 없다. 하지만 값을 맞추기 위해서 모달에서의 평균값을 모달의 데이터가 아닌 1년치 데이터의 평균을 넣고 최대, 최소만 월별 데이터를 기반으로 구한다. +### 4-2) 지하수유입량 추정 + -적정여부 = 연간 지하수유입량/연평균 유입하수량*100 +
 -지하수 유입량 = 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율) +
 -모달에서의 오수발생량 전체 평균을 구할 때 평균 하수유입량을 기반으로 한 물사용량이 아닌 현재 월 데이터에서의 평균을 구한것을 넣는다. +### 4-3) RDII분석 + -RDII 추정값 : 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) +
 - RDII 추정시 일강수량 : 하절기 최저 유입 BOD 날짜의 강우량 +
 - 적정여부 : 하절기일 때 최저유입 BOD유입유량 > 시설용량 일 경우 초과유입 아니면 적정 \ No newline at end of file diff --git a/apps/fo/app/pages/(with-layout)/dashboard/drainageEquipment/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/drainageEquipment/page.tsx index 1b7249efd..fb59cfc13 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/drainageEquipment/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/drainageEquipment/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 대시보드 - 표로보기 - 배수설비 정비현황 + * + * - 배수설비 현황을 조회하는 화면. 2차사업 때 예정인 화면으로 현재 사용되지 않음. + */ + +"use client" import { useFoStore } from '@/app/store'; import type { DrainageEquipmentListProps, TableUpperProps } from '@/app/store/dashboard'; diff --git a/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/modal/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/modal/page.tsx index c482e8b7c..850d52528 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/modal/page.tsx @@ -1,4 +1,11 @@ -"use client" +/** + * 대시보드 - 표로보기 - 시설정보 및 운영현황(모달) + * + * - 유량, 수질, 총인시설의 연간, 하절기, 동절기 단위로 값을 차트로 시각화하여 보여주는 모달화면 + * - 막대그래프로 모달을 그려준다. + */ + +"use client" import type { OperationalStatusListProps } from "@/app/store/dashboard"; import { CHART_FORM, MainChart, type ChartConfig } from "@common/business_components"; import { Button } from "@common/business_components/ui/table/lib/button"; diff --git a/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/page.tsx index fa2a97d9e..dd689f2fa 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/page.tsx @@ -1,4 +1,13 @@ -"use client" +/** + * 대시보드 - 표로보기 - 시설정보 및 운영현황 + * + * - 시설정보 및 운영현황 탭의 메인 페이지 + * - 중앙상단에는 시설에 대한 요약정보가, 좌측 상단은 시설계획에 대한 정보, 좌측하단에는 물사용량에 대한 정보, + * 우측에는 조회년도 및 시설에 해당하는 유량 및 수질정보를 연간,하절기,동절기별 추출하여 데이터를 보여준다. + * - 우측 운영실태는 연간, 하절기, 동절기별로 색이 칠해져있는데 어떤항목들끼리 차트로 그려지는지 확인하기 위해서다. + */ + +"use client" import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/processFacility"; @@ -13,7 +22,12 @@ export type facilityInfoProps = { fcltyList?: { bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string, efflWqltStndrdNm: string }[]; }; -// 시설계획 table header 변경 +/** + * 시설계획 table header 변경 + * @param upHeadList + * @param planYearList + * @returns + */ const headMakeColSpanPlanFclty = (upHeadList: TableUpperProps[], planYearList: string[]) => { return ( <> { @@ -29,6 +43,12 @@ const headMakeColSpanPlanFclty = (upHeadList: TableUpperProps[], planYearList: s } // 시설계획 table header 변경 +/** + * + * @param upHeadList + * @param searchYear + * @returns + */ const headMakeColSpanOperationStatus = (upHeadList: TableUpperProps[], searchYear: string) => { return ( <> diff --git a/apps/fo/app/pages/(with-layout)/dashboard/maingraph/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/maingraph/page.tsx index 3f193e035..82eeb4d7c 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/maingraph/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/maingraph/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 대시보드 - 표로보기 - 주요그래프 + * + * - 시설의 조회년도에 해당하는 수질정보, 강우량, 유입량 등을 특정 항목별로 묶어서 차트로 시각화해주는 화면 + */ + +"use client" import { useFoStore } from "@/app/store"; import type { lineChartDataProps } from "@/app/store/dashboard"; import { CHART_FORM, type ChartConfig, ContentsDiv, MainChart } from "@common/business_components"; @@ -63,7 +69,7 @@ export default function DashBoardChart({searchYear = '', fcltyList = []}: facili color: colors[2], }, lineVal0: { - label: '시설용량', + label: '지하수유입량', color: colors[1], }, lineVal1: { diff --git a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx index 2003addee..77e4168ec 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 대시보드 - 표로보기(메인) + * + * - 대시보드 - 표로보기 메인페이지로 상단영역의 제어 및 탭 전환 시 보여주는 페이지를 지정해준다. + */ + +"use client" import { useFoStore } from "@/app/store"; import { ContentsDiv, downloadExcel, downloadMultipleExcel, filePickedBlobArray, MainDiv, SelectBox, UITab, type SelectDataType } from "@common/business_components"; import { Button, TabsContent } from "@common/components/ui"; @@ -153,7 +159,7 @@ export default function DashBoard() { const excelData1 = planFcltyList.map((item) => { return [ item.item, - item.provisionalApproval, + Number(item.provisionalApproval.toString().replaceAll(',',''))?Number(item.provisionalApproval.toString().replaceAll(',','')):item.provisionalApproval, item.now, item.stepOne, item.stepTwo, @@ -165,23 +171,24 @@ export default function DashBoard() { // operationalStatusList를 2차원 배열로 변환 const excelData2 = operationalStatusList.map((item, index) => { const baseData = [ - item.yearAvg, - item.yearMax, - item.yearMin, - item.summerAll, - item.summerThree, - item.summerRain, - item.winterAll, - item.winterSunnyAvg, - item.winterSunnyMax, - item.winterSunnyMin, - item.groundWaterAvg, - item.groundWaterSummer, - item.groundWaterWinter + Number(item.yearAvg?.replaceAll(',','')), + Number(item.yearMax?.replaceAll(',','')), + Number(item.yearMin?.replaceAll(',','')), + Number(item.summerAll?.replaceAll(',','')), + Number(item.summerThree?.replaceAll(',','')), + Number(item.summerRain?.replaceAll(',','')), + Number(item.winterAll?.replaceAll(',','')), + Number(item.winterSunnyAvg?.replaceAll(',','')), + Number(item.winterSunnyMax?.replaceAll(',','')), + Number(item.winterSunnyMin?.replaceAll(',','')), + Number(item.groundWaterAvg?.replaceAll(',','').replaceAll('%','')), + Number(item.groundWaterSummer?.replaceAll(',','').replaceAll('%','')), + Number(item.groundWaterWinter?.replaceAll(',','').replaceAll('%','')) ]; // index가 0일 때만 rdi와 rdiRain 추가 - return index === 0 ? [...baseData, item.rdi, item.rdiRain] : baseData; + console.log(item.rdiRain); + return index === 0 ? [...baseData, item.rdi&&item.rdi.toString().trim()!=''?Number(item.rdi.toString().replaceAll(',','')):'', item.rdiRain&&item.rdiRain.toString().trim()!=''?Number(item.rdiRain.toString().replaceAll(',','')):''] : baseData; }); const sheetParameter = [ @@ -240,7 +247,7 @@ export default function DashBoard() { const sheetParameter = [ { - data: [['날짜', '강수량', '유입하수량', '시설용량', '유입BOD', '유입T-P','총인유입T-P', '방류T-P', '유입T-N', '방류T-N'],...yearValueData], + data: [['날짜', '강수량', '유입하수량', '지하수유입량', '유입BOD', '유입T-P','총인유입T-P', '방류T-P', '유입T-N', '방류T-N'],...yearValueData], headerNum: 1, headerRange: 'A1:J1', sheetName: '주요그래프' diff --git a/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx index 9bceed75e..e084bf04d 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx @@ -1,4 +1,11 @@ -"use client" +/** + * 대시보드 - 표로보기 - 강우일 운영현황 + * + * - 시설의 강우량 구간별(3~10mm미만..10~20mm미만 등) 강우일수 및 수질정보를 표로 보여주는 화면 + * - 강우영향일 계산후 바뀌는 tobe강우일을 계산해야 한다. + */ + +"use client" import { useFoStore } from "@/app/store"; import { UiTable } from "@common/business_components/ui/table"; import { useEffect, useState } from "react"; @@ -46,16 +53,17 @@ export default function RainManageTab({searchYear = '', fcltyList = []}: facilit return (
- {}} - > - + {}} + widthFixed={true} + > + ☞ 일수에 강우영향일 포함됨
) diff --git a/apps/fo/app/pages/(with-layout)/dashboardMain/page.tsx b/apps/fo/app/pages/(with-layout)/dashboardMain/page.tsx index 12bf0763c..67e704570 100644 --- a/apps/fo/app/pages/(with-layout)/dashboardMain/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboardMain/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 대시보드 - 표로보기 상단구역 페에지 + * + * - 대시보드 - 표로보기의 3개의 탭 상단에 조회년도, 행정정보, 시설명의 구역을 컴포넌트 + */ + +"use client" import { useFoStore } from "@/app/store"; import { useEffect, useState } from "react"; import SearchInput from "../../../components/common/SearchInput"; diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx index bb430d0ba..e90def9b6 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 강수현황(모달) + * + * - 선택한 시설을 조회한 년도의 하루단위로 강우량 및 강우영향일 정보를 보여주는 화면. + */ + +"use client" import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; @@ -105,6 +111,8 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { const getTableData = () => { const totals = calculateTotals(); + totals.infoRnDay = roundNumber(totals.infoRnDay, 1); + return [ { bscFctCd: "", @@ -220,6 +228,7 @@ export default function PrecipitationModal(props: PrecipitationModalProps) { cellClick={undefined} onPageChange={() => {}} boldArray={[0]} + widthFixed={true} /> diff --git a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx index 0d66de569..6c5181549 100644 --- a/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityPrecipitation/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 강수현황(메인) + * + * - 시설별 강수 현황을 조회조건대로 추출하여 표로 보여주는 화면. + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; @@ -6,6 +12,7 @@ import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useEffect, useRef, useState } from "react"; import PrecipitationModal from "./modal/page"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; +import UnderComment from "@/app/components/common/UnderComment"; export default function FacilityPrecipitation() { const {Common @@ -223,9 +230,9 @@ export default function FacilityPrecipitation() {
- index !== undefined && cellClick(index)} headName={"시설별 강수현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} /> + index !== undefined && cellClick(index)} headName={"시설별 강수현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
- ☞ 강우일은 3mm 이상만 해당 / 강우영향일은 강우일 및 강우일 후 연속 2일간으로 정의 +
diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/HeadMakeColSpan.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/HeadMakeColSpan.tsx index 61076c105..aa1e36abd 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/HeadMakeColSpan.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/HeadMakeColSpan.tsx @@ -1,3 +1,9 @@ +/** + * 처리시설 연간 운영현황 - 수질현황 + * + * - 수질현황의 헤더를 만들어주는 컴포넌트 + */ + import { TableHead, TableRow } from "@common/components/ui"; interface TableUpperProps { diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx index d7cad3367..e76778d89 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/modal/page.tsx @@ -1,13 +1,29 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 수질현황 + * + * - 메인화면에서 선택한 시설의 수질정보를 하루단위로 보여주는 모달. + */ + +"use client" +import CommaToNumber from "@/app/components/common/CommaToNumber"; +import { roundNumber } from "@/app/components/common/DataForm"; +import UnderComment from "@/app/components/common/UnderComment"; import { useFoStore } from "@/app/store"; import type { FacilityWaterQltyProps, modalExcelType } from "@/app/store/facilityWaterQlty"; -import { downloadExcel, UITab, UiTable } from "@common/business_components/ui"; +import { downloadExcelFormat, UITab, UiTable } from "@common/business_components/ui"; import { Button, TabsContent } from "@common/components/ui"; import { useCallback, useEffect, useRef, useState } from "react"; import type { ReturnType } from "../../../../components/common/FacilityTermModalHeader"; import FacilityTermModalHeader from "../../../../components/common/FacilityTermModalHeader"; import { HeadMakeColSpan } from "../HeadMakeColSpan"; -import { roundNumber } from "@/app/components/common/DataForm"; + +const commentArrayChungchun = [ + "청천시 : 강우량이 3mm미만의 날" +]; + +const commentArrayRain = [ + "강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날" +]; type ModalProps ={ fcltyName: string; @@ -40,9 +56,10 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe searchFacilityWaterQltyListHist, Common } = useFoStore((state) => state); - const {btnClass} = Common; + const {btnClass, COD_YEAR} = Common; const { upHeadListModalYear, + upHeadListModalYearCod, facilityWaterQltyYearList, upHeadListModalTms, tmsList, @@ -65,12 +82,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe let maxEfflWqltTn = 0; let maxEfflWqltTp = 0; let maxefflWqltToc = 0; + let maxefflWqltCod = 0; let maxEfflWqltSs = 0; let maxinflAssctBfrWqltBod = 0; let maxinflAssctBfrWqltTn = 0; let maxInflAssctBfrWqltTp = 0; let maxinflAssctBfrWqltToc = 0; + let maxinflAssctBfrWqltCod = 0; let maxinflAssctBfrWqltSs = 0; let maxTpInflWqltBod = 0; @@ -84,12 +103,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe let minEfflWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltTn) : 0; let minEfflWqltTp = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltTp) : 0; let minefflWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltToc) : 0; + let minefflWqltCod = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltCod) : 0; let minEfflWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltSs) : 0; let mininflAssctBfrWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltBod) : 0; let mininflAssctBfrWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTn) : 0; let minInflAssctBfrWqltTp = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTp) : 0; let mininflAssctBfrWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltToc) : 0; + let mininflAssctBfrWqltCod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltCod) : 0; let mininflAssctBfrWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltSs) : 0; let minTpInflWqltBod = 99999999; @@ -101,12 +122,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe let avgEfflWqltTn = 0; let avgEfflWqltTp = 0; let avgefflWqltToc = 0; + let avgefflWqltCod = 0; let avgEfflWqltSs = 0; let avginflAssctBfrWqltBod = 0; let avginflAssctBfrWqltTn = 0; let avgInflAssctBfrWqltTp = 0; let avginflAssctBfrWqltToc = 0; + let avginflAssctBfrWqltCod = 0; let avginflAssctBfrWqltSs = 0; let avgTpInflWqltBod = 0; @@ -123,11 +146,13 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe const efflWqltTn = parseNumber(item.efflWqltTn); const efflWqltTp = parseNumber(item.efflWqltTp); const efflWqltToc = parseNumber(item.efflWqltToc); + const efflWqltCod = parseNumber(item.efflWqltCod?item.efflWqltCod.replaceAll("(","").replaceAll(")",""):0); const efflWqltSs = parseNumber(item.efflWqltSs); const inflAssctBfrWqltBod = parseNumber(item.inflAssctBfrWqltBod); const inflAssctBfrWqltTn = parseNumber(item.inflAssctBfrWqltTn); const inflAssctBfrWqltTp = parseNumber(item.inflAssctBfrWqltTp); const inflAssctBfrWqltToc = parseNumber(item.inflAssctBfrWqltToc); + const inflAssctBfrWqltCod = parseNumber(item.inflAssctBfrWqltCod?item.inflAssctBfrWqltCod.replaceAll("(","").replaceAll(")",""):0); const inflAssctBfrWqltSs = parseNumber(item.inflAssctBfrWqltSs); const tpInflWqltBod = parseNumber(item.tpInflWqltBod); @@ -145,12 +170,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe maxEfflWqltTn = Math.max(maxEfflWqltTn, efflWqltTn); maxEfflWqltTp = Math.max(maxEfflWqltTp, efflWqltTp); maxefflWqltToc = Math.max(maxefflWqltToc, efflWqltToc); + maxefflWqltCod = Math.max(maxefflWqltCod, efflWqltCod); maxEfflWqltSs = Math.max(maxEfflWqltSs, efflWqltSs); maxinflAssctBfrWqltBod = Math.max(maxinflAssctBfrWqltBod, inflAssctBfrWqltBod); maxinflAssctBfrWqltTn = Math.max(maxinflAssctBfrWqltTn, inflAssctBfrWqltTn); maxInflAssctBfrWqltTp = Math.max(maxInflAssctBfrWqltTp, inflAssctBfrWqltTp); maxinflAssctBfrWqltToc = Math.max(maxinflAssctBfrWqltToc, inflAssctBfrWqltToc); + maxinflAssctBfrWqltCod = Math.max(maxinflAssctBfrWqltCod, inflAssctBfrWqltCod); maxinflAssctBfrWqltSs = Math.max(maxinflAssctBfrWqltSs, inflAssctBfrWqltSs); maxTpInflWqltBod = Math.max(maxTpInflWqltBod, tpInflWqltBod); @@ -162,12 +189,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe minEfflWqltTn = Math.min(minEfflWqltTn, efflWqltTn); minEfflWqltTp = Math.min(minEfflWqltTp, efflWqltTp); minefflWqltToc = Math.min(minefflWqltToc, efflWqltToc); + minefflWqltCod = Math.min(minefflWqltCod, efflWqltCod); minEfflWqltSs = Math.min(minEfflWqltSs, efflWqltSs); mininflAssctBfrWqltBod = Math.min(mininflAssctBfrWqltBod, inflAssctBfrWqltBod); mininflAssctBfrWqltTn = Math.min(mininflAssctBfrWqltTn, inflAssctBfrWqltTn); minInflAssctBfrWqltTp = Math.min(minInflAssctBfrWqltTp, inflAssctBfrWqltTp); mininflAssctBfrWqltToc = Math.min(mininflAssctBfrWqltToc, inflAssctBfrWqltToc); + mininflAssctBfrWqltCod = Math.min(mininflAssctBfrWqltToc, inflAssctBfrWqltCod); mininflAssctBfrWqltSs = Math.min(mininflAssctBfrWqltSs, inflAssctBfrWqltSs); if(item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined ){ @@ -185,12 +214,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe avgEfflWqltTn += efflWqltTn; avgEfflWqltTp += efflWqltTp; avgefflWqltToc += efflWqltToc; + avgefflWqltCod += efflWqltCod; avgEfflWqltSs += efflWqltSs; avginflAssctBfrWqltBod += inflAssctBfrWqltBod; avginflAssctBfrWqltTn += inflAssctBfrWqltTn; avgInflAssctBfrWqltTp += inflAssctBfrWqltTp; avginflAssctBfrWqltToc += inflAssctBfrWqltToc; + avginflAssctBfrWqltCod += inflAssctBfrWqltCod; avginflAssctBfrWqltSs += inflAssctBfrWqltSs; if(item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined){ @@ -207,16 +238,18 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe const newFilteredData = [ { msrDt: '평균', - efflWqltBod: filteredData.length==0?'0.0':(Math.round(avgEfflWqltBod / filteredData.length * 10) / 10).toFixed(1), - efflWqltToc: filteredData.length==0?'0.0':(Math.round(avgefflWqltToc / filteredData.length * 10) / 10).toFixed(1), - efflWqltSs: filteredData.length==0?'0.0':(Math.round(avgEfflWqltSs / filteredData.length * 10) / 10).toFixed(1), - efflWqltTn: filteredData.length==0?'0.000':(Math.round(avgEfflWqltTn / filteredData.length * 1000) / 1000).toFixed(3), - efflWqltTp: filteredData.length==0?'0.000':(Math.round(avgEfflWqltTp / filteredData.length * 1000) / 1000).toFixed(3), - inflAssctBfrWqltBod: filteredData.length==0?'0.0':(Math.round(avginflAssctBfrWqltBod / filteredData.length * 10) / 10).toFixed(1), - inflAssctBfrWqltTn: filteredData.length==0?'0.000':(Math.round(avginflAssctBfrWqltTn / filteredData.length * 1000) / 1000).toFixed(3), - inflAssctBfrWqltTp: filteredData.length==0?'0.000':(Math.round(avgInflAssctBfrWqltTp / filteredData.length * 1000) / 1000).toFixed(3), - inflAssctBfrWqltToc: filteredData.length==0?'0.0':(Math.round(avginflAssctBfrWqltToc / filteredData.length * 10) / 10).toFixed(1), - inflAssctBfrWqltSs: filteredData.length==0?'0.0':(Math.round(avginflAssctBfrWqltSs / filteredData.length * 10) / 10).toFixed(1), + efflWqltBod: filteredData.length==0 || avgEfflWqltBod===0?'0.0':roundNumber((avgEfflWqltBod / filteredData.length), 1), + efflWqltToc: filteredData.length==0 || avgefflWqltToc===0?'0.0':roundNumber((avgefflWqltToc / filteredData.length), 1), + efflWqltCod: filteredData.length==0 || avgefflWqltCod===0?"(0.0)":"("+roundNumber((avgefflWqltCod / filteredData.length), 1)+")", + efflWqltSs: filteredData.length==0 || avgEfflWqltSs===0?'0.0':roundNumber((avgEfflWqltSs / filteredData.length), 1), + efflWqltTn: filteredData.length==0 || avgEfflWqltTn ===0?'0.000':roundNumber((avgEfflWqltTn / filteredData.length), 3), + efflWqltTp: filteredData.length==0 || avgEfflWqltTp ===0?'0.000':roundNumber((avgEfflWqltTp / filteredData.length), 3), + inflAssctBfrWqltBod: filteredData.length==0 || avginflAssctBfrWqltBod===0?'0.0':roundNumber((avginflAssctBfrWqltBod / filteredData.length), 1), + inflAssctBfrWqltTn: filteredData.length==0 || avginflAssctBfrWqltTn===0?'0.000':roundNumber((avginflAssctBfrWqltTn / filteredData.length), 3), + inflAssctBfrWqltTp: filteredData.length==0 || avgInflAssctBfrWqltTp===0?'0.000':roundNumber((avgInflAssctBfrWqltTp / filteredData.length), 3), + inflAssctBfrWqltToc: filteredData.length==0 || avginflAssctBfrWqltToc===0?'0.0':roundNumber((avginflAssctBfrWqltToc / filteredData.length), 1), + inflAssctBfrWqltCod: filteredData.length==0 || avginflAssctBfrWqltCod===0?'(0.0)':"("+roundNumber((avginflAssctBfrWqltCod / filteredData.length), 1)+")", + inflAssctBfrWqltSs: filteredData.length==0 || avginflAssctBfrWqltSs===0?'0.0':roundNumber((avginflAssctBfrWqltSs / filteredData.length), 1), bscFctCd: "", bscFctNm: "", lclgvrnmntNm: "", @@ -225,22 +258,24 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe addr: "", fctCpc: 0, noProcessInflAmnt : roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0), - infoRnDay: filteredData.length==0?'0.0':(Math.round(avgInfoRnDay / filteredData.length * 10) / 10).toFixed(1), - tpInflWqltBod: filteredData.length==0?'0.0':(Math.round(avgTpInflWqltBod / tpInflWqltBodCnt * 10) / 10).toFixed(1), - tpInflWqltTp: filteredData.length==0?'0.000':(Math.round(avgTpInflWqltTp / tpInflWqltTpCnt * 1000) / 1000).toFixed(3) + infoRnDay: filteredData.length==0 || avgInfoRnDay===0?'0.0':roundNumber(avgInfoRnDay / filteredData.length, 1), + tpInflWqltBod: filteredData.length==0 || avgTpInflWqltBod ===0 ?'0.0':roundNumber(avgTpInflWqltBod / tpInflWqltBodCnt, 1), + tpInflWqltTp: filteredData.length==0 || avgTpInflWqltTp === 0?'0.000':roundNumber(avgTpInflWqltTp / tpInflWqltTpCnt, 3) }, { msrDt : '최대', - efflWqltBod : Math.round(maxEfflWqltBod * 10) / 10?(Math.round(maxEfflWqltBod * 10) / 10).toFixed(1):'0.0', - efflWqltToc : Math.round(maxefflWqltToc * 10) / 10?(Math.round(maxefflWqltToc * 10) / 10).toFixed(1):'0.0', - efflWqltSs : Math.round(maxEfflWqltSs * 10) / 10?(Math.round(maxEfflWqltSs * 10) / 10).toFixed(1):'0.0', - efflWqltTn : Math.round(maxEfflWqltTn * 1000) / 1000?(Math.round(maxEfflWqltTn * 1000) / 1000).toFixed(3):'0.000', - efflWqltTp : Math.round(maxEfflWqltTp * 1000) / 1000?(Math.round(maxEfflWqltTp * 1000) / 1000).toFixed(3):'0.000', - inflAssctBfrWqltBod : Math.round(maxinflAssctBfrWqltBod * 10) / 10?(Math.round(maxinflAssctBfrWqltBod * 10) / 10).toFixed(1):'0.0', - inflAssctBfrWqltTn : Math.round(maxinflAssctBfrWqltTn * 1000) / 1000?(Math.round(maxinflAssctBfrWqltTn * 1000) / 1000).toFixed(3):'0.000', - inflAssctBfrWqltTp : Math.round(maxInflAssctBfrWqltTp * 1000) / 1000?(Math.round(maxInflAssctBfrWqltTp * 1000) / 1000).toFixed(3):'0.000', - inflAssctBfrWqltToc : Math.round(maxinflAssctBfrWqltToc * 10) / 10?(Math.round(maxinflAssctBfrWqltToc * 10) / 10).toFixed(1):'0.0', - inflAssctBfrWqltSs : Math.round(maxinflAssctBfrWqltSs * 10) / 10?(Math.round(maxinflAssctBfrWqltSs * 10) / 10).toFixed(1):'0.0', + efflWqltBod : Math.round(maxEfflWqltBod * 10) / 10?roundNumber(maxEfflWqltBod, 1):'0.0', + efflWqltToc : Math.round(maxefflWqltToc * 10) / 10?roundNumber(maxefflWqltToc, 1):'0.0', + efflWqltCod : Math.round(maxefflWqltCod * 10) / 10?"("+roundNumber(maxefflWqltCod, 1)+")":'(0.0)', + efflWqltSs : Math.round(maxEfflWqltSs * 10) / 10?roundNumber(maxEfflWqltSs, 1):'0.0', + efflWqltTn : Math.round(maxEfflWqltTn * 1000) / 1000?roundNumber(maxEfflWqltTn, 3):'0.000', + efflWqltTp : Math.round(maxEfflWqltTp * 1000) / 1000?roundNumber(maxEfflWqltTp, 3):'0.000', + inflAssctBfrWqltBod : Math.round(maxinflAssctBfrWqltBod * 10) / 10?roundNumber(maxinflAssctBfrWqltBod, 1):'0.0', + inflAssctBfrWqltTn : Math.round(maxinflAssctBfrWqltTn * 1000) / 1000?roundNumber(maxinflAssctBfrWqltTn, 3):'0.000', + inflAssctBfrWqltTp : Math.round(maxInflAssctBfrWqltTp * 1000) / 1000?roundNumber(maxInflAssctBfrWqltTp, 3):'0.000', + inflAssctBfrWqltToc : Math.round(maxinflAssctBfrWqltToc * 10) / 10?roundNumber(maxinflAssctBfrWqltToc, 1):'0.0', + inflAssctBfrWqltCod : Math.round(maxinflAssctBfrWqltCod * 10) / 10?"("+roundNumber(maxinflAssctBfrWqltCod, 1)+")":'(0.0)', + inflAssctBfrWqltSs : Math.round(maxinflAssctBfrWqltSs * 10) / 10?roundNumber(maxinflAssctBfrWqltSs, 1):'0.0', bscFctCd: "", bscFctNm: "", lclgvrnmntNm: "", @@ -249,22 +284,24 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe addr: "", fctCpc: 0, noProcessInflAmnt : roundNumber(maxNoProcessInflAmnt, 0), - infoRnDay: Math.round(maxInfoRnDay * 10) / 10?(Math.round(maxInfoRnDay * 10) / 10).toFixed(1):'0.0', - tpInflWqltBod: Math.round(maxTpInflWqltBod * 10) / 10?(Math.round(maxTpInflWqltBod * 10) / 10).toFixed(1):'0.0', - tpInflWqltTp: Math.round(maxTpInflWqltTp * 1000) / 1000?(Math.round(maxTpInflWqltTp * 1000) / 1000).toFixed(3):'0.000' + infoRnDay: Math.round(maxInfoRnDay * 10) / 10?roundNumber(maxInfoRnDay, 1):'0.0', + tpInflWqltBod: Math.round(maxTpInflWqltBod * 10) / 10?roundNumber(maxTpInflWqltBod, 1):'0.0', + tpInflWqltTp: Math.round(maxTpInflWqltTp * 1000) / 1000?roundNumber(maxTpInflWqltTp, 3):'0.000' }, { msrDt : '최소', - efflWqltBod : Math.round(minEfflWqltBod * 10) / 10?(Math.round(minEfflWqltBod * 10) / 10).toFixed(1) : '0.0', - efflWqltToc : Math.round(minefflWqltToc * 10) / 10?(Math.round(minefflWqltToc * 10) / 10).toFixed(1) : '0.0', - efflWqltSs : Math.round(minEfflWqltSs * 10) / 10?(Math.round(minEfflWqltSs * 10) / 10).toFixed(1) : '0.0', - efflWqltTn : Math.round(minEfflWqltTn * 1000) / 1000?(Math.round(minEfflWqltTn * 1000) / 1000).toFixed(3) : '0.000', - efflWqltTp : Math.round(minEfflWqltTp * 1000) / 1000?(Math.round(minEfflWqltTp * 1000) / 1000).toFixed(3) : '0.000', - inflAssctBfrWqltBod : Math.round(mininflAssctBfrWqltBod * 10) / 10?(Math.round(mininflAssctBfrWqltBod * 10) / 10).toFixed(1) : '0.0', - inflAssctBfrWqltTn : Math.round(mininflAssctBfrWqltTn * 1000) / 1000?(Math.round(mininflAssctBfrWqltTn * 1000) / 1000).toFixed(3) : '0.000', - inflAssctBfrWqltTp : Math.round(minInflAssctBfrWqltTp * 1000) / 1000?(Math.round(minInflAssctBfrWqltTp * 1000) / 1000).toFixed(3) : '0.000', - inflAssctBfrWqltToc : Math.round(mininflAssctBfrWqltToc * 10) / 10?(Math.round(mininflAssctBfrWqltToc * 10) / 10).toFixed(1) : '0.0', - inflAssctBfrWqltSs : Math.round(mininflAssctBfrWqltSs * 10) / 10?(Math.round(mininflAssctBfrWqltSs * 10) / 10).toFixed(1) : '0.0', + efflWqltBod : Math.round(minEfflWqltBod * 10) / 10?roundNumber(minEfflWqltBod, 1) : '0.0', + efflWqltToc : Math.round(minefflWqltToc * 10) / 10?roundNumber(minefflWqltToc, 1) : '0.0', + efflWqltCod : Math.round(minefflWqltCod * 10) / 10?"("+roundNumber(minefflWqltCod, 1)+")" : '(0.0)', + efflWqltSs : Math.round(minEfflWqltSs * 10) / 10?roundNumber(minEfflWqltSs, 1) : '0.0', + efflWqltTn : Math.round(minEfflWqltTn * 1000) / 1000?roundNumber(minEfflWqltTn, 3) : '0.000', + efflWqltTp : Math.round(minEfflWqltTp * 1000) / 1000?roundNumber(minEfflWqltTp, 3) : '0.000', + inflAssctBfrWqltBod : Math.round(mininflAssctBfrWqltBod * 10) / 10?roundNumber(mininflAssctBfrWqltBod, 1) : '0.0', + inflAssctBfrWqltTn : Math.round(mininflAssctBfrWqltTn * 1000) / 1000?roundNumber(mininflAssctBfrWqltTn, 3) : '0.000', + inflAssctBfrWqltTp : Math.round(minInflAssctBfrWqltTp * 1000) / 1000?roundNumber(minInflAssctBfrWqltTp, 3) : '0.000', + inflAssctBfrWqltToc : Math.round(mininflAssctBfrWqltToc * 10) / 10?roundNumber(mininflAssctBfrWqltToc, 1) : '0.0', + inflAssctBfrWqltCod : Math.round(mininflAssctBfrWqltCod * 10) / 10?"("+roundNumber(mininflAssctBfrWqltCod, 1)+")" : '(0.0)', + inflAssctBfrWqltSs : Math.round(mininflAssctBfrWqltSs * 10) / 10?roundNumber(mininflAssctBfrWqltSs, 1) : '0.0', bscFctCd: "", bscFctNm: "", lclgvrnmntNm: "", @@ -273,9 +310,9 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe addr: "", fctCpc: 0, noProcessInflAmnt : roundNumber(minNoProcessInflAmnt, 0), - infoRnDay: Math.round(minInfoRnDay * 10) / 10?'0.0':(Math.round(minInfoRnDay * 10) / 10).toFixed(1), - tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999?(Math.round(minTpInflWqltBod * 10) / 10).toFixed(1):'0.0', - tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999?(Math.round(minTpInflWqltTp * 1000) / 1000).toFixed(3):'0.000' + infoRnDay: Math.round(minInfoRnDay * 10) / 10?'0.0':roundNumber(minInfoRnDay, 1), + tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999?roundNumber(minTpInflWqltBod, 1):'0.0', + tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999?roundNumber(minTpInflWqltTp, 3):'0.000' }, ...filteredData ]; @@ -319,22 +356,29 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe copyYearList.forEach((item) => { excelDownList.push({ 날짜: item.msrDt, - "유입BOD(mg/L)": item.inflAssctBfrWqltBod, - "유입TOC(COD)(mg/L)": item.inflAssctBfrWqltToc, - "유입SS(mg/L)": item.inflAssctBfrWqltSs, - "유입TN(mg/L)": item.inflAssctBfrWqltTn, - "유입TP(mg/L)": item.inflAssctBfrWqltTp, - "유출BOD(mg/L)": item.efflWqltBod, - "유출TOC(COD)(mg/L)": item.efflWqltToc, - "유출SS(mg/L)": item.efflWqltSs, - "유출TN(mg/L)": item.efflWqltTn, - "유출TP(mg/L)": item.efflWqltTp, -/* "강우량(mm/일)": item.infoRnDay?item.infoRnDay.toString():"0.0", */ + "유입BOD(mg/L)": CommaToNumber(item.inflAssctBfrWqltBod), + "유입TOC(COD)(mg/L)": CommaToNumber(item.inflAssctBfrWqltToc), + "유입SS(mg/L)": CommaToNumber(item.inflAssctBfrWqltSs), + "유입TN(mg/L)": CommaToNumber(item.inflAssctBfrWqltTn), + "유입TP(mg/L)": CommaToNumber(item.inflAssctBfrWqltTp), + "유출BOD(mg/L)": CommaToNumber(item.efflWqltBod), + "유출TOC(COD)(mg/L)": CommaToNumber(item.efflWqltToc), + "유출SS(mg/L)": CommaToNumber(item.efflWqltSs), + "유출TN(mg/L)": CommaToNumber(item.efflWqltTn), + "유출TP(mg/L)": CommaToNumber(item.efflWqltTp), + "강우량(mm/일)": CommaToNumber(item.infoRnDay?item.infoRnDay.toString():"0.0"), }); }); } if (excelDownList && excelDownList.length > 0) { - downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: searchYear+'년 '+fcltyName + ' 수질현황', sheetNameArray: [fcltyName + ' 수질현황'], headerRange: 'A1:K1' }); + downloadExcelFormat( + { data: JSON.parse(JSON.stringify(excelDownList)) + , fileName: searchYear+'년 '+fcltyName + ' 수질현황' + , sheetNameArray: [fcltyName + ' 수질현황'] + , headerRange: 'A1:L1' + , decimalArray1: [1,2,3,6,7,8,11] + , decimalArray3: [4,5,9,10] + }); } else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) { alert('다운받을 데이터가 없습니다.'); } @@ -364,7 +408,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe - {msrmtDate != yesterDayStr?.replaceAll('-','')?

※전날 데이터 결측으로 인해 가장 최근 데이터 표출함

: ''} + {msrmtDate != yesterDayStr?.replaceAll('-','') ? ( + + ) : null}
@@ -410,7 +456,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
-
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

-
@@ -441,7 +483,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
-
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

-
@@ -472,7 +510,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
-
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

- ☞ 청천시 : 강우량이 3mm미만의 날 -
+ @@ -504,7 +538,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
-
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

- ☞ 강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날 -
+ diff --git a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx index 98f5ba57a..a107dfd2a 100644 --- a/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx +++ b/apps/fo/app/pages/(with-layout)/facilityWaterQlty/page.tsx @@ -1,13 +1,19 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 수질현황 + * + * - 시설별 수질 현황을 조회조건대로 추출하여 표로 보여주는 화면. + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import type { FacilityWaterQltyProps } from "@/app/store/facilityWaterQlty"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; +import LoadingOverlay from "@common/business_components/ui/loadingBar"; import { useCallback, useEffect, useRef, useState } from "react"; import WaterQualityModal from "./modal/page"; -import type { FacilityWaterQltyProps } from "@/app/store/facilityWaterQlty"; -import LoadingOverlay from "@common/business_components/ui/loadingBar"; export default function ProcessFacilitySearch() { const { Common @@ -138,12 +144,23 @@ export default function ProcessFacilitySearch() { useEffect(() => { if (excelList && excelList.length > 0) { - downloadExcel({ + downloadExcelFormat( + { + data: excelList as unknown as JSON[], + fileName: '시설별 수질현황', + sheetNameArray: ['시설별 수질현황'], + headerRange: 'A1:T1', + decimalArray1:[10,11,12,15,16,17], + decimalArray3:[13,14,18,19] + } + ); + + /* downloadExcel({ data: excelList as unknown as JSON[], fileName: '시설별 수질현황', sheetNameArray: ['시설별 수질현황'], headerRange: 'A1:T1' - }); + }); */ } }, [excelList]); @@ -190,7 +207,7 @@ export default function ProcessFacilitySearch() {
- index !== undefined && cellClick(index)} headName={"시설별 수질현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total<10?facilityWaterQltyList.length:total} resetPageNo={resetPage} onPageChange={handlePageChange} /> + index !== undefined && cellClick(index)} headName={"시설별 수질현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total<10?facilityWaterQltyList.length:total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
diff --git a/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx b/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx index 5a38ad8f0..30b97c945 100644 --- a/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/flowRate/modal/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 유량현황(모달)) + * + * - 선택한 시설의 유량 정보를 하루 단위로 표로 출력해주는 모달 + */ + +"use client" import FacilityTermModalHeader from "@/app/components/common/FacilityTermModalHeader"; import { useFoStore } from "@/app/store"; import type { FlowRateModalInterface, modalExcelType } from "@/app/store/flowRate"; @@ -8,6 +14,8 @@ import { useCallback, useEffect, useRef, useState } from "react"; import type { ReturnType } from "../../../../components/common/FacilityTermModalHeader"; import { roundUp } from "@/app/store/common"; import { roundNumber } from "@/app/components/common/DataForm"; +import UnderComment from "@/app/components/common/UnderComment"; +import CommaToNumber from "@/app/components/common/CommaToNumber"; const tabList = [ { value: 'tab_term_year', label: '연간' }, @@ -179,11 +187,11 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st copyYearList.forEach((item) => { excelDownList.push({ "날짜": item.msrDt, - "총유입량(m³/일)": item.totInflAmnt, - "하수유입량(m³/일)": item.inflAmnt, - "연계처리량(m³/일)": item.sumFlow, - "총인반류수량(m³/일)": item.returnAmnt, - "방류량(m³/일)": item.efflAmnt, + "총유입량(m³/일)": CommaToNumber(item.totInflAmnt), + "하수유입량(m³/일)": CommaToNumber(item.inflAmnt), + "연계처리량(m³/일)": CommaToNumber(item.sumFlow), + "총인반류수량(m³/일)": CommaToNumber(item.returnAmnt), + "방류량(m³/일)": CommaToNumber(item.efflAmnt), /* "강우량(mm/일)": item.infoRnDay, */ }); }); @@ -225,10 +233,6 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st boldArray={[0,1,2]} /> -
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

-
@@ -253,10 +257,6 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st boldArray={[0,1,2]} /> -
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

-
@@ -281,10 +281,6 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st boldArray={[0,1,2]} /> -
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

-
@@ -309,11 +305,6 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st boldArray={[0,1,2]} /> -
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

- ☞ 청천시 : 강우량이 3mm미만의 날 -
@@ -328,11 +319,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
{}} className="h-[370px]" boldArray={[0,1,2]}/>
-
- ☞ 미처리하수량 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​/강우시 일별유입BOD)​

- ☞ 음수값 발생시 제외(null, 평균값 산정시 제외)

- ☞ 강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날 -
+
diff --git a/apps/fo/app/pages/(with-layout)/flowRate/page.tsx b/apps/fo/app/pages/(with-layout)/flowRate/page.tsx index bec068858..5b53f51a2 100644 --- a/apps/fo/app/pages/(with-layout)/flowRate/page.tsx +++ b/apps/fo/app/pages/(with-layout)/flowRate/page.tsx @@ -1,12 +1,18 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 유량현황 + * + * - 시설별 유량 현황을 조회조건대로 추출하여 표로 보여주는 화면. + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; -import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; +import type { ExcelType } from "@/app/store/flowRate"; +import { ContentsDiv, downloadExcelFormat, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; +import LoadingOverlay from "@common/business_components/ui/loadingBar"; import { useCallback, useEffect, useRef, useState } from "react"; import FlowRateModal from "./modal/page"; -import type { ExcelType } from "@/app/store/flowRate"; -import LoadingOverlay from "@common/business_components/ui/loadingBar"; export default function ProcessFacilitySearch() { const {Common @@ -134,7 +140,7 @@ export default function ProcessFacilitySearch() { useEffect(() => { if (excelList && excelList.length > 0) { - downloadExcel({ data: JSON.parse(JSON.stringify(excelList)), fileName: '시설별 유량현황', sheetNameArray: ['시설별 유량현황'], headerRange: 'A1:O1' }); + downloadExcelFormat({ data: JSON.parse(JSON.stringify(excelList)), fileName: '시설별 유량현황', sheetNameArray: ['시설별 유량현황'], headerRange: 'A1:O1', decimalArray0: [9,10,11,12,13,14] }); } else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) { alert('다운받을 데이터가 없습니다.'); } @@ -192,7 +198,7 @@ export default function ProcessFacilitySearch() {
- index !== undefined && cellClick(index)} headName={"시설별 유량현황"} tableData={flowRateList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} /> + index !== undefined && cellClick(index)} headName={"시설별 유량현황"} tableData={flowRateList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
diff --git a/apps/fo/app/pages/(with-layout)/planSewage/page.tsx b/apps/fo/app/pages/(with-layout)/planSewage/page.tsx index 00539da13..1f1768af5 100644 --- a/apps/fo/app/pages/(with-layout)/planSewage/page.tsx +++ b/apps/fo/app/pages/(with-layout)/planSewage/page.tsx @@ -1,11 +1,24 @@ -"use client" +/** + * 처리시설 연간 운영현황 - 계획하수량 산정지표 현황 + * + * - 시설별 여유용량, 변동부하율, 분류식화율을 조회조건대로 추출하여 표로 보여주는 화면. + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; import { downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { useCallback, useEffect, useRef, useState } from "react"; import LoadingOverlay from "@common/business_components/ui/loadingBar"; - +import UnderComment from "@/app/components/common/UnderComment"; + +const commentArray = [ + "여유용량 = 하수처리시설 시설용량 – 건기시 유입유량(평균)​", + "변동부하율 = 건기시 일최대 유량/일평균​유량(기준 최근 3개년)​", + "분류식화율 = 분류식지역 면적(㎢) / 처리​구역 면적합계(㎢) ×100" +] + export default function PlanSewage() { const {Common ,PlanSewage @@ -135,12 +148,14 @@ export default function PlanSewage() { default: if(sidoValue !== '0') nameCd = sidoValue; if(sigunValue !== '0') nameCd = sigunValue; - partStr = envPartValue !== '0' ? envPartValue:partValue; - break; + partStr = envPartValue !== '0' ? envPartValue:partValue; + break; } if (partStr.length > 1 || fcltCpct !== '0' || operationValue!== '0' ||nameCd ||(fcltyName.trim() !== "" && fcltyName.trim() !== null)) { searchPlanSewageList(pageNo, pageCnt, searchYear, partStr, nameCd || '0', fcltCpct, operationValue, fcltyName.trim() !== "" || fcltyName.trim() !== null ? fcltyName : undefined); } else { + // G로 넘기면 데이터가 안떠서 환경청 전체로 넘기면 전체를 추출하기위해서... + partValue = partValue==='G'?'A':partValue; searchPlanSewageList(pageNo, pageCnt, searchYear, partValue); } }, [operationValue, fcltyName, searchPlanSewageList, searchYear, fcltCpct]); @@ -191,13 +206,9 @@ export default function PlanSewage() {
- -
-
- ☞ 여유용량 = 하수처리시설 시설용량 – 건기시 유입유량(평균)​
- ☞ 변동부하율 = 건기시 일최대 유량/일평균​유량(기준 최근 3개년)​
- ☞ 분류식화율 = 분류식지역 면적(㎢) / 처리​구역 면적합계(㎢) ×100
+
+
diff --git a/apps/fo/app/pages/(with-layout)/processArea/modal/page.tsx b/apps/fo/app/pages/(with-layout)/processArea/modal/page.tsx index 06e26bac6..bc7c2651b 100644 --- a/apps/fo/app/pages/(with-layout)/processArea/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processArea/modal/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 처리시설 현황 - 처리구역정보(모달) + * + * - 선택한 시설의 계획정보를 가져와 표로 출력해주는 모달 + */ + +"use client" import { useFoStore } from "@/app/store"; import { UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; diff --git a/apps/fo/app/pages/(with-layout)/processArea/page.tsx b/apps/fo/app/pages/(with-layout)/processArea/page.tsx index 24a30d910..fc571c665 100644 --- a/apps/fo/app/pages/(with-layout)/processArea/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processArea/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 처리시설 현황 - 처리구역정보(메인) + * + * - 시설계획 정보를 조회조건대로 추출하여 표로 보여주는 화면. + */ + +"use client" import { useFoStore } from "@/app/store"; import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; @@ -157,7 +163,7 @@ export default function ProcessArea() {
- index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList} headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} /> + index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList} headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
diff --git a/apps/fo/app/pages/(with-layout)/processFacility/modal/page.tsx b/apps/fo/app/pages/(with-layout)/processFacility/modal/page.tsx index b27984df7..fbda7a140 100644 --- a/apps/fo/app/pages/(with-layout)/processFacility/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processFacility/modal/page.tsx @@ -1,8 +1,13 @@ -"use client" -import { roundNumber } from "@/app/components/common/DataForm"; +/** + * 처리시설 현황 - 처리시설 시설정보(모달)) + * + * - 선택한 시설의 정보와 시설이력정보를 보여주는 모달. + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/dashboard"; -import { downloadExcel, filePickedBlobArray, UITab, UiTable } from "@common/business_components/ui"; +import { downloadExcelFormat, filePickedBlobArray, UITab, UiTable } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; import { TabsContent @@ -131,12 +136,12 @@ export default function ProcessFacilityInfoModal(props: ModalType) { "준공일": item.cmplDt, "시운전완료일": item.trlrnCmplDt, "가동개시일": item.rnDt, - "시설용량(m³/일)": roundNumber(item.fctCpc,0), + "시설용량(m³/일)": item.fctCpc&&item.fctCpc.toString().trim()!=''?Number(item.fctCpc.toString().replaceAll(',','')):'', }); }); } if (excelDownList && excelDownList.length > 0) { - downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.fcltyName + ' 시설이력관리', sheetNameArray: [props.fcltyName + ' 시설이력관리'], headerRange: 'A1:I1' }); + downloadExcelFormat({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.fcltyName + ' 시설이력관리', sheetNameArray: [props.fcltyName + ' 시설이력관리'], headerRange: 'A1:I1' }); } else if (gridListFcltyHistInfo.length == 0) { alert('다운받을 데이터가 없습니다.'); } diff --git a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx index 381c64ea5..0e9085cb4 100644 --- a/apps/fo/app/pages/(with-layout)/processFacility/page.tsx +++ b/apps/fo/app/pages/(with-layout)/processFacility/page.tsx @@ -1,11 +1,17 @@ -"use client" -import { HeadMakeColSpan } from "@/app/components/common/HeadMakeColSpan"; +/** + * 처리시설 현황 - 처리시설 시설정보(메인) + * + * - 시설별 정보를 조회조건대로 추출하여 표로 보여주는 화면. + */ + +"use client" +import UnderComment from "@/app/components/common/UnderComment"; import { useFoStore } from "@/app/store"; import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; +import LoadingOverlay from "@common/business_components/ui/loadingBar"; import { useCallback, useEffect, useRef, useState } from "react"; import ProcessFacilityInfoModal from "./modal/page"; -import LoadingOverlay from "@common/business_components/ui/loadingBar"; export default function ProcessFacilitySearch() { const {Common @@ -274,13 +280,13 @@ export default function ProcessFacilitySearch() { total={total} resetPageNo={resetPage} onPageChange={changePage} + widthFixed={true} > - + - ※계획유입수질 및 설계유입수질은 해당 BOD를 나타냄 {selectedRow !== null && ( (false); // 표 너비 - const [widthSize, setWidthSize] = useState("w-[120%]"); + const [widthSize, setWidthSize] = useState("w-[130%]"); // 구분별 그리드 헤더 const [upheadList, setUpheadList] = useState(upHeadList1); // 용량별 @@ -149,7 +161,7 @@ export default function Rdi() { }, [operationValue, fcltyName, searchRdiList, searchYear, fcltCpct]); const chkVal = useCallback((returntype:ReturnType) => { - setWidthSize(returntype.partValue=='A' ?"w-[120%]":"w-[130%]") + setWidthSize(returntype.partValue=='A' ?"w-[130%]":"w-[150%]") setUpheadList(returntype.partValue == 'R' ? upHeadList2 : returntype.partValue == 'G'?upHeadList3:upHeadList1); setResetPage(true); }, [upHeadList1, upHeadList2, upHeadList3]); @@ -195,10 +207,9 @@ export default function Rdi() {
- +
- ※ 강우시 총 추정유입량 = 청천시 유입하수량 + RDII 추정값

- ※ 주) 처리장 유입부에서 측정된 유량 및 수질조사 자료를 기준으로 산정된 결과임 +
diff --git a/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx b/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx index 37cadc7c6..a2ffb386a 100644 --- a/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/sewageOccur/modal/page.tsx @@ -1,4 +1,10 @@ -"use client" +/** + * 운영실태 - 오수발생량 추정(모달) + * + * - 선택한 시설의 물사용량과 오수전환율을 가지고 오수발생량 추정 데이터를 월별로 보여주는 모달. + */ + +"use client" import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { modalTableType } from "@/app/store/sewageOccur"; @@ -142,7 +148,7 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd - {}} boldArray={[0, 1, 2]}> + {}} boldArray={[0, 1, 2]} widthFixed={true} > diff --git a/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx b/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx index 885af7567..6fb01efb3 100644 --- a/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx +++ b/apps/fo/app/pages/(with-layout)/sewageOccur/page.tsx @@ -1,4 +1,11 @@ -"use client" +/** + * 운영실태 - 오수발생량 추정(메인) + * + * - 조회조건대로 시설별 물 사용량과 오수전환율을 기반으로 오수발생량 추정치를 표로 보여주는 화면 + * - 현재 물사용량의 경우 연계받는 데이터가 아닌 연 하수유입량의 65%로 가정하고 계산함 + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; @@ -222,7 +229,7 @@ export default function PlanSewage() {
- index !== undefined && cellClick(index)} headName={"오수발생량 추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} /> + index !== undefined && cellClick(index)} headName={"오수발생량 추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
diff --git a/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx b/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx index 1d4ea2310..2e0f5f27e 100644 --- a/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx +++ b/apps/fo/app/pages/(with-layout)/underWaterInput/modal/page.tsx @@ -1,4 +1,11 @@ -"use client" +/** + * 운영실태 - 지하수 유입량 추정(모달) + * + * - 선택한 시설의 월별 청천시 실제 하수유입량, 오수발생량으로 지하수 유입량을 보여주는 모달 + * - 청천시 실제 하수유입량 - 오수발생량으로 지하수유입량을 추정한다. + */ + +"use client" import { roundNumber } from "@/app/components/common/DataForm"; import { useFoStore } from "@/app/store"; import type { UnderWaterInputModalProps } from "@/app/store/underWaterInput/types"; @@ -166,6 +173,7 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea onPageChange={() => {}} className="h-[200px]" boldArray={[0,1,2]} + widthFixed={true} /> @@ -233,6 +241,7 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea onPageChange={() => { } } className="h-[500px]" boldArray={[0,1,2]} + widthFixed={true} /> @@ -291,6 +300,7 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea onPageChange={() => {}} className="h-[500px]" boldArray={[0,1,2]} + widthFixed={true} /> diff --git a/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx b/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx index 2126a31a0..a621611b7 100644 --- a/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx +++ b/apps/fo/app/pages/(with-layout)/underWaterInput/page.tsx @@ -1,4 +1,12 @@ -"use client" +/** + * 운영실태 - 지하수 유입량 추정(메인) + * + * - 조회조건대로 시설별 연간, 하절기, 동절기 단위로 지하수 유입량 추정을 표로 보여주는 화면 + * - 청천시 실제 하수유입량 - 오수발생량으로 지하수유입량을 추정한다. + * - 연간 지하수 유입량이 하수유입량보다 20% 클 경우 초과유입으로 아닌 경우 적정으로 적정여부를 표시한다. + */ + +"use client" import { useFoStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common"; import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SearchInput, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components"; @@ -220,7 +228,7 @@ export default function UnderWaterInput() {
- index !== undefined && cellClick(index)} headName={"지하수유입량 추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} /> + index !== undefined && cellClick(index)} headName={"지하수유입량 추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true}/>
※적정여부 = 연간 지하수유입량/연평균 유입하수량*100

diff --git a/apps/fo/app/store/common/index.tsx b/apps/fo/app/store/common/index.tsx index 1c9b06991..e75492d52 100644 --- a/apps/fo/app/store/common/index.tsx +++ b/apps/fo/app/store/common/index.tsx @@ -225,6 +225,8 @@ export const qltyDataSetting = (value: number, day : number, digit: number) => { return value > 0 ? roundUp((value/day), digit).toFixed(digit) : toZero; }; +export const COD_YEAR = 2021; + /** * STORE - API */ @@ -392,6 +394,7 @@ export type CommonType = { selectFlowPanel: SelectDataType[]; selectEnvPartData: envPartSelectDataType[]; btnClass: string; + COD_YEAR : number; }; auth: { @@ -421,6 +424,7 @@ export const commonState: CommonType = { selectFlowPanel: selectFlowPanel, selectEnvPartData: selectEnvPartData, btnClass: "p-4 m-2 !mr-10 text-white rounded-sm text-lg font-medium", + COD_YEAR : COD_YEAR, }, auth: { diff --git a/apps/fo/app/store/dashboard/index.tsx b/apps/fo/app/store/dashboard/index.tsx index b263c2288..906ce8e3b 100644 --- a/apps/fo/app/store/dashboard/index.tsx +++ b/apps/fo/app/store/dashboard/index.tsx @@ -26,6 +26,7 @@ export type TableUpperProps = { row? : number; rowSpan?: number; colSpan?: number; + widthPercent? : number; } // ===TAB1 @@ -52,9 +53,9 @@ export type planFcltyListProps = { export type OperationalStatusListProps = { flowRate : string, waterQlty : string, - yearAvg : number | string | '', - yearMax : number | string | '', - yearMin : number | string | '', + yearAvg : number | '', + yearMax : number | '', + yearMin : number | '', summerAll : number | string | '', summerThree : number | string | '', summerRain : number | string | '', @@ -357,12 +358,12 @@ const upHeadListOperationStatus : TableUpperProps[] = [ ] const upHeadListRainManage : TableUpperProps[] = [ - { id: "rainItem", title: "강우량", row:0, rowSpan:2 }, - { id: "rainRate", title: "강우조건\n비율(%)", row:0, rowSpan:2, align: "right" }, - { id: "rainDay", title: "일수", row:0, rowSpan:2, align: "right" }, + { id: "rainItem", title: "강우량", row:0, rowSpan:2, widthPercent: 8 }, + { id: "rainRate", title: "강우조건\n비율(%)", row:0, rowSpan:2, align: "right", widthPercent: 5 }, + { id: "rainDay", title: "일수", row:0, rowSpan:2, align: "right", widthPercent: 5 }, { id: "A", title: "유입(㎥/일)", row:0, colSpan:2 }, - { id: "inflAmnt", title: "유입유량", row:1, align: "right" }, - { id: "fctCpc", title: "시설용량대비", row:1, align: "right" }, + { id: "inflAmnt", title: "유입유량", row:1, align: "right", widthPercent: 6 }, + { id: "fctCpc", title: "시설용량대비", row:1, align: "right", widthPercent: 6 }, { id: "B", title: "설계유입수질(㎎/L)", row:0, colSpan:5 }, { id: "dsInflWqltBod", title: "BOD", row:1, align: "right" }, { id: "dsInflWqltCod", title: "TOC\n(COD)", row:1, align: "right" }, @@ -404,7 +405,7 @@ const upHeadListDrainageEquipment : TableUpperProps[] = [ { id: "etc", title: "비고", row:0, upName:"upChangeRe7", upSequnce:1 }, ] -let operationalStatusList : OperationalStatusListProps[] = [ +const operationalStatusListOrg : OperationalStatusListProps[] = [ { flowRate : '유량\n(㎥/일)', waterQlty : '유입', @@ -753,31 +754,40 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl // (0) 전체변수 let summerDay = 0; + let noNullSummerDay = 0; let totalInflBodAvgSummer = 0; let totalInflTnAvgSummer = 0; let totalInflTpAvgSummer = 0; let totalEfflBodAvgSummer = 0; let totalEfflTnAvgSummer = 0; let totalEfflTpAvgSummer = 0; + let totalTpInflAvgSummer = 0; let winterDay = 0; + let noNullWinterDay = 0; let totalInflBodAvgWinter = 0; let totalInflTnAvgWinter = 0; let totalInflTpAvgWinter = 0; let totalEfflBodAvgWinter = 0; let totalEfflTnAvgWinter = 0; let totalEfflTpAvgWinter = 0; + let totalTpInflAvgWinter = 0; // 전체 대상 qltyData.forEach((item: any) => { const month = item.msrDt.substring(4, 6); // 월 추출 if(month === '01' || month === '02'){ + winterDay += 1; + if(item.tpInflWqltTp != null && item.tpInflWqltTp != 0){ + noNullWinterDay+=1; + } const inflbod = nullToZero(item.inflAssctBfrWqltBod); const infltn = nullToZero(item.inflAssctBfrWqltTn); const infltp = nullToZero(item.inflAssctBfrWqltTp); const effbod = nullToZero(item.efflWqltBod); const efftn = nullToZero(item.efflWqltTn); const efftp = nullToZero(item.efflWqltTp); + const tpInfl = nullToZero(item.tpInflWqltTp); totalInflBodAvgWinter += inflbod; totalInflTnAvgWinter += infltn; @@ -785,15 +795,19 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl totalEfflBodAvgWinter += effbod; totalEfflTnAvgWinter += efftn; totalEfflTpAvgWinter += efftp; - winterDay += 1; + totalTpInflAvgWinter += tpInfl; }else if(month === '06' || month === '07' || month === '08'){ summerDay += 1; + if(item.tpInflWqltTp != null && item.tpInflWqltTp != 0){ + noNullSummerDay+=1; + } const inflbod = nullToZero(item.inflAssctBfrWqltBod); const infltn = nullToZero(item.inflAssctBfrWqltTn); const infltp = nullToZero(item.inflAssctBfrWqltTp); const effbod = nullToZero(item.efflWqltBod); const efftn = nullToZero(item.efflWqltTn); const efftp = nullToZero(item.efflWqltTp); + const tpInfl = nullToZero(item.tpInflWqltTp); totalInflBodAvgSummer += inflbod; totalInflTnAvgSummer += infltn; @@ -801,6 +815,7 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl totalEfflBodAvgSummer += effbod; totalEfflTnAvgSummer += efftn; totalEfflTpAvgSummer += efftp; + totalTpInflAvgSummer += tpInfl; } }); @@ -811,6 +826,10 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl orgData[9].winterAll = qltyDataSetting(totalInflTpAvgWinter, winterDay, 3); orgData[10].winterAll = qltyDataSetting(totalEfflTpAvgWinter, winterDay, 3); + //총인설비 + orgData[11].winterAll = qltyDataSetting(totalTpInflAvgWinter, noNullWinterDay, 3); + orgData[12].winterAll = qltyDataSetting(totalEfflTpAvgWinter, winterDay, 3); + orgData[5].summerAll = qltyDataSetting(totalInflBodAvgSummer, summerDay, 1); orgData[6].summerAll = qltyDataSetting(totalEfflBodAvgSummer, summerDay, 1); orgData[7].summerAll = qltyDataSetting(totalInflTnAvgSummer, summerDay, 3); @@ -818,10 +837,16 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl orgData[9].summerAll = qltyDataSetting(totalInflTpAvgSummer, summerDay, 3); orgData[10].summerAll = qltyDataSetting(totalEfflTpAvgSummer, summerDay, 3); + //총인설비 + orgData[11].summerAll = qltyDataSetting(totalTpInflAvgSummer, noNullSummerDay, 3); + orgData[12].summerAll = qltyDataSetting(totalEfflTpAvgSummer, summerDay, 3); + // (1) 청천시 변수 // (1-1) 날짜 count let chungchunSummerDay = 0; let chungchunWinterDay = 0; + let noNullChungchunSummerDay = 0; + let noNullChungchunWinterDay = 0; // (1-2) 하절기 let chungchunInflBodAvgSummer = 0; @@ -830,17 +855,21 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl let chungchunEfflBodAvgSummer = 0; let chungchunEfflTnAvgSummer = 0; let chungchunEfflTpAvgSummer = 0; + let chungchunTpInflAvgSummer = 0; // (1-3) 동절기 (최대, 최소, 평균 다 필요) let chungchunInflBodAvg = 0; let chungchunInflTnAvg = 0; let chungchunInflTpAvg = 0; + let chungchunTpInflAvg = 0; let chungchunInflBodMax = 0; let chungchunInflTnMax= 0; let chungchunInflTpMax = 0; + let chungchunTpInflMax = 0; let chungchunInflBodMin = 99999999; let chungchunInflTnMin = 99999999; let chungchunInflTpMin = 99999999; + let chungchunTpInflMin = 99999999; let chungchunEfflBodAvg = 0; let chungchunEfflTnAvg = 0; @@ -857,6 +886,9 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl const month = item.msrDt.substring(4, 6); // 월 추출 if(month === '01' || month === '02'){ chungchunWinterDay += 1; + if(item.tpInflWqltTp != null && item.tpInflWqltTp != 0){ + noNullChungchunWinterDay+=1; + } const inflbod = nullToZero(item.inflAssctBfrWqltBod); const infltn = nullToZero(item.inflAssctBfrWqltTn); @@ -864,10 +896,12 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl const effbod = nullToZero(item.efflWqltBod); const efftn = nullToZero(item.efflWqltTn); const efftp = nullToZero(item.efflWqltTp); + const tpInfl = nullToZero(item.tpInflWqltTp); chungchunInflBodAvg += inflbod; chungchunInflTnAvg += infltn; chungchunInflTpAvg += infltp; + chungchunTpInflAvg += tpInfl; chungchunEfflBodAvg += effbod; chungchunEfflTnAvg += efftn; chungchunEfflTpAvg += efftp; @@ -875,6 +909,7 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl if(chungchunInflBodMax < inflbod) chungchunInflBodMax = inflbod; if(chungchunInflTnMax < infltn) chungchunInflTnMax = infltn; if(chungchunInflTpMax < infltp) chungchunInflTpMax = infltp; + if(chungchunTpInflMax < tpInfl) chungchunTpInflMax = tpInfl; if(chungchunEfflBodMax < effbod) chungchunEfflBodMax = effbod; if(chungchunEfflTnMax < efftn) chungchunEfflTnMax = efftn; if(chungchunEfflTpMax < efftp) chungchunEfflTpMax = efftp; @@ -882,11 +917,15 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl if(chungchunInflBodMin > inflbod) chungchunInflBodMin = inflbod; if(chungchunInflTnMin > infltn) chungchunInflTnMin = infltn; if(chungchunInflTpMin > infltp) chungchunInflTpMin = infltp; + if(chungchunTpInflMin > tpInfl) chungchunTpInflMin = tpInfl; if(chungchunEfflBodMin > effbod) chungchunEfflBodMin = effbod; if(chungchunEfflTnMin > efftn) chungchunEfflTnMin = efftn; if(chungchunEfflTpMin > efftp) chungchunEfflTpMin = efftp; }else if(month === '06' || month === '07' || month === '08'){ chungchunSummerDay += 1; + if(item.tpInflWqltTp != null && item.tpInflWqltTp != 0){ + noNullChungchunSummerDay+=1; + } const inflbod = nullToZero(item.inflAssctBfrWqltBod); const infltn = nullToZero(item.inflAssctBfrWqltTn); @@ -894,6 +933,7 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl const effbod = nullToZero(item.efflWqltBod); const efftn = nullToZero(item.efflWqltTn); const efftp = nullToZero(item.efflWqltTp); + const tpInfl = nullToZero(item.tpInflWqltTp); chungchunInflBodAvgSummer += inflbod; chungchunInflTnAvgSummer += infltn; @@ -901,6 +941,7 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl chungchunEfflBodAvgSummer += effbod; chungchunEfflTnAvgSummer += efftn; chungchunEfflTpAvgSummer += efftp; + chungchunTpInflAvgSummer += tpInfl; } }); @@ -913,6 +954,10 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl orgData[9].summerRain = qltyDataSetting(chungchunInflTpAvgSummer, chungchunSummerDay, 3); orgData[10].summerRain = qltyDataSetting(chungchunEfflTpAvgSummer, chungchunSummerDay, 3); + // 총인설비 + orgData[11].summerRain = qltyDataSetting(chungchunTpInflAvgSummer, noNullChungchunSummerDay, 3); + orgData[12].summerRain = qltyDataSetting(chungchunEfflTpAvgSummer, chungchunSummerDay, 3); + // 동절기 orgData[5].winterSunnyAvg = qltyDataSetting(chungchunInflBodAvg, chungchunWinterDay, 1); orgData[6].winterSunnyAvg = qltyDataSetting(chungchunEfflBodAvg, chungchunWinterDay, 1); @@ -921,12 +966,18 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl orgData[9].winterSunnyAvg = qltyDataSetting(chungchunInflTpAvg, chungchunWinterDay, 3); orgData[10].winterSunnyAvg = qltyDataSetting(chungchunEfflTpAvg, chungchunWinterDay, 3); + // 총인설비 + orgData[11].winterSunnyAvg = qltyDataSetting(chungchunTpInflAvg, noNullChungchunWinterDay, 3); + orgData[12].winterSunnyAvg = qltyDataSetting(chungchunInflTpAvg, chungchunWinterDay, 3); + orgData[5].winterSunnyMax = roundUp(chungchunInflBodMax, 1).toFixed(1); orgData[6].winterSunnyMax = roundUp(chungchunEfflBodMax, 1).toFixed(1); orgData[7].winterSunnyMax = roundUp(chungchunInflTnMax, 3).toFixed(3); orgData[8].winterSunnyMax = roundUp(chungchunEfflTnMax, 3).toFixed(3); orgData[9].winterSunnyMax = roundUp(chungchunInflTpMax, 3).toFixed(3); orgData[10].winterSunnyMax = roundUp(chungchunEfflTpMax, 3).toFixed(3); + orgData[11].winterSunnyMax = roundUp(chungchunTpInflMax, 3).toFixed(3); + orgData[12].winterSunnyMax = roundUp(chungchunInflTpMax, 3).toFixed(3); orgData[5].winterSunnyMin = chungchunInflBodMin === 99999999 ? '0.0' : roundUp(chungchunInflBodMin, 1).toFixed(1); orgData[6].winterSunnyMin = chungchunEfflBodMin === 99999999 ? '0.0' : roundUp(chungchunEfflBodMin, 1).toFixed(1); @@ -934,9 +985,12 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl orgData[8].winterSunnyMin = chungchunEfflTnMin === 99999999 ? '0.000' : roundUp(chungchunEfflTnMin, 3).toFixed(3); orgData[9].winterSunnyMin = chungchunInflTpMin === 99999999 ? '0.000' : roundUp(chungchunInflTpMin, 3).toFixed(3); orgData[10].winterSunnyMin = chungchunEfflTpMin === 99999999 ? '0.000' : roundUp(chungchunEfflTpMin, 3).toFixed(3); + orgData[11].winterSunnyMin = chungchunTpInflMin === 99999999 ? '0.000' : roundUp(chungchunTpInflMin, 3).toFixed(3); + orgData[12].winterSunnyMin = chungchunInflTpMin === 99999999 ? '0.000' : roundUp(chungchunInflTpMin, 3).toFixed(3); // 강우시 변수 let rainSummerDay = 0; + let noNullRainSummerDay = 0; let rainInflBodAvg = 0; let rainInflTnAvg = 0; @@ -944,12 +998,16 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl let rainEfflBodAvg = 0; let rainEfflTnAvg = 0; let rainEfflTpAvg = 0; + let rainTpInflAvg = 0; // 강우시 qltyRainData.forEach((item: any) => { const month = item.msrDt.substring(4, 6); // 월 추출 if(month === '06' || month === '07' || month === '08'){ rainSummerDay += 1; + if(item.tpInflWqltTp != null && item.tpInflWqltTp != 0){ + noNullRainSummerDay+=1; + } const inflbod = nullToZero(item.inflAssctBfrWqltBod); const infltn = nullToZero(item.inflAssctBfrWqltTn); @@ -957,6 +1015,7 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl const effbod = nullToZero(item.efflWqltBod); const efftn = nullToZero(item.efflWqltTn); const efftp = nullToZero(item.efflWqltTp); + const tpInfl = nullToZero(item.tpInflWqltTp); rainInflBodAvg += inflbod; rainInflTnAvg += infltn; @@ -964,6 +1023,7 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl rainEfflBodAvg += effbod; rainEfflTnAvg += efftn; rainEfflTpAvg += efftp; + rainTpInflAvg += tpInfl; } }); @@ -974,6 +1034,11 @@ const calcWaterQltyData = async (data: any[], searchYear : string|undefined, fcl orgData[8].summerThree = qltyDataSetting(rainEfflTnAvg, rainSummerDay, 3); orgData[9].summerThree = qltyDataSetting(rainInflTpAvg, rainSummerDay, 3); orgData[10].summerThree = qltyDataSetting(rainEfflTpAvg, rainSummerDay, 3); + + // 총인설비 + orgData[11].summerThree = qltyDataSetting(rainTpInflAvg, noNullRainSummerDay, 3); + orgData[12].summerThree = qltyDataSetting(rainInflTpAvg, rainSummerDay, 3); + return orgData; } else { return orgData; @@ -1084,7 +1149,7 @@ export const dashBoardInitState:DashBoardType = { OperationStatus : { isInit : false, upHeadListOperationStatus : upHeadListOperationStatus, - operationalStatusList : operationalStatusList, + operationalStatusList : operationalStatusListOrg, isLoadingOperationStatus : false, }, @@ -1181,9 +1246,7 @@ const changeValue=(operationalStatus, data, keyTxt = 'INFL_AMNT')=>{ operationalStatus.winterSunnyAvg = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN"))? data.winterSunny?Number(Math.round(data.winterSunny["AVG_" + keyTxt] * 1000) / 1000).toFixed(3).toString():'': data.winterSunny["AVG_" + keyTxt] : ''; operationalStatus.winterSunnyMax = data.winterSunny ? (keyTxt.includes('_TP') || keyTxt.includes("_TN"))? data.winterSunny?Number(Math.round(data.winterSunny["MAX_" + keyTxt] * 1000) / 1000).toFixed(3).toString():'': data.winterSunny["MAX_" + keyTxt] : ''; // 지하수 - operationalStatus.groundWaterAvg = 10; - operationalStatus.groundWaterSummer = 11; - operationalStatus.groundWaterWinter = 12; + // 오염물질 // RDII 추정 = 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) const summerLowFlow = data.summerBod && data.summerBod.INFL_AMNT && data.summerBod.INFL_AMNT != 'null' ? Number(data.summerBod.INFL_AMNT) : 0; @@ -1395,8 +1458,10 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) let winterChungchunEfflMax = 1 ; let winterChungchunEfflMin = 1 ; - let rdiPercent = 0; + const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; + let rdiPercent = 0; + let operationalStatusList = clone(operationalStatusListOrg); if(data && operationalStatusList){ // 유량 - 유입 if (operationalStatusList?.[0]) { @@ -1512,7 +1577,6 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) } }); - const clone = (arr: any[]) => arr?.map(v => ({ ...v })) ?? []; const calData = CalcRainEffect(clone(res2.data), 'SUNNY'); const calRainData = CalcRainEffect(clone(res2.data), 'RAIN'); @@ -1712,10 +1776,15 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) winterCnt += 1; }); - const winterBodAvg = winterBodSunny / winterCnt; + const roundMinSummerBodInfl = Number(roundNumber(minSummerBodInfl, 0).toString().replaceAll(',','')); + const roundMinSummerBod = Number(roundNumber(minSummerBod, 1).toString().replaceAll(',','')); + const roundWinterBodSunny = Number(roundNumber(winterBodSunny, 1).toString().replaceAll(',','')); + + const winterBodAvg = Number(roundNumber((roundWinterBodSunny / winterCnt), 1).toString().replaceAll(',','')); // 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) - const winMinusSum = winterBodAvg - minSummerBod; - const rdiValue = winMinusSum===0 ? 0 : minSummerBodInfl * ((winMinusSum / winterBodAvg )); + const winMinusSum = winterBodAvg - roundMinSummerBod; + + const rdiValue = winMinusSum===0 ? 0 : roundMinSummerBodInfl * (winMinusSum / winterBodAvg ); rdiPercent = (rdiValue / minSummerBodInfl) * 100; @@ -1838,13 +1907,15 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) } const rtnData = await calcWaterQltyData(operationalStatusList, searchYear, fcltyCd); - operationalStatusList = rtnData; // 총인설비가 없을 경우 제외 console.log('총인시설 여부 : ', data.yearData.TP_FCT_YN); + console.log('rtnData : ', rtnData); if(data.yearData.TP_FCT_YN !== 'Y') { - operationalStatusList = operationalStatusList.slice(0, 11); + operationalStatusList = rtnData.slice(0, 11); + }else{ + operationalStatusList = rtnData; } set((state: DashBoardType) => ({ ...state, @@ -1868,6 +1939,20 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) const res = await fetchMainGraph(searchYear, fcltyCd); const res2 = await fetchFacilityWaterQltyInfo(fcltyCd); + let chungcunSumFlow = 0; + const calData = CalcRainEffect(res.data.wqltObjs, 'SUNNY') + calData.forEach((flowItem: any) => { + chungcunSumFlow += flowItem.inflAmnt && flowItem.inflAmnt !== 'x' ? Number(flowItem.inflAmnt.toString().trim()) : 0; + }); + const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / calData.length:0; + + //bscFctCd === '11200PB001R') 중랑 - 테스트할 때 코드넣고 해야 보기편해요~ + /* if(bscFctCd === '11200PB001R') { + console.log('calData.length : ', calData.length); + console.log('usage : ', usage, 'summerUsage : ', summerUsage, 'winterUsage : ', winterUsage); + } */ + const underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1; + // 법적방류수질 데이터 const sortedWaterQltyInfo = [...res2].sort((a, b) => { // 숫자로 변환하여 비교 @@ -1908,7 +1993,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) const chart_inflowRain = res.data.wqltObjs.map((item: FacilityWaterQltyProps) => ({ label: item.msrDt.substring(0, 4)+"-"+item.msrDt.substring(4, 6)+"-"+item.msrDt.substring(6, 8), barVal0: item.infoRnDay ?? 0, - lineVal0: item.fctCpc ?? 0, + lineVal0: underWaterInputYear, lineVal1: item.inflAmnt ?? 0, })); @@ -1994,7 +2079,7 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType) } const fcltyCpcValue = res.data.wqltObjs[0].fctCpc; - const itemList = ['계', '3~10mm 미만', '10~20mm 미만', '20~30mm 미만', '30~40mm 미만', '40~50mm 미만', '50mm~60mm 미만', '60mm 이상']; + const itemList = ['계', '3~10mm 미만', '10~20mm 미만', '20~30mm 미만', '30~40mm 미만', '40~50mm 미만', '50~60mm 미만', '60mm 이상']; const rainRate = ['0', '0', '0', '0', '0', '0', '0', '0']; const rainDate = [0, 0, 0, 0, 0, 0, 0, 0]; const inflAmtCnt = [0, 0, 0, 0, 0, 0, 0, 0]; diff --git a/apps/fo/app/store/facilityPrecipitation/index.tsx b/apps/fo/app/store/facilityPrecipitation/index.tsx index 77a053fc5..984a40814 100644 --- a/apps/fo/app/store/facilityPrecipitation/index.tsx +++ b/apps/fo/app/store/facilityPrecipitation/index.tsx @@ -1,6 +1,7 @@ -import DataForm from "@/app/components/common/DataForm"; -import type { TableUpperProps } from "../dashboard"; import { getFetch } from "@/app/components/api"; +import CalcRainEffect from "@/app/components/common/CalcRainEffect"; +import { roundNumber } from "@/app/components/common/DataForm"; +import type { TableUpperProps } from "../dashboard"; export type { TableUpperProps }; /**==================================== * Store - 타입 @@ -68,48 +69,48 @@ const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시 // 리스트 헤더 const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", row: 0, colSpan: 2 }, - { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1, row: 1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe",upSequnce:2, row: 1 }, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2}, + { id: "A", title: "행정구역", row: 0, colSpan: 2, widthPercent: 20 }, + { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1, row: 1, widthPercent: 10 }, + { id: "gugun", title: "시군구", upName:"upChangeRe",upSequnce:2, row: 1, widthPercent: 10 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10}, { id: "addr", title: "주소", row: 0, rowSpan: 2}, - { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right"}, - { id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2}, - { id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right"}, - { id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right"}, - { id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right"} + { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right", widthPercent: 10 }, + { id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }, + { id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }, + { id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 } ]; const upHeadList2:TableUpperProps[] = [ - { id: "A", title: "유역", row: 0, colSpan: 3} , - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row: 1} , - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row: 1}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row: 1}, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2}, + { id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 21 } , + { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row: 1, widthPercent: 7 } , + { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row: 1, widthPercent: 7 }, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row: 1, widthPercent: 7 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, { id: "addr", title: "주소", row: 0, rowSpan: 2}, - { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right"}, - { id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2}, - { id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right"}, - { id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right"}, - { id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right"} + { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right", widthPercent: 10 }, + { id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }, + { id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }, + { id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 } ]; const upHeadList3:TableUpperProps[] = [ - { id: "A", title: "유역", row: 0, colSpan: 3} , - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row: 1}, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row: 1}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row: 1}, - { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2}, - { id: "B", title: "행정구역", upName:"upChangeRe2", row: 0, colSpan: 2}, - { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row: 1}, - { id: "gugun", title: "시군구", upName:"upChangeRe2",upSequnce:2, row: 1}, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2}, + { id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 15 } , + { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row: 1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "B", title: "행정구역", upName:"upChangeRe2", row: 0, colSpan: 2, widthPercent: 10 }, + { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row: 1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName:"upChangeRe2",upSequnce:2, row: 1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, { id: "addr", title: "주소", row: 0, rowSpan: 2}, - { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right"}, - { id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2}, - { id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right"}, - { id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right"}, - { id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right"} + { id: "fctCpc", title: "시설용량(m³/일)", row: 0, rowSpan: 2, align:"right", widthPercent: 10 }, + { id: "stnKo", title: "관측소 정보", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "infoRnDay", title: "강우일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }, + { id: "rainEffectDay", title: "강우영향일\n(일)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 }, + { id: "totalYearRain", title: "연간 총 총강수량\n(mm)", row: 0, rowSpan: 2, align:"right", widthPercent: 7 } ]; const facilityPrecipitation:FacilityPrecipitationProps[] = [ @@ -155,14 +156,15 @@ const fetchFacilityPrecipitationList = async (pageNo: number, pageSize: number, }) } } - + res.data.map((item: FacilityPrecipitationProps) => { const filteredList = tmpData.filter((gridItem) => { - return gridItem.bscFctCd === item.bscFctCd; + return gridItem.bscFctCd === item.bscFctCd; }); - item.rainEffectDay = filteredList.reduce((acc, curr) => acc + curr.rainEffectDay, 0); - item.totalYearRain = filteredList.reduce((acc, curr) => acc + curr.infoRnDay, 0); + const rtnData = CalcRainEffect(filteredList); + item.rainEffectDay = rtnData.reduce((acc, curr) => acc + curr.rainEffectDay, 0); + item.totalYearRain = rtnData.reduce((acc, curr) => acc + Number(curr.infoRnDay), 0); item.infoRnDay = filteredList.reduce((acc, curr) => acc + curr.rainDay, 0); }); @@ -178,11 +180,6 @@ export type FacilityPrecipitationActions = { searchFacilityPrecipitationList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void; } -const dataFormSetting=(item : FacilityPrecipitationProps)=> { - DataForm({ type: 'number', column: 'fctCpc', item: item as unknown as Record }); - DataForm({ type: 'float1', column: 'totalYearRain', item: item as unknown as Record}); -}; - export type FacilityPrecipitationType = { FacilityPrecipitationSearch: { isInit: boolean; @@ -246,13 +243,16 @@ export const facilityPrecipitationReducer:(set:(fn: (state: FacilityPrecipitatio const res = await fetchFacilityPrecipitationList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm); const data = res.data; + + data.forEach(item => { + item.fctCpc = roundNumber(item.fctCpc, 0); + item.totalYearRain = roundNumber(item.totalYearRain, 1); + }); + const excelDownList: ExcelType[] = []; if(pageSize>5000){ data.forEach((item: FacilityPrecipitationProps) => { - dataFormSetting(item) - item.fctCpc = item.fctCpc ? parseFloat(item.fctCpc.toString().replace(/,/g, '')) : 0; - item.totalYearRain = item.totalYearRain ? parseFloat(item.totalYearRain.toString().replace(/,/g, '')) : 0; excelDownList.push({ 시설코드: item.bscFctCd, 권역: item.rvbsn, @@ -270,18 +270,12 @@ export const facilityPrecipitationReducer:(set:(fn: (state: FacilityPrecipitatio "연간총강수량(mm)": item.totalYearRain, }) }) - }else{ - data.forEach((item: FacilityPrecipitationProps) => { - dataFormSetting(item) - item.fctCpc = item.fctCpc ? parseFloat(item.fctCpc.toString().replace(/,/g, '')) : 0; - item.totalYearRain = item.totalYearRain ? parseFloat(item.totalYearRain.toString().replace(/,/g, '')) : 0; - }) } set((state:FacilityPrecipitationType) => ({ ...state, FacilityPrecipitation: pageSize<5000?{ ...state.FacilityPrecipitation, - facilityPrecipitation: res.data, + facilityPrecipitation: data, facilityPrecipitationCount: res.count, isLoading : false, }:{ diff --git a/apps/fo/app/store/facilityWaterQlty/index.tsx b/apps/fo/app/store/facilityWaterQlty/index.tsx index f8b874c85..d0ddc6090 100644 --- a/apps/fo/app/store/facilityWaterQlty/index.tsx +++ b/apps/fo/app/store/facilityWaterQlty/index.tsx @@ -2,6 +2,8 @@ import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; +import { COD_YEAR } from "../common"; +import CommaToNumber from "@/app/components/common/CommaToNumber"; export type { TableUpperProps }; /**==================================== @@ -26,6 +28,8 @@ export interface FacilityWaterQltyProps { inflAssctAftWqltBod: string | '', inflAssctBfrWqltToc: string | '', inflAssctAftWqltToc: string | '', + inflAssctBfrWqltCod : string | '', + inflAssctAftWqltCod : string | '', inflAssctBfrWqltSs: string | '', inflAssctAftWqltSs: string | '', inflAssctBfrWqltTn: string | '', @@ -34,6 +38,7 @@ export interface FacilityWaterQltyProps { inflAssctAftWqltTp: string | '', efflWqltBod: string | '', efflWqltToc: string | '', + efflWqltCod : string | '', efflWqltSs: string | '', efflWqltTn: string | '', efflWqltTp: string | '', @@ -66,17 +71,17 @@ export interface ExcelType { 시군구: string, 시설이름: string, 주소: string, - "시설용량(m³/일)": number, - "유입BOD(mg/L)": string | '', - "유입TOC(mg/L)": string | '', - "유입SS(mg/L)": string | '', - "유입TN(mg/L)": string | '', - "유입TP(mg/L)": string | '', - "유출BOD(mg/L)": string | '', - "유출TOC(mg/L)": string | '', - "유출SS(mg/L)": string | '', - "유출TN(mg/L)": string | '', - "유출TP(mg/L)": string | '', + "시설용량(m³/일)": number | '', + "유입BOD(mg/L)": number | '', + "유입TOC(mg/L)": number | '', + "유입SS(mg/L)": number | '', + "유입TN(mg/L)": number | '', + "유입TP(mg/L)": number | '', + "유출BOD(mg/L)": number | '', + "유출TOC(mg/L)": number | '', + "유출SS(mg/L)": number | '', + "유출TN(mg/L)": number | '', + "유출TP(mg/L)": number | '', } /** @@ -100,17 +105,17 @@ export interface WaterQualityHistoryResponse { export type modalExcelType = { 날짜: string; - "유입BOD(mg/L)": string; - "유입TOC(COD)(mg/L)": string; - "유입SS(mg/L)": string; - "유입TN(mg/L)": string; - "유입TP(mg/L)": string; - "유출BOD(mg/L)": string; - "유출TOC(COD)(mg/L)": string; - "유출SS(mg/L)": string; - "유출TN(mg/L)": string; - "유출TP(mg/L)": string; - /* "강우량(mm/일)": string; */ + "유입BOD(mg/L)": number | ''; + "유입TOC(COD)(mg/L)": number | ''; + "유입SS(mg/L)": number | ''; + "유입TN(mg/L)": number | ''; + "유입TP(mg/L)": number | ''; + "유출BOD(mg/L)": number | ''; + "유출TOC(COD)(mg/L)": number | ''; + "유출SS(mg/L)": number | ''; + "유출TN(mg/L)": number | ''; + "유출TP(mg/L)": number | ''; + "강우량(mm/일)": number | ''; } /**==================================== @@ -124,74 +129,74 @@ const mainLabelArray: string[] = ['구분', '시도', '시군구', '용량별', // 시설수질리스트 헤더(행정별) const upHeadList1: TableUpperProps[] = [ - { id: "C", title: "행정명", colSpan: 2, row: 0 }, - { id: "sidoNm", title: "시도", row: 1 }, - { id: "sggNm", title: "시군구", row: 1 }, - { id: "bscFctNm", title: "시설명", rowSpan: 2, row: 0 }, + { id: "C", title: "행정명", colSpan: 2, row:0, widthPercent:10 }, + { id: "sidoNm", title: "시도", row: 1, widthPercent:5}, + { id: "sggNm", title: "시군구", row: 1, widthPercent:5 }, + { id: "bscFctNm", title: "시설명", rowSpan: 2, row: 0, widthPercent: 10 }, { id: "addr", title: "주소", rowSpan: 2, row: 0 }, - { id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0 }, - { id: "A", title: "유입", colSpan: 5, row: 0 }, - { id: "B", title: "방류", colSpan: 5, row: 0 }, - { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1 }, - { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1 }, - { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1 }, - { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1 }, - { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1 }, - { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1 }, - { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1 }, - { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1 }, - { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 4, align: "right", row: 1 }, - { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1 }, + { id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0, widthPercent:10 }, + { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent:25 }, + { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent:25 }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent:5 }, + { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent:5 }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1, widthPercent:5 }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent:5 }, + { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent:5 }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 4, align: "right", row: 1, widthPercent:5 }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent:5 }, ]; // 시설수질리스트 헤더(권역별) const upHeadList2: TableUpperProps[] = [ - { id: "C", title: "유역", colSpan: 3, row: 0 }, - { id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row:1 }, - { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row:1 }, - { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "C", title: "유역", colSpan: 3, row: 0, widthPercent:15 }, + { id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row:1, widthPercent:5 }, + { id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row:1, widthPercent:5 }, + { id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row:1, widthPercent:5 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent:10 }, { id: "addr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2 }, - { id: "A", title: "유입", colSpan: 5, row: 0 }, - { id: "B", title: "방류", colSpan: 5, row: 0 }, - { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1 }, - { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 }, - { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 }, - { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 }, - { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 }, - { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1 }, - { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1 }, - { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1 }, - { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1 }, - { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1 }, + { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2, widthPercent:8 }, + { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent:25 }, + { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent:25 }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1, widthPercent:5 }, + { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent:5 }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent:5 }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent:5 }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent:5 }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1, widthPercent:5 }, + { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent:5 }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent:5 }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent:5 }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent:5 }, ]; // 시설수질리스트 헤더(환경청별) const upHeadList3: TableUpperProps[] = [ - { id: "C", title: "유역", colSpan: 3, row: 0 }, - { id: "rvbsn", title: "권역", row:1 }, - { id: "lgbsn", title: "단위유역", row:1 }, - { id: "mdmbsn", title: "중권역", row:1 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2 }, - { id: "D", title: "행정명", colSpan: 2, row: 0 }, - { id: "sidoNm", title: "시도", upName: "upChangeRe2", row:1 }, - { id: "sggNm", title: "시군구", upName: "upChangeRe2", row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "C", title: "유역", colSpan: 3, row: 0, widthPercent: 15 }, + { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 7 }, + { id: "D", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 }, + { id: "sidoNm", title: "시도", upName: "upChangeRe2", row:1, widthPercent: 5 }, + { id: "sggNm", title: "시군구", upName: "upChangeRe2", row:1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "addr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2 }, - { id: "A", title: "유입", colSpan: 5, row: 0 }, - { id: "B", title: "방류", colSpan: 5, row: 0 }, - { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1 }, - { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 }, - { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 }, - { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1 }, - { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1 }, - { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1 }, - { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1 }, - { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1 }, - { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1 }, - { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1 }, + { id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2, widthPercent: 5 }, + { id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 20 }, + { id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 20 }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1, widthPercent: 4 }, + { id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1, widthPercent: 4 }, + { id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent: 4 }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent: 4 }, ]; /** @@ -210,7 +215,22 @@ const upHeadListModalYear: TableUpperProps[] = [ { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe2", upSequnce: 3, align: "right" }, { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe2", upSequnce: 2, align: "right" }, { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe2", upSequnce: 3, align: "right" }, - { id: "noProcessInflAmnt", title: "미처리하수량\n(m³/일)", align:"right"}, + { id: "infoRnDay", title: "강우량\n(mm/일)", align: "right" } +]; + +// 처리시설 수질현황 헤더(모달-연간) +const upHeadListModalYearCod: TableUpperProps[] = [ + { id: "msrDt", title: "날짜" }, + { id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe1", upSequnce: 1, align: "right" }, + { id: "inflAssctBfrWqltCod", title: "TOC(COD)\n(mg/L)", upName: "upChangeRe1", upSequnce: 2, align: "right" }, + { id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe1", upSequnce: 3, align: "right" }, + { id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe1", upSequnce: 2, align: "right" }, + { id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe1", upSequnce: 3, align: "right" }, + { id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe2", upSequnce: 1, align: "right" }, + { id: "efflWqltCod", title: "TOC(COD)\n(mg/L)", upName: "upChangeRe2", upSequnce: 2, align: "right" }, + { id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe2", upSequnce: 3, align: "right" }, + { id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe2", upSequnce: 2, align: "right" }, + { id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe2", upSequnce: 3, align: "right" }, { id: "infoRnDay", title: "강우량\n(mm/일)", align: "right" } ]; @@ -298,6 +318,7 @@ export type FacilityWaterQltyType = { FacilityWaterQltyModal: { // 처리시설 수질현황 upHeadListModalYear: TableUpperProps[]; + upHeadListModalYearCod : TableUpperProps[]; facilityWaterQltyYearList: FacilityWaterQltyProps[]; upHeadListModalTms: TableUpperProps[]; facilityWaterQltyTmsList: FacilityWaterQltyTmsProps[]; @@ -327,6 +348,7 @@ export const facilityWaterQltyInitState: FacilityWaterQltyType = { FacilityWaterQltyModal: { // 처리시설 수질현황 upHeadListModalYear: upHeadListModalYear, + upHeadListModalYearCod: upHeadListModalYearCod, facilityWaterQltyYearList: facilityWaterQltyYearList, upHeadListModalTms: upHeadListModalTms, facilityWaterQltyTmsList: facilityWaterQltyTmsList, @@ -453,8 +475,8 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, '')); item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || ''; item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || ''; - item.inflAssctBfrWqltToc = Number(searchYear)<2021? "("+item.inflAssctBfrWqltToc+")" : item.inflAssctBfrWqltToc; - item.efflWqltToc = Number(searchYear)<2021? "("+item.efflWqltToc+")" : item.efflWqltToc; + item.inflAssctBfrWqltToc = Number(searchYear) ({ @@ -625,6 +647,12 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType if(item.efflWqltToc){ item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1); } + if(item.inflAssctBfrWqltCod){ + item.inflAssctBfrWqltCod = "("+Number(Math.round(Number(item.inflAssctBfrWqltCod) * 10)/10).toFixed(1)+")"; + } + if(item.efflWqltCod){ + item.efflWqltCod = "("+Number(Math.round(Number(item.efflWqltCod) * 10)/10).toFixed(1)+")"; + } if(item.inflAssctBfrWqltBod){ item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1); } diff --git a/apps/fo/app/store/flowRate/index.tsx b/apps/fo/app/store/flowRate/index.tsx index f8125e59c..05a41e556 100644 --- a/apps/fo/app/store/flowRate/index.tsx +++ b/apps/fo/app/store/flowRate/index.tsx @@ -3,6 +3,7 @@ import type { TableUpperProps } from "../dashboard"; import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { fetchFacilityWaterQltyListHist } from "../facilityWaterQlty"; +import CommaToNumber from "@/app/components/common/CommaToNumber"; /**==================================== * Store - 타입 @@ -95,53 +96,53 @@ export type FlowRateModalProps = { */ // 리스트 (행정별) const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정명", row: 0 ,colSpan: 2 }, - { id: "sido", title: "시도", upName:"upChangeRe", row:1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe", row:1 }, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2}, - { id: "daddr", title: "주소", row: 0, rowSpan: 2}, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2}, - { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2}, - { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2}, - { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2}, - { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2}, - { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2} + { id: "A", title: "행정명", row: 0, colSpan: 2, widthPercent: 16 }, + { id: "sido", title: "시도", upName:"upChangeRe", row:1, widthPercent: 8 }, + { id: "gugun", title: "시군구", upName:"upChangeRe", row:1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10}, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 } ]; // 리스트 (권역별) const upHeadList2:TableUpperProps[] = [ - { id: "A", title: "유역", row: 0, colSpan: 3}, - { id: "rvbsn", title: "권역", upName:"upChangeRe", row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", row:1 }, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2}, - { id: "daddr", title: "주소", row: 0, rowSpan: 2}, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2}, - { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2}, - { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2}, - { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2}, - { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2}, - { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2} + { id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 24 }, + { id: "rvbsn", title: "권역", upName:"upChangeRe", row:1, widthPercent: 8 }, + { id: "lgbsn", title: "단위유역", upName:"upChangeRe", row:1, widthPercent: 8 }, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe", row:1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 10 }, + { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 } ]; // 리스트 (환경청별별) const upHeadList3:TableUpperProps[] = [ - { id: "A", title: "유역", row: 0, colSpan: 3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", row:1 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2 }, - { id: "B", title: "행정명", row: 0 ,colSpan: 2 }, - { id: "sido", title: "시도", upName:"upChangeRe2", row:1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe2", row:1 }, - { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2 }, + { id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 15 }, + { id: "rvbsn", title: "권역", upName:"upChangeRe1", row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", row:1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 7 }, + { id: "B", title: "행정명", row: 0 ,colSpan: 2, widthPercent: 10 }, + { id: "sido", title: "시도", upName:"upChangeRe2", row:1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName:"upChangeRe2", row:1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 7 }, { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2 }, - { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2 }, - { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2 }, - { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2 }, - { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2 }, - { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2 } + { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }, + { id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 } ]; const flowRateList:flowRateListProps[] = [ @@ -172,6 +173,7 @@ const fetchFlowRateList = async (pageNo: number, pageSize: number, searchYear: s try { const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; const url = '/fclt/flow/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr; + console.log(url); const res = await getFetch('fo', url); return { data: res.data, count: res.count } } catch (error) { @@ -299,11 +301,11 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow 시설이름: item.bscFctNm, 주소: item.daddr, "시설용량(m³/일)": item.fctCpc, - "총유입량(m³/일)": item.totInflAmnt, - "하수유입량(m³/일)": item.inflAmnt, - "연계처리량(m³/일)": item.sumFlow, - "총인반류수량(m³/일)": item.returnAmnt, - "방류량(m³/일)": item.efflAmnt, + "총유입량(m³/일)": CommaToNumber(item.totInflAmnt), + "하수유입량(m³/일)": CommaToNumber(item.inflAmnt), + "연계처리량(m³/일)": CommaToNumber(item.sumFlow), + "총인반류수량(m³/일)": CommaToNumber(item.returnAmnt), + "방류량(m³/일)": CommaToNumber(item.efflAmnt), }); }); } diff --git a/apps/fo/app/store/planSewage/index.tsx b/apps/fo/app/store/planSewage/index.tsx index 21a711e8b..80a4d66e7 100644 --- a/apps/fo/app/store/planSewage/index.tsx +++ b/apps/fo/app/store/planSewage/index.tsx @@ -47,44 +47,44 @@ const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시 // 리스트 헤더 const upHeadList1:TableUpperProps[] = [ { id: "A", title: "행정구역", upSequnce:1, row:0, colSpan:2 }, - { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1, row:1, widthPercent: 10 }, + { id: "gugun", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1, widthPercent: 10 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 10 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right' }, - { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right' }, - { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right' }, - { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right' }, + { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, ]; const upHeadList2:TableUpperProps[] = [ { id: "A", title: "유역", upName:"upChangeRe", upSequnce:1, row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1}, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1}, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1, widthPercent: 8 }, + { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1, widthPercent: 8}, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1, widthPercent: 8}, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 10 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right' }, - { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right' }, - { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right' }, - { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right' }, + { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, ]; const upHeadList3:TableUpperProps[] = [ { id: "A", title: "유역", upName:"upChangeRe", upSequnce:1, row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1}, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1}, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1, widthPercent: 5}, + { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 }, { id: "B", title: "행정구역", upName:"upChangeRe", upSequnce:1, row:0, colSpan:2 }, - { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 10 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right' }, - { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right' }, - { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right' }, - { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right' }, + { id: "fctCpc", title: "시설용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "spareCapacity", title: "여유용량(m³/일)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "variableLoadPercent", title: "변동부하율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, + { id: "classifiedSewerPercent", title: "분류식화율(%)", row:0, rowSpan:2, align:'right', widthPercent: 8 }, ]; const planSewageList:PlanSewageProps[] = [ @@ -96,6 +96,7 @@ const planSewageList:PlanSewageProps[] = [ const fetchPlanSewageList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { const tailStr = partCd ? '/'+ partCd + '/' + (nameCd || '0') + '/' + (fcltCpct || '0') + '/' + (operationValue || '0') +'/0'+ (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : ''; const url = '/prcsFclt/info/plan/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr; + console.log(url); const res = await getFetch('fo', url); return { data: res.data, count: res.count } } diff --git a/apps/fo/app/store/processArea/index.tsx b/apps/fo/app/store/processArea/index.tsx index ccad3436e..37b4d52f0 100644 --- a/apps/fo/app/store/processArea/index.tsx +++ b/apps/fo/app/store/processArea/index.tsx @@ -128,35 +128,35 @@ const ProcessFacilityLabelArray:string[] = ['구분', '시도', '시군구','용 // 리스트 헤더(행정별) const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", colSpan:2, rowSpan:2, row:0}, - { id: "sido", title: "시도", upName:"upChangeRe", row:2 }, - { id: "sigungo", title: "시군구", upName:"upChangeRe", row:2 }, - { id: "swtrmtFcltNm", title: "시설명", rowSpan:3, row:0}, - { id: "location", title: "주소", rowSpan:3, row:0, }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", rowSpan:3, row:0}, - { id: "B", title: "시설계획", colSpan:19, row:0}, - { id: "C", title: "증설계획(m³/일)", colSpan:6, row:1}, - { id: "planSwageQntSumDt4", title: "기승인\n4단계", row:2, align:"right"}, - { id: "planSwageQntSum", title: "현재", row:2, align:"right"}, - { id: "planSwageQntSumDc1", title: "1단계", row:2, align:"right"}, - { id: "planSwageQntSumDc2", title: "2단계", row:2, align:"right"}, - { id: "planSwageQntSumDc3", title: "3단계", row:2, align:"right"}, - { id: "planSwageQntSumDc4", title: "4단계", row:2, align:"right"}, - { id: "D", title: "처리인구(인)", colSpan:6, row:1}, - { id: "swtrmtPpltnCntDt4", title: "기승인\n4단계", row:2, align:"right"}, - { id: "swtrmtPpltnCnt", title: "현재", row:2, align:"right"}, - { id: "swtrmtPpltnCntDc1", title: "1단계", row:2, align:"right"}, - { id: "swtrmtPpltnCntDc2", title: "2단계", row:2, align:"right"}, - { id: "swtrmtPpltnCntDc3", title: "3단계", row:2, align:"right"}, - { id: "swtrmtPpltnCntDc4", title: "4단계", row:2, align:"right"}, - { id: "E", title: "처리구역(km²)", colSpan:7, row:1}, - { id: "swtrmtZoneAreaDt4", title: "기승인\n4단계", row:2, align:"right"}, - { id: "swtrmtZoneArea", title: "현재", row:2, align:"right"}, - { id: "swtrmtZoneAreaDc1", title: "1단계", row:2, align:"right"}, - { id: "swtrmtZoneAreaDc2", title: "2단계", row:2, align:"right"}, - { id: "swtrmtZoneAreaDc3", title: "3단계", row:2, align:"right"}, - { id: "swtrmtZoneAreaDc4", title: "4단계", row:2, align:"right"}, - { id: "trtDstr", title: "처리구역", row:2} + { id: "A", title: "행정구역", colSpan:2, rowSpan:2, row:0 }, + { id: "sido", title: "시도", upName:"upChangeRe", row:2, widthPercent:4 }, + { id: "sigungo", title: "시군구", upName:"upChangeRe", row:2, widthPercent:4 }, + { id: "swtrmtFcltNm", title: "시설명", rowSpan:3, row:0, widthPercent: 8 }, + { id: "location", title: "주소", rowSpan:3, row:0 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", rowSpan:3, row:0, widthPercent: 5 }, + { id: "B", title: "시설계획", colSpan:19, row: 0 }, + { id: "C", title: "증설계획(m³/일)", colSpan:6, row: 1 }, + { id: "planSwageQntSumDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "planSwageQntSum", title: "현재", row:2, align:"right", widthPercent: 2.5 }, + { id: "planSwageQntSumDc1", title: "1단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "planSwageQntSumDc2", title: "2단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "planSwageQntSumDc3", title: "3단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "planSwageQntSumDc4", title: "4단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "D", title: "처리인구(인)", colSpan:6, row:1 }, + { id: "swtrmtPpltnCntDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtPpltnCnt", title: "현재", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtPpltnCntDc1", title: "1단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtPpltnCntDc2", title: "2단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtPpltnCntDc3", title: "3단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtPpltnCntDc4", title: "4단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "E", title: "처리구역(km²)", colSpan:7, row:1 }, + { id: "swtrmtZoneAreaDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtZoneArea", title: "현재", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtZoneAreaDc1", title: "1단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtZoneAreaDc2", title: "2단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtZoneAreaDc3", title: "3단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "swtrmtZoneAreaDc4", title: "4단계", row:2, align:"right", widthPercent: 2.5 }, + { id: "trtDstr", title: "처리구역", row:2 } ]; const processAreaList:ProcessAreaProps[] = [ diff --git a/apps/fo/app/store/processFacility/index.tsx b/apps/fo/app/store/processFacility/index.tsx index ecb668063..43e7eab53 100644 --- a/apps/fo/app/store/processFacility/index.tsx +++ b/apps/fo/app/store/processFacility/index.tsx @@ -162,52 +162,56 @@ const ProcessFacilityLabelArray:string[] = ['구분', '시도', '시군구','용 // 리스트 헤더 const upHeadList1:TableUpperProps[] = [ - { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe",upSequnce:2 }, - { id: "bscFctNm", title: "시설명"}, - { id: "daddr", title: "주소"}, - { id: "fctCpc", title: "시설용량\n(m³/일)", align: 'right'}, - { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", align:"right"}, - { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", align:"right"}, - { id: "trtFrfNm", title: '공법'}, - { id: "rnDt", title: '가동개시일'}, - { id: "cmplDt", title: '준공일' }, - { id: "trstOprEtpNm", title: '관리대행업자'} + { id: "A", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 }, + { id: "sido", title: "시도", upName:"upChangeRe", row: 1, upSequnce:1, widthPercent: 5 }, + { id: "gugun", title: "시군구", upName:"upChangeRe", row: 1, upSequnce:2, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", row: 0, align: 'right', rowSpan: 2, widthPercent: 5 }, + { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", row: 0, align:"right", rowSpan: 2, widthPercent: 5 }, + { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", row: 0, align:"right", rowSpan: 2, widthPercent: 5 }, + { id: "trtFrfNm", title: '공법', row: 0, rowSpan: 2 }, + { id: "rnDt", title: '가동개시일', row: 0, rowSpan: 2, widthPercent: 5 }, + { id: "cmplDt", title: '준공일', row: 0, rowSpan: 2, widthPercent: 5 }, + { id: "trstOprEtpNm", title: '관리대행업자', row: 0, rowSpan: 2 , widthPercent: 14} ]; // 처리시설 리스트 (유역) const upHeadList2:TableUpperProps[] = [ - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1}, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3}, - { id: "bscFctNm", title: "시설명"}, - { id: "daddr", title: "주소"}, - { id: "fctCpc", title: "시설용량\n(m³/일)", align: 'right'}, - { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", align:'right'}, - { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", align:'right'}, - { id: "trtFrfNm", title: '공법'}, - { id: "rnDt", title: '가동개시일'}, - { id: "cmplDt", title: '준공일' }, - { id: "trstOprEtpNm", title: '관리대행업자'} + { id: "A", title: "유역", colSpan: 3, row: 0, widthPercent: 15 }, + { id: "rvbsn", title: "권역", row: 1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", rowSpan: 2,row: 0, widthPercent: 8 }, + { id: "daddr", title: "주소", rowSpan: 2,row: 0 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", rowSpan: 2,row: 0, widthPercent: 5, align: 'right'}, + { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", rowSpan: 2,row: 0, widthPercent: 6, align:'right'}, + { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", rowSpan: 2,row: 0, widthPercent: 6, align:'right'}, + { id: "trtFrfNm", title: '공법', rowSpan: 2,row: 0 }, + { id: "rnDt", title: '가동개시일', rowSpan: 2,row: 0, widthPercent: 5 }, + { id: "cmplDt", title: '준공일', rowSpan: 2,row: 0, widthPercent: 5 }, + { id: "trstOprEtpNm", title: '관리대행업자', rowSpan: 2,row: 0, widthPercent: 14 } ]; // 처리시설 리스트 (환경청청) const upHeadList3:TableUpperProps[] = [ - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1}, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2}, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3}, - { id: "rgnNm", title: "환경청"}, - { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1 }, - { id: "gugun", title: "시군구", upName:"upChangeRe2",upSequnce:2 }, - { id: "bscFctNm", title: "시설명"}, - { id: "daddr", title: "주소"}, - { id: "fctCpc", title: "시설용량\n(m³/일)", align: 'right'}, - { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", align:'right'}, - { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", align:'right'}, - { id: "trtFrfNm", title: '공법'}, - { id: "rnDt", title: '가동개시일'}, - { id: "cmplDt", title: '준공일' }, - { id: "trstOprEtpNm", title: '관리대행업자'} + { id: "A", title: "유역", colSpan: 3, row: 0, widthPercent: 12 }, + { id: "rvbsn", title: "권역", row: 1, widthPercent: 4 }, + { id: "lgbsn", title: "단위유역", row: 1, widthPercent: 4}, + { id: "mdmbsn", title: "중권역", row: 1, widthPercent: 4 }, + { id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 6 }, + { id: "B", title: "행정명", colSpan: 2, row: 0, widthPercent: 8 }, + { id: "sido", title: "시도", row: 1, widthPercent: 4 }, + { id: "gugun", title: "시군구", row: 1, widthPercent: 4 }, + { id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 }, + { id: "daddr", title: "주소", row: 0, rowSpan: 2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", row: 0, rowSpan: 2, align: 'right', widthPercent: 5 }, + { id: "plInflWqltBod", title: "계획유입수질\n(mg/L)", row: 0, rowSpan: 2, align:'right', widthPercent: 5 }, + { id: "dsInflWqltBod", title: "설계유입수질\n(mg/L)", row: 0, rowSpan: 2, align:'right', widthPercent: 5 }, + { id: "trtFrfNm", title: '공법', row: 0, rowSpan: 2 }, + { id: "rnDt", title: '가동개시일', row: 0, rowSpan: 2, widthPercent: 5 }, + { id: "cmplDt", title: '준공일', row: 0, rowSpan: 2, widthPercent: 5 }, + { id: "trstOprEtpNm", title: '관리대행업자', row: 0, rowSpan: 2, widthPercent: 14 } ]; const processFacilityList:facilityListProps[] = [ diff --git a/apps/fo/app/store/rdi/index.tsx b/apps/fo/app/store/rdi/index.tsx index 601a925a0..c22859043 100644 --- a/apps/fo/app/store/rdi/index.tsx +++ b/apps/fo/app/store/rdi/index.tsx @@ -101,65 +101,65 @@ export interface ExcelType { // 리스트 헤더 const upHeadList1:TableUpperProps[] = [ { id: "A", title: "행정구역", row:0, colSpan:2 }, - { id: "sido", title: "시도", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "sigungo", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sido", title: "시도", row:1, widthPercent: 6 }, + { id: "sigungo", title: "시군구", row:1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 7 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 7 }, + { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 7 }, { id: "B", title: "하절기 운영현황(6~8월)", row:0, colSpan:2 }, - { id: "summerMinBodValue", title: "3mm 이상 강우일 중 최저 유입BOD\n(mg/L)", align:"right", row:1 }, - { id: "inflAmnt", title: "하절기최저유입BOD유입유량\n(m³/일)", row:1, align:"right" }, + { id: "summerMinBodValue", title: "3mm 이상 강우일 중\n최저 유입BOD\n(mg/L)", align:"right", row:1, widthPercent: 7 }, + { id: "inflAmnt", title: "하절기최저유입\nBOD유입유량\n(m³/일)", row:1, align:"right", widthPercent: 7 }, { id: "C", title: "동절기 운영현황(1~2월)", row:0 }, - { id: "winterAvgBodLowRainfall", title: "청천시 유입BOD\n(mg/L)", row:1, align:"right" }, - { id: "rdiiValue", title: "RDII추정", row:0, rowSpan:2, align:"right" }, - { id: "infoRnDay", title: "RDII추정시일강수량\n(mm)", row:0, rowSpan:2, align:"right" }, - { id: "rainCalInflAmnt", title: "강우시 총 추정유입량\n(m³/일)", row:0, rowSpan:2, align:"right" }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2 }, + { id: "winterAvgBodLowRainfall", title: "청천시 유입BOD\n(mg/L)", row:1, align:"right", widthPercent: 8 }, + { id: "rdiiValue", title: "RDII추정", row:0, rowSpan:2, align:"right", widthPercent: 8 }, + { id: "infoRnDay", title: "RDII추정시\n일강수량\n(mm)", row:0, rowSpan:2, align:"right", widthPercent: 7 }, + { id: "rainCalInflAmnt", title: "강우시\n총 추정유입량\n(m³/일)", row:0, rowSpan:2, align:"right", widthPercent: 6 }, + { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 6 }, ]; const upHeadList2:TableUpperProps[] = [ { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 7 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 7 }, + { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 7 }, { id: "B", title: "하절기 운영현황(6~8월)", row:0, colSpan:2 }, - { id: "summerMinBodValue", title: "3mm 이상 강우일 중 최저 유입BOD\n(mg/L)", align:"right", row:1 }, - { id: "inflAmnt", title: "하절기최저유입BOD유입유량", row:1, align:"right" }, + { id: "summerMinBodValue", title: "3mm 이상 강우일 중\n최저 유입BOD\n(mg/L)", align:"right", row:1, widthPercent: 7 }, + { id: "inflAmnt", title: "하절기최저유입\nBOD유입유량\n(m³/일)", row:1, align:"right", widthPercent: 7 }, { id: "D", title: "동절기 운영현황(1~2월)", row:0 }, - { id: "winterAvgBodLowRainfall", title: "동절기청천시유입BOD", row:1, align:"right" }, - { id: "rdiiValue", title: "RDII추정", row:0, rowSpan:2, align:"right" }, - { id: "infoRnDay", title: "RDII추정시일강수량", row:0, rowSpan:2, align:"right" }, - { id: "rainCalInflAmnt", title: "강우시 총 추정유입량\n(m³/일)", row:0, rowSpan:2, align:"right" }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2 }, + { id: "winterAvgBodLowRainfall", title: "청천시 유입BOD\n(mg/L)", row:1, align:"right", widthPercent: 8 }, + { id: "rdiiValue", title: "RDII추정", row:0, rowSpan:2, align:"right", widthPercent: 7 }, + { id: "infoRnDay", title: "RDII추정시\n일강수량\n(mm)", row:0, rowSpan:2, align:"right", widthPercent: 7 }, + { id: "rainCalInflAmnt", title: "강우시\n총 추정유입량\n(m³/일)", row:0, rowSpan:2, align:"right", widthPercent: 6 }, + { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 6 }, ]; const upHeadList3:TableUpperProps[] = [ { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", row:1, widthPercent: 4 }, + { id: "lgbsn", title: "단위유역", row:1, widthPercent: 4 }, + { id: "mdmbsn", title: "중권역", row:1, widthPercent: 4 }, + { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 6 }, { id: "B", title: "행정구역", row:0, colSpan:2 }, - { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1 }, - { id: "sigungo", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sido", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1, widthPercent: 4 }, + { id: "sigungo", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1, widthPercent: 4 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 6 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 5 }, + { id: "chungchunFlow", title: "청천시 유입하수량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, { id: "C", title: "하절기 운영현황(6~8월)", row:0, colSpan:2 }, - { id: "summerMinBodValue", title: "3mm 이상 강우일 중 최저 유입BOD\n(mg/L)", align:"right", row:1 }, - { id: "inflAmnt", title: "하절기최저유입BOD유입유량", row:1, align:"right" }, + { id: "summerMinBodValue", title: "3mm 이상 강우일 중\n최저 유입BOD\n(mg/L)", align:"right", row:1, widthPercent: 6 }, + { id: "inflAmnt", title: "하절기최저유입\nBOD유입유량\n(m³/일)", row:1, align:"right", widthPercent: 6 }, { id: "D", title: "동절기 운영현황(1~2월)", row:0 }, - { id: "winterAvgBodLowRainfall", title: "동절기청천시유입BOD", row:1, align:"right" }, - { id: "rdiiValue", title: "RDII추정", row:0, rowSpan:2, align:"right" }, - { id: "infoRnDay", title: "RDII추정시일강수량", row:0, rowSpan:2, align:"right" }, - { id: "rainCalInflAmnt", title: "강우시 총 추정유입량\n(m³/일)", row:0, rowSpan:2, align:"right" }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2 }, + { id: "winterAvgBodLowRainfall", title: "청천시 유입BOD\n(mg/L)", row:1, align:"right", widthPercent: 8 }, + { id: "rdiiValue", title: "RDII추정", row:0, rowSpan:2, align:"right", widthPercent: 6 }, + { id: "infoRnDay", title: "RDII추정시\n일강수량\n(mm)", row:0, rowSpan:2, align:"right", widthPercent: 6 }, + { id: "rainCalInflAmnt", title: "강우시\n총 추정유입량\n(m³/일)", row:0, rowSpan:2, align:"right", widthPercent: 6 }, + { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 6 }, ]; const rdiList:RdiProps[] = [ @@ -336,11 +336,20 @@ export const rdiReducer:(set:SetStateFunction)=>RdiActions=(set: SetStateFunctio minSummerBod = minSummerBod === 99999999 ? 0 : minSummerBod; minSummerBodInfl = minSummerBodInfl === 99999999 ? 0 : minSummerBodInfl; - const winterBodAvg = winterBodSunny / winterCnt; + const roundMinSummerBodInfl = Number(roundNumber(minSummerBodInfl, 0).toString().replaceAll(',','')); + const roundMinSummerBod = Number(roundNumber(minSummerBod, 1).toString().replaceAll(',','')); + const roundWinterBodSunny = Number(roundNumber(winterBodSunny, 1).toString().replaceAll(',','')); + + console.log('bsccd : ', item.bscFctCd); + console.log('roundMinSummerBodInfl : ',roundMinSummerBodInfl); + console.log('roundMinSummerBod : ',roundMinSummerBod); + console.log('roundWinterBodSunny : ',roundWinterBodSunny); + + const winterBodAvg = Number(roundNumber((roundWinterBodSunny / winterCnt), 1).toString().replaceAll(',','')); // 하절기(6~8월) 중 최저 유입 BOD일때 유입유량 x ((동절기 청천시 유입BOD - 하절기(6~8월) 중 최저 유입BOD) / (동절기 청천시 유입BOD)) - const winMinusSum = winterBodAvg - minSummerBod; - console.log(item.bscFctCd+' '+minSummerBodInfl+' '+winMinusSum+' ('+winterBodSunny+' '+winterCnt+') '+' '+winterBodSunny) - const rdiValue = winMinusSum===0 ? 0 : minSummerBodInfl * ((winMinusSum / winterBodAvg )); + const winMinusSum = winterBodAvg - roundMinSummerBod; + + const rdiValue = winMinusSum===0 ? 0 : roundMinSummerBodInfl * (winMinusSum / winterBodAvg ); rtnWinterInflBod = winterBodAvg; rtnSummerBodInfl = minSummerBodInfl; diff --git a/apps/fo/app/store/sewageOccur/index.tsx b/apps/fo/app/store/sewageOccur/index.tsx index efc51a5af..e9ae8985b 100644 --- a/apps/fo/app/store/sewageOccur/index.tsx +++ b/apps/fo/app/store/sewageOccur/index.tsx @@ -63,50 +63,50 @@ export interface ExcelType { // 리스트 헤더 const upHeadList1:TableUpperProps[] = [ { id: "A", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "sggNm", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sidoNm", title: "시도", row:1, widthPercent: 8 }, + { id: "sggNm", title: "시군구", row:1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "swageChangePercent", title: "오수전환율\n(%)", align:"right", row:0, rowSpan:2 }, - { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "swageChangePercent", title: "오수전환율\n(%)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, ]; const upHeadList2:TableUpperProps[] = [ { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", row:1, widthPercent: 6 }, + { id: "lgbsn", title: "단위유역", row:1, widthPercent: 6 }, + { id: "mdmbsn", title: "중권역", row:1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2 }, - { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, ]; const upHeadList3:TableUpperProps[] = [ { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 }, { id: "B", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1 }, - { id: "sggNm", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sidoNm", title: "시도", row:1, widthPercent: 6 }, + { id: "sggNm", title: "시군구", row:1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2 }, - { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, + { id: "waterUsage", title: "물사용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, + { id: "swageChangePercent", title: "오수전환율", align:"right", row:0, rowSpan:2, widthPercent: 6 }, + { id: "estimationSewage", title: "오수발생량 추정\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, + { id: "sewageInputYear", title: "연간 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, + { id: "sewageInputChungchun", title: "청천시 하수유입량\n(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, ]; const upHeadListSewageOccurDetail:TableUpperProps[] = [ diff --git a/apps/fo/app/store/underWaterInput/index.tsx b/apps/fo/app/store/underWaterInput/index.tsx index 816860469..f6b466492 100644 --- a/apps/fo/app/store/underWaterInput/index.tsx +++ b/apps/fo/app/store/underWaterInput/index.tsx @@ -35,53 +35,53 @@ const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시 // 리스트 헤더 const upHeadList1:TableUpperProps[] = [ { id: "A", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "sggNm", title: "시군구", upName:"upChangeRe",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sidoNm", title: "시도", row:1, widthPercent: 8 }, + { id: "sggNm", title: "시군구", row:1, widthPercent: 8 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 }, { id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 }, - { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1 }, - { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1 }, - { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1 }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2 }, + { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 8 }, + { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, + { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, + { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 8 }, ]; const upHeadList2:TableUpperProps[] = [ { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe", upSequnce:1, row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe", upSequnce:2, row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe", upSequnce:3, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 }, + { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 }, { id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 }, - { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1 }, - { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1 }, - { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1 }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2 }, + { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 8 }, + { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, + { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 8 }, + { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 8 }, ]; const upHeadList3:TableUpperProps[] = [ { id: "A", title: "유역", row:0, colSpan:3 }, - { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1 }, - { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1 }, - { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1 }, - { id: "rgnNm", title: "환경청", row:0, rowSpan:2 }, + { id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1, widthPercent: 5 }, + { id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1, widthPercent: 5 }, + { id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1, widthPercent: 5 }, + { id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 }, { id: "B", title: "행정구역", row:0, colSpan:2 }, - { id: "sidoNm", title: "시도", upName:"upChangeRe2", upSequnce:1, row:1 }, - { id: "sggNm", title: "시군구", upName:"upChangeRe2",upSequnce:2, row:1 }, - { id: "bscFctNm", title: "시설명", row:0, rowSpan:2 }, + { id: "sidoNm", title: "시도", row:1, widthPercent: 6 }, + { id: "sggNm", title: "시군구", row:1, widthPercent: 6 }, + { id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 }, { id: "daddr", title: "주소", row:0, rowSpan:2 }, - { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2 }, - { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2 }, + { id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 6 }, + { id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 }, { id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 }, - { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1 }, - { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1 }, - { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1 }, - { id: "properYn", title: "적정여부", row:0, rowSpan:2 }, + { id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 6}, + { id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 6 }, + { id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 6 }, + { id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 6 }, ]; // 모달 @@ -288,6 +288,7 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy const bscFctCd = item.bscFctCd; const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as ApiResponse; const calData = CalcRainEffect(res2.data, 'SUNNY'); + let chungcunSumFlow = 0; let sumSummerChungcunDay = 0; diff --git a/apps/sn/.env.local b/apps/sn/.env.local index 9d5804fc0..ed1b605c3 100644 --- a/apps/sn/.env.local +++ b/apps/sn/.env.local @@ -11,6 +11,9 @@ NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr/openapi/Gettile.do?apiKey=04trYP9_ NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083 NEXT_PUBLIC_DC_URL = https://apigateway.apps.rsonesoft.com +NEXT_PUBLIC_DEV_CM_LOGIN_PAGE_URL = http://localhost:3000/auth/login +NEXT_PUBLIC_VDI_DEV_CM_LOGIN_PAGE_URL = http://localhost:3000/auth/login +NEXT_PUBLIC_VDI_DEV_CM_LOGIN_PAGE_URL = http://localhost:3000/auth/login #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883 #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.222:8883 #NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883 \ No newline at end of file diff --git a/apps/sn/app/(map-layout)/layout.tsx b/apps/sn/app/(map-layout)/layout.tsx index 2ea6758b3..f58e67489 100644 --- a/apps/sn/app/(map-layout)/layout.tsx +++ b/apps/sn/app/(map-layout)/layout.tsx @@ -1,3 +1,16 @@ +/** + * ➡️ 경로 : 하수관망도 모든 페이지 + * + * 📄 Map Layout + * Next.js App Router (app/) 기반 맵 레이아웃 컴포넌트 + * + * - 메뉴 클릭 이벤트 처리 및 라우팅 + * - 현재 메뉴 정보 Zustand를 통한 상태 관리 + * - 시도/시군구/사업 구분/사업 유형 데이터 초기 로드 + * - NoFooterLayout을 통한 공통 레이아웃 적용 + * - QueryClient를 통한 데이터 캐싱 및 관리 + * - 경로 변경 시 메뉴 정보 동기화 + */ "use client"; import React, { useEffect } from 'react'; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx index 04490f741..0e2ec3780 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/MsSwagePpl.tsx @@ -1,3 +1,18 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수관로) + * + * 📄 MsSwagePpl + * 하수관로 정보 컴포넌트 + * + * - 하수관로의 자체입력정보 표시 및 편집 기능 + * - 보수 및 갱신, 청소 및 준설, 점검 및 진단 데이터 조회 및 표시 + * - VerticalTable을 통한 입력 폼 렌더링 + * - InputSection을 통한 운영 데이터 관리 + * - 저장 버튼을 통한 데이터 저장 기능 + * + * 🔗 사용 API + * - 시설별 운영 정보 조회: GET /api/v1/bizInfo/bizByFclt (sewerage-service) + */ 'use client' import { VerticalTable } from '@/components/ui/verticalTable'; import React, { useState, useEffect } from 'react' @@ -88,9 +103,6 @@ const MsSwagePpl = ({ featureData, onSaveClick }: { featureData: any, onSaveClic setInspectionData(inspectionArr); setCleaningData(cleaningArr); setRepairData(repairArr); - console.log('inspectionArr', inspectionArr); - console.log('cleaningArr', cleaningArr); - console.log('repairArr', repairArr); }; fetchAll(); }, [featureData]); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx index 1b5a25aa3..d55e1c9c2 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx @@ -1,7 +1,21 @@ -// 우수토실 +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (우수토실) + * + * 📄 Ssc + * 우수토실 정보 컴포넌트 + * + * - 우수토실의 자체입력정보 표시 및 편집 기능 + * - 중점우수토실 운영정보 모달 표시 (강우/측정 정보, 수량/수질측정 정보) + * - VerticalTable을 통한 입력 폼 렌더링 + * - 저장 버튼을 통한 데이터 저장 기능 + * + * 🔗 사용 API + * - 위경도로 강우시 미처리 하수 목록 조회: GET /api/v1/onsemiro/getSwgRainsByGeomety (sewerage-service) + * - 강우시 월류 하수 관리 모니터링 조회: GET /api/v1/onsemiro/swgRain/{adstDstrCd}/{manageNo}/mntrngs (sewerage-service) + */ import { UiModal, UiTable } from '@common/business_components/ui'; import { Button, TableHead, TableRow } from '@common/components/ui'; -import React, { useState, useEffect, useCallback } from 'react'; +import React, { useState, useEffect } from 'react'; import { untrtSwgRainCol3, untrtSwgRainCol4, untrtSwgRainCol5 } from '../common/table'; import { VerticalTable } from '@/components/ui/verticalTable'; import { getData } from "@/components/lib/api"; @@ -34,8 +48,6 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: { const [isResetDetailPage, setIsResetDetailPage] = useState(true); const [isResetSelection, setIsResetSelection] = useState(false); - console.log('featureData', featureData); - // 강우, 측정 정보 API 호출 함수 const fetchRainMeasureData = async (chmbrXcnts: string, chmbrYdnts: string) => { setIsResetDetailPage(true); @@ -53,13 +65,8 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: { size: '3', }); - console.log('queryParams', queryParams.toString()); - console.log(`추가 데이터 API 호출 시작: v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`); - const result = await getData(`v1/onsemiro/getSwgRainsByGeomety?${queryParams.toString()}`); - console.log('추가 데이터 API 호출 성공:', result); - const processedDataArray: any[] = result.content.map((data: any) => { // 🎯 formatDisplayData로 기본 포맷팅 적용 const formattedItem = formatDisplayData(data); @@ -92,12 +99,8 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: { size: '3', }); - console.log(`SSC 추가 데이터 API 호출 시작: v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs?${queryParams.toString()}`); - const result = await getData(`v1/onsemiro/swgRain/${adstDstrCd}/${manageNo}/mntrngs?${queryParams.toString()}`); - console.log('SSC 추가 데이터 API 호출 성공:', result); - // 각 아이템 전처리 const processedDataArray = result.content.map((data: any) => { // 기본 포맷팅 적용 @@ -107,8 +110,6 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: { }; }); - console.log('processedDataArray', processedDataArray); - setMntrngsData(processedDataArray); setTotalDetailCount(result?.totalElements || 0); } catch (error) { diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/SwtrmtFclt.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/SwtrmtFclt.tsx index 366218ec1..8b029673f 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/SwtrmtFclt.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/SwtrmtFclt.tsx @@ -1,3 +1,13 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수처리시설) + * + * 📄 SwtrmtFclt + * 하수처리시설 정보 컴포넌트 + * + * - 하수처리시설의 디지털 자료관 연계 정보 표시 + * - VerticalTable을 통한 테이블 렌더링 + * - 조회 버튼을 통한 모달 표시 및 ReportTab 연동 + */ 'use client' import React, { useState } from 'react' import { VerticalTable } from '@/components/ui/verticalTable'; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts index ae5c87298..aba8d2eed 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/aplcnYms.ts @@ -84,7 +84,6 @@ const selectAplcnYms = async(gubun:string) => { // 상수사용월 const queryString = ''; const result = await getData(`v1/${gubun}/aplcnYm${queryString ? `?${queryString}` : ''}`); if (result && result.length > 0) { - console.log("selectAplcnYms", result); return getOptionsAplcnYm(result); } } catch (error) { @@ -119,7 +118,6 @@ export const selectInftwtAnls = async(aplcnYm:string) => { // 침입수분석 const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : ''; const result = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); if (result && result.numberOfElements > 0) { - console.log("selectInftwtAnls", result.content); return result.content; } } catch (error) { @@ -141,7 +139,6 @@ export const selectInftwtAnlsRslt = async(inftwtAnlsSn:number, pplMngNo:string) } const result = await getData(`v1/inftwtAnlsRslt/ppl/${inftwtAnlsSn}/${pplMngNo}`); if (result && result.numberOfElements > 0) { - console.log("selectInftwtAnlsRslt", result.content); return result.content; } } catch (error) { @@ -163,7 +160,6 @@ export const selectOilq = async(inftwtAnlsSn:number, pplMngNo:string) => { // } const result = await getData(`v1/inftwtAnlsRslt/oilqPpl/${inftwtAnlsSn}/${pplMngNo}`); if (result && result.numberOfElements > 0) { - console.log("selectOilq", result.content); return result.content; } } catch (error) { @@ -178,7 +174,6 @@ export const selectPplInftwtQty = async(inftwtAnlsSn:number, pplMngNo:string) => } const result = await getData(`v1/inftwtAnlsRslt/pplInftwtQty/${inftwtAnlsSn}/${pplMngNo}`); if (result.length > 0) { - console.log("selectPplInftwtQty", result); return result[0].avg_day_flow; } else { return 0; // 데이터가 없을 경우 0 반환 @@ -196,7 +191,6 @@ export const selectPplRdiiQty = async(rainInfwtAnlsSn:number, pplMngNo:string) = } const result = await getData(`v1/rdiiAnlsRslt/pplRdiiQty/${rainInfwtAnlsSn}/${pplMngNo}`); if (result?.sustaintime > 0) { - console.log("selectPplRdiiQty", result); return result; } } catch (error) { @@ -218,7 +212,6 @@ export const selectRdiiAnls = async(aplcnYm:string) => { // 침입수분석 const queryString = aplcnYm ? `aplcnYmFrom=${aplcnYm}&aplcnYmTo=${aplcnYm}` : ''; const result = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`); if (result && result.numberOfElements > 0) { - console.log("selectRdiiAnls", result.content); return result.content; } } catch (error) { @@ -262,7 +255,6 @@ export const selectRainData = async(rainInfwtAnlsSn:number) => { // 강우데이 } const result = await getData(`v1/rdiiAnlsRslt/rainData/${rainInfwtAnlsSn}`); if (result && result.numberOfElements > 0) { - console.log("selectRainData", result.content); return result.content; } } catch (error) { diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx index 542156c2a..9f481a2b9 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/chart/infilChart.tsx @@ -63,7 +63,6 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => { // 상수사용월 변경 핸들러 const handleAplcnYmChange = async (val: string | number) => { const selectedValue = String(val); - console.log("선택된 상수사용월:", selectedValue); setSelectedAplcnYm(selectedValue); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx index b3db19b1c..e0fe03a92 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx @@ -1,3 +1,26 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 + * + * 📄 FeatureClickEventPopup + * 시설물(피처) 클릭시 오른쪽 팝업창 컴포넌트 + * + * - 지도 시설물(피처) 클릭 시 팝업 표시 및 데이터 로딩 + * - 레이어 유형에 따른 동적 테이블 및 헤드리스트 설정 + * - 자체입력정보 조회 및 저장 기능 (하수관로, 우수토실, 하수펌프장, 하수맨홀) + * - 코드 매핑 및 데이터 포맷팅 처리 + * - 상류관로 검색, 침입수/RDII 분석 차트 표시 + * - 모달을 통한 저장 확인 및 API 연동 + * + * 🔗 사용 API + * - 하수관로 자체입력정보 조회: GET /api/v1/fcltppl/{fcltMngNo}/{mngInstCd} (sewerage-service) + * - 우수토실 자체입력정보 조회: GET /api/v1/fcltstofcbr/{fcltMngNo}/{mngInstCd} (sewerage-service) + * - 하수펌프장 자체입력정보 조회: GET /api/v1/fcltpump/{fcltMngNo}/{mngInstCd} (sewerage-service) + * - 하수맨홀 자체입력정보 조회: GET /api/v1/fcltmhl/{fcltMngNo}/{mngInstCd} (sewerage-service) + * - 하수관로 자체입력정보 저장: POST /api/v1/fcltppl (sewerage-service) + * - 우수토실 자체입력정보 저장: POST /api/v1/fcltstofcbr (sewerage-service) + * - 하수펌프장 자체입력정보 저장: POST /api/v1/fcltpump (sewerage-service) + * - 하수맨홀 자체입력정보 저장: POST /api/v1/fcltmhl (sewerage-service) + */ 'use client' import { getData, postData } from "@/components/lib/api"; import Modal from "@/components/ui/modal"; @@ -75,7 +98,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, if (featureData['ol_uid']) { // Gis 레이어 클릭 이벤트 setIsClicked(true); - console.log('gis data', featureData.values_); const lyrTyNm = featureData.id_.split('.')[0]; switch (lyrTyNm) { @@ -139,7 +161,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, else { // SearchModal 클릭 이벤트 setIsClicked(false); - console.log('SearchModal data', featureData); const lyrTyNm = featureData.lyrTypeNm; switch (lyrTyNm) { @@ -158,12 +179,10 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, case 'tb_ms_swage_pmstn': { const drtwPumpCode = DRTW_SEWAGE_PUMP_USE_CODES.find(code => code.text === '오수펌프장'); if (drtwPumpCode && featureData.usgCd.trim() === drtwPumpCode.val) { - console.log('오수펌프장'); setIsDrtwSewagePump(false); setHeadlist(ExclnSewagePumpCol2) } else { - console.log('빗물펌프장'); setIsDrtwSewagePump(true); setHeadlist(DrtwSewagePumpCol2) } @@ -299,9 +318,6 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, const result = await getData(apiEndpoint); if (result) { - console.log('API 데이터 로드 성공:', result); - - // ✅ codeMapper 사용하여 API 결과도 변환 const processedApiData = codeMapper({ layerName: selectedLayerName, data: { ...result, ...tableData } @@ -381,12 +397,9 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, bodyData.prrtymngYn = 'N'; } } - console.log('bodyData', bodyData); - console.log('apiEndpoint', apiEndpoint); try { result = await postData(apiEndpoint, bodyData); - console.log('result', result); if (result) { alert('저장되었습니다'); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/sewagePump.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/sewagePump.tsx index 5dcde5f5e..07d78a7d1 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/sewagePump.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/sewagePump.tsx @@ -1,3 +1,13 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수펌프장) + * + * 📄 sewagePump + * 하수펌프장 정보 컴포넌트 + * + * - 빗물펌프장 및 오수펌프장 구분에 따른 자체 입력 정보 표시 및 편집 기능 + * - VerticalTable을 통한 입력 폼 렌더링 + * - 저장 버튼을 통한 데이터 저장 기능 + */ import { VerticalTable } from '@/components/ui/verticalTable'; import React, { useState, useEffect } from 'react' // 빗물펌프장 자체 입력 정보 @@ -12,7 +22,7 @@ const drtwInputColumn = [ { id: "mltvDtdvNm", title: "처리분구", type: "input" }, ] -// 하수펌프장 + const sewagePump = ({ featureData, isDrtwSewagePump, onSaveClick }: { featureData: any, isDrtwSewagePump?: boolean, onSaveClick?: () => void }) => { const [formData, setFormData] = useState({}); diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx index f19518ab1..f814092e7 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx @@ -1,4 +1,17 @@ -// 하수맨홀 +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수맨홀) + * + * 📄 Smh + * 하수맨홀 정보 컴포넌트 + * + * - 하수맨홀의 자체입력정보 표시 및 편집 기능 + * - VerticalTable을 통한 입력 폼 렌더링 + * - 상류관로 검색 및 지도 포커스 기능 + * - 저장 버튼을 통한 데이터 저장 기능 + * + * 🔗 사용 API + * - 상류관로 조회: GET /api/v1/fcltmhl/upperPpls/{fcltMngNo} (sewerage-service) + */ import { VerticalTable } from '@/components/ui/verticalTable'; import { useEffect, useState } from 'react'; import GisApp from "@common/business_components/ui/map/lib/gis.core"; diff --git a/apps/sn/app/(map-layout)/map/components/popupComponent/stormWaterPump.tsx b/apps/sn/app/(map-layout)/map/components/popupComponent/stormWaterPump.tsx index 96f10fa55..92973b133 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/stormWaterPump.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/stormWaterPump.tsx @@ -1,3 +1,12 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (빗물펌프) + * + * 📄 StormWaterPump + * 빗물펌프 정보 컴포넌트 + * + * - 빗물펌프의 자체입력정보 표시 및 편집 기능 + * - VerticalTable을 통한 입력 폼 렌더링 + */ import { VerticalTable } from '@/components/ui/verticalTable'; import React from 'react' const inputColumn = [ diff --git a/apps/sn/app/(map-layout)/map/page.tsx b/apps/sn/app/(map-layout)/map/page.tsx index 7ca34053b..651738642 100644 --- a/apps/sn/app/(map-layout)/map/page.tsx +++ b/apps/sn/app/(map-layout)/map/page.tsx @@ -1,3 +1,20 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 + * + * 📄 Map Page + * 지도 페이지 컴포넌트 + * + * - OpenLayers 기반 GIS 지도 렌더링 및 상호작용 + * - 레이어 트리 데이터 관리 및 동적 레이어 표시/숨김 + * - 피처 검색 및 선택 기능 (SearchModal, ProcSearchBar) + * - 피처 클릭 이벤트 처리 및 상세 정보 팝업 표시 + * - 수심(WaterDepth) 레이어 애니메이션 재생 기능 + * - Zustand를 통한 검색 모달 상태 관리 + * + * 🔗 사용 API + * - 레이어 설정 조회: GET /api/v1/map/lyrStngs/{lyrGrp} (sewerage-service) + */ + "use client"; import Gis from "@common/business_components/ui/map/Gis"; @@ -10,7 +27,6 @@ import { WaterDepth, WATER_DEPTH_LAYER_TYPES } from "./waterDepth/waterDepth"; import { ProcSearchBar } from "@common/business_components/ui/map/searchBar"; import useSearchModalStore from "@/store/useSearchModalStore"; - const Map = () => { const { isSearchModalOpen, setIsSearchModalOpen } = useSearchModalStore(); @@ -73,7 +89,6 @@ const Map = () => { }); } - // 3. 피처 선택 if (foundFeature) { let geometry = foundFeature.getGeometry(); diff --git a/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx index 62fed6a28..6d1507f06 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx @@ -1,3 +1,13 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 + * + * 📄 BasicTab Component + * Next.js App Router (app/) 기반 검색 모달의 기본정보 탭 컴포넌트 + * + * - 기본정보 검색을 위한 구분 선택 및 조건 입력 UI 제공 + * - 하수관로, 하수처리시설, 하수처리구역, 하수맨홀, 하수펌프장, 우수토실 등 다양한 유형별 컴포넌트 렌더링 + * - useSearchModalStore를 통해 상태 관리 및 사용자 상호작용 처리 + */ import React from 'react'; import { SelectBox } from '@common/business_components/ui'; import { Label } from '@common/components'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx index c77cc58cc..13025e2ec 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx @@ -1,9 +1,22 @@ -import React, { use } from 'react'; +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 운영정보 탭 + * + * 📄 Operation Tab + * Next.js App Router (app/) 기반 검색 모달 운영정보 탭 컴포넌트 + * + * - 업무구분 선택 (보수 및 갱신, 점검 및 진단, 청소 및 준설) + * - 사업명 입력 및 수행기간 범위 선택 + * - 사업 유형 필터링 기능 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ +import React from 'react'; import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { SelectBox } from '@common/business_components/ui'; import { Button, Input, Label } from '@common/components'; -import useStore from '../../../store/useStore'; -import useSearchModalStore from '../../../store/useSearchModalStore'; +import useStore from '@/store/useStore'; +import useSearchModalStore from '@/store/useSearchModalStore'; import useSearchModal from './useSearchModal'; import useOperationTab from './useOperationTab'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/reportFilesModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/reportFilesModal.tsx index 62c62b811..8be73ba1e 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/reportFilesModal.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/reportFilesModal.tsx @@ -1,6 +1,18 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 하수도정비기본계획보고서 탭 (셀 클릭) + * + * 📄 Report Files Modal + * Next.js App Router (app/) 기반 보고서 파일 모달 컴포넌트 + * + * - 하수도정비 기본계획 보고서 파일 목록 표시 + * - 파일명 및 등록일자 정보 테이블 출력 + * - 페이지네이션 및 로딩 오버레이 지원 + * - 파일 클릭 이벤트 처리 및 상세 조회 + * - Zustand를 통한 모달 상태 및 데이터 관리 + * - 모달 열림/닫힘 시 데이터 초기화 기능 + */ 'use client' -import React, { useEffect, useState } from 'react'; - +import React, { useEffect } from 'react'; import LoadingOverlay from '@/components/ui/LoadingBar'; import useReportTab from './useReportTab'; import { useReportTabStore } from '@/store/useReportTabStore'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx index 1885cd8e9..cbc635a7c 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx @@ -1,3 +1,16 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 하수도정비기본계획보고서 탭 + * + * 📄 Report Tab + * Next.js App Router (app/) 기반 검색 모달 보고서 탭 컴포넌트 + * + * - 하수도정비 기본계획 보고서 목록 표시 및 필터링 + * - 시도/시군구/보고서 구분/승인년도 기반 검색 기능 + * - 테이블 데이터 표시 및 페이지네이션 지원 + * - 보고서 클릭 시 파일 목록 모달 열기 + * - Zustand를 통한 모달 상태 및 데이터 관리 + * - 로딩 오버레이 및 선택 초기화 기능 + */ 'use client'; import React, { useEffect, useState } from 'react'; import { Button, Label } from '@common/components'; @@ -7,6 +20,7 @@ import LoadingOverlay from '@/components/ui/LoadingBar'; import useReportTab from './useReportTab'; import useStore from '@/store/useStore'; import { CtpvSggPrcsFcltSelectBox } from '@/components/ui/ctpvSggPrcsFcltSelectBox'; +import useSearchModalStore from '@/store/useSearchModalStore'; import { useReportTabStore } from '@/store/useReportTabStore'; import ReportFilesModal from './reportFilesModal'; // 파일목록모달 @@ -31,19 +45,31 @@ interface ReportTabProps { const ReportTab: React.FC = ({ open, isSearch = true, ctpvNm, sggNm }) => { - const [isLoading, setIsLoading] = useState(false); + // const [isLoading, setIsLoading] = useState(false); const [isResetPage, setIsResetPage] = useState(false); const [isResetSelection, setIsResetSelection] = useState(false); const [showTable, setShowTable] = useState(false); - const [tableData, setTableData] = useState([]); - const [tableCount, setTableCount] = useState(0); - const [curPage, setCurPage] = useState(1); - const [yearFilter, setYearFilter] = useState({ start: "", end: "" }); + // const [tableData, setTableData] = useState([]); + // const [tableCount, setTableCount] = useState(0); + // const [curPage, setCurPage] = useState(1); + // const [yearFilter, setYearFilter] = useState({ start: "", end: "" }); const [ctpvCd, setCtpvCd] = useState('0'); const [sggCd, setSggCd] = useState('0'); const [reportGubun, setReportGubun] = useState("0"); const [clsfSystmSn, setClsfSystmSn] = useState(''); // 자료관 기본계획 일련번호 + const { + tableData, + tableCount, + isLoading, + yearFilter, + curPage, + setTableData, + setTableCount, + setIsLoading, + setYearFilter, + setCurPage + } = useSearchModalStore(); const { ctpv, sgg } = useStore(); const { isOpen: isReportFilesModalOpen, diff --git a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx index da1f05169..d2537663e 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx @@ -1,12 +1,23 @@ +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 + * + * 📄 Search Modal + * Next.js App Router (app/) 기반 검색 모달 컴포넌트 + * + * - 탭 기반 검색 인터페이스 (기본정보, 운영정보, 보고서) + * - 테이블 데이터 표시 및 페이지네이션 기능 + * - 시설물 조회 결과 및 운영 사업 현황 표시 + * - 엑셀 다운로드 및 지도에서 보기 기능 + * - Zustand를 통한 검색 모달 상태 관리 + * - 로딩 오버레이 및 선택 초기화 지원 + */ import LoadingOverlay from '@/components/ui/LoadingBar'; import { UiModal, UITab, UiTable } from '@common/business_components/ui'; import { Button } from '@common/components/ui'; -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { Toaster } from "react-hot-toast"; -import useSearchModalStore from '../../../store/useSearchModalStore'; -import { - ExclnSewagePumpCol2, MsSwageMhlCol2, MsSwagePplCol2, stofcbrCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2 -} from '../components/common/table'; +import useSearchModalStore from '@/store/useSearchModalStore'; +import { ExclnSewagePumpCol2, MsSwageMhlCol2, MsSwagePplCol2, stofcbrCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2 } from '../components/common/table'; import BasicTab, { BASIC_TYPES } from './basicTab'; import OperationTab from './operationTab'; import ReportTab from './reportTab'; @@ -16,18 +27,24 @@ import useOperationTab from './useOperationTab'; const SearchModal: React.FC = () => { const { + showTable, isSearchModalOpen, setIsSearchModalOpen, activeTab, basicType, workType, tableData, detailTableData, tableCount, detailTableCount, curPage, detailCurPage, + detailBizId, isLoading, isDetailLoading, isResetPage, isResetDetailPage, isResetSelection, isResetDetailSelection, setActiveTab, setCurPage, setDetailCurPage, + setIsResetPage, setIsResetDetailPage, + setDetailBizId, + setIsResetDetailSelection, + resetFilters } = useSearchModalStore(); - const { TABS, viewMultipleFeature } = useSearchModal(); + const { TABS, viewMultipleFeature, fetchFilteredData } = useSearchModal(); const { handleBasicCellClick, basicExcelDownload } = useBasicTab(); const { WORK_TYPES, @@ -39,7 +56,8 @@ const SearchModal: React.FC = () => { handleOperationCellClick, handleOperationResultCellClick, operationExcelDownload, - operationResultExcelDownload + operationResultExcelDownload, + handleOperationPageNation } = useOperationTab(); @@ -69,6 +87,24 @@ const SearchModal: React.FC = () => { return []; }, [activeTab, workType]); + useEffect(() => { + resetFilters(); + }, [activeTab, basicType, workType]); + + // 페이지 변경 시마다 데이터 fetch + useEffect(() => { + setIsResetPage(false); + setIsResetDetailPage(true); + setDetailBizId(0); + if (showTable) fetchFilteredData(); + }, [curPage]); + + // 페이지 변경 시마다 데이터 fetch + useEffect(() => { + setIsResetDetailSelection(false); + if (showTable) handleOperationPageNation(Number(detailBizId)); + }, [detailCurPage]); + const renderBody = () => ( <> diff --git a/apps/sn/app/(map-layout)/map/searchModal/stofcbr.tsx b/apps/sn/app/(map-layout)/map/searchModal/stofcbr.tsx index 11c4c8bfa..4fc830c59 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/stofcbr.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/stofcbr.tsx @@ -1,5 +1,15 @@ -// 우수토실 - +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 우수토실) + * + * 📄 Stofcbr Tab + * Next.js App Router (app/) 기반 검색 모달 우수토실 탭 컴포넌트 + * + * - 시도/시군구 선택 및 설치년도 범위 필터링 + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { Button } from '@common/components'; import React from 'react'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/swageMhl.tsx b/apps/sn/app/(map-layout)/map/searchModal/swageMhl.tsx index 04ffeb1fa..aade9662a 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/swageMhl.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/swageMhl.tsx @@ -1,5 +1,16 @@ -// 하수맨홀 - +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수맨홀) + * + * 📄 SwageMhl Tab + * Next.js App Router (app/) 기반 검색 모달 하수맨홀 탭 컴포넌트 + * + * - 시도/시군구 선택 및 설치년도 범위 필터링 + * - 용도 및 구경 범위 기반 검색 기능 + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ import React from 'react'; import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { Button, Input, Label } from '@common/components'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/swagePmstn.tsx b/apps/sn/app/(map-layout)/map/searchModal/swagePmstn.tsx index f3eef5d66..a9be8704e 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/swagePmstn.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/swagePmstn.tsx @@ -1,5 +1,16 @@ -// 하수펌프장 - +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수펌프장) + * + * 📄 SwagePmstn Tab + * Next.js App Router (app/) 기반 검색 모달 하수펌프장 탭 컴포넌트 + * + * - 시도/시군구 선택 및 설치년도 범위 필터링 + * - 일일처리용량 및 양수능력 범위 기반 검색 기능 + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { Button, Input, Label } from '@common/components'; import React from 'react'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/swagePpl.tsx b/apps/sn/app/(map-layout)/map/searchModal/swagePpl.tsx index 0a79d8f81..9378c779b 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/swagePpl.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/swagePpl.tsx @@ -1,5 +1,16 @@ -// 하수관로 - +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수관로) + * + * 📄 SwagePpl Tab + * Next.js App Router (app/) 기반 검색 모달 하수관로 탭 컴포넌트 + * + * - 시도/시군구 선택 및 설치년도 범위 필터링 + * - 용도 및 관경 범위 기반 검색 기능 + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { SelectBox } from '@common/business_components/ui'; import { Button, Input, Label } from '@common/components'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/swagePrcsFclt.tsx b/apps/sn/app/(map-layout)/map/searchModal/swagePrcsFclt.tsx index 97486e4a3..395c936a4 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/swagePrcsFclt.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/swagePrcsFclt.tsx @@ -1,5 +1,16 @@ -// 하수처리시설 - +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수처리시설) + * + * 📄 SwagePrcsFclt Tab + * Next.js App Router (app/) 기반 검색 모달 하수처리시설 탭 컴포넌트 + * + * - 시도/시군구 선택 및 가동개시일자 범위 필터링 + * - 시설용량 범위 기반 검색 기능 + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ import React from 'react'; import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox'; import { Button, Input, Label } from '@common/components'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/swagePrcsZone.tsx b/apps/sn/app/(map-layout)/map/searchModal/swagePrcsZone.tsx index dcda670f2..0d1fb9fc4 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/swagePrcsZone.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/swagePrcsZone.tsx @@ -1,5 +1,15 @@ -// 하수처리구역 - +/** + * ➡️ 경로 : 하수관망도 메인 페이지 (오른쪽 돋보기 모양 클릭) - 검색 모달 창 내 기본정보 탭 (구분: 하수처리구역) + * + * 📄 SwagePrcsZone Tab + * Next.js App Router (app/) 기반 검색 모달 하수처리구역 탭 컴포넌트 + * + * - 시도/시군구 선택 및 하수처리시설명/구역명 기반 검색 기능 + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - Zustand를 통한 상태 관리 및 필터 값 저장 + * - Enter 키 입력 시 자동 조회 지원 + */ import React from 'react'; import { CtpvSggPrcsFcltSelectBox } from '@/components/ui/ctpvSggPrcsFcltSelectBox'; import { Button, Input, Label } from '@common/components'; diff --git a/apps/sn/app/(map-layout)/map/searchModal/useBasicTab.ts b/apps/sn/app/(map-layout)/map/searchModal/useBasicTab.ts index 1d49529da..80d3deb50 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/useBasicTab.ts +++ b/apps/sn/app/(map-layout)/map/searchModal/useBasicTab.ts @@ -1,6 +1,18 @@ -import { useEffect, useState } from 'react'; +/** + * 📄 useBasicTab Hook + * 검색 모달 기본정보 탭 훅 + * + * - 필터링된 시설물 데이터 조회 및 포맷팅 + * - 테이블 셀 클릭 시 지도 피처 선택 및 줌 기능 + * - 엑셀 다운로드 기능 (한글 헤더 지원) + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - Zustand를 통한 상태 관리 및 로딩 처리 + * - 데이터 매핑 및 코드 변환 (시도/시군구, 용도 등) + * + * 🔗 사용 API + * - 관망도 시설물 목록 조회: GET /api/v1/fclts (sewerage-service) + */ import { downloadExcelWithKoreanHeaders } from '@common/business_components/ui'; -import axios from 'axios'; import { MS_SWAGE_PPL_USE_CODES, MS_SWAGE_MHL_CODES, MS_SWAGE_MHL_USE_CODES, MsSwagePplExcelCol, SwtrmtFcltExcelCol, SwtrmtPrcsZoneExcelCol, MsSwageMhlExcelCol, ExclnSewagePumpExcelCol, stofcbrExcelCol @@ -8,11 +20,11 @@ import { import { getData } from "@/components/lib/api"; import { BASIC_TYPES } from './basicTab'; import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue'; -import useStore from '../../../store/useStore'; +import useStore from '@/store/useStore'; import GisApp from "@common/business_components/ui/map/lib/gis.core"; import { confirmToast } from '@/components/ui/toast' import { toast } from "react-hot-toast"; -import useSearchModalStore from '../../../store/useSearchModalStore'; +import useSearchModalStore from '@/store/useSearchModalStore'; import { swagePplCqlFilters } from './swagePpl'; import { swagePrcsFcltCqlFilters } from './swagePrcsFclt'; import { swagePrcsZoneCqlFilters } from './swagePrcsZone'; @@ -52,11 +64,6 @@ export default function useBasicTab() { if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); const res = await getData(`v1/fclts?${queryParams.toString()}`); - // const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); - console.log('fetch res', res); - console.log('fetch res.data', res.data); - console.log('fetch res.count', res.count); - console.log('fetch res.length', res.length); // 🎯 각 아이템을 개별적으로 포맷팅하면서 일련번호 추가 const dataWithRowNumber = (res.data || []).map((item: any, index: number) => { @@ -186,15 +193,13 @@ export default function useBasicTab() { if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and ')); const res = await getData(`v1/fclts?${queryParams.toString()}`); - // const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`); - console.log('onDownload res', res); const mhlUsgCdMap = new Map(MS_SWAGE_MHL_USE_CODES.map(code => [code.val?.trim(), code.text])); const pplUsgCdMap = new Map(MS_SWAGE_PPL_USE_CODES.map(code => [code.val?.trim(), code.text])); const ctpvMap = new Map(ctpv.map(code => [code.val?.trim(), code.text])); const sggMap = new Map(sgg.map(code => [code.val?.trim(), code.text])); - const mappedContent = (res.data.data || []).map((item: any) => { + const mappedContent = (res.data || []).map((item: any) => { const formattedItem = formatDisplayData(item); let ctpvCd = item?.ctpvCd ?? formattedItem?.ctpvCd ?? ''; @@ -306,8 +311,6 @@ export default function useBasicTab() { const label = BASIC_TYPES.find((type) => type.val === basicType)?.text const fileName = `${label} 조회 결과_${todayYear}${todayMonth}${todayDate}`; - console.log(`excelData: ${excelData}, label: ${label}, fileName: ${fileName}`); - await downloadExcelWithKoreanHeaders({ data: excelData as JSON[], fileName: fileName, diff --git a/apps/sn/app/(map-layout)/map/searchModal/useOperationTab.ts b/apps/sn/app/(map-layout)/map/searchModal/useOperationTab.ts index dd7b8d3cc..a4df8ae92 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/useOperationTab.ts +++ b/apps/sn/app/(map-layout)/map/searchModal/useOperationTab.ts @@ -1,3 +1,19 @@ +/** + * 📄 useOperationTab Hook + * 검색 모달 운영정보 탭 훅 + * + * - 필터링된 사업 현황 데이터 조회 및 포맷팅 + * - 사업 현황 테이블 셀 클릭 시 상세 결과표 조회 + * - 결과표 셀 클릭 시 지도 피처 선택 및 줌 기능 + * - 엑셀 다운로드 기능 (사업 현황 및 결과표) + * - CQL 필터 생성을 통한 쿼리 조건 설정 + * - Zustand를 통한 상태 관리 및 로딩 처리 + * - 데이터 매핑 및 코드 변환 (사업 유형, 용도, 재질 등) + * + * 🔗 사용 API + * - 운영정보 목록 조회: GET /api/v1/bizInfo (sewerage-service) + * - 운영정보(사업정보) 관련 시설 목록 조회: GET /api/v1/bizInfo/fclts (sewerage-service) + */ import { downloadExcelWithKoreanHeaders } from '@common/business_components/ui'; import { MS_SWAGE_PPL_CODES, MS_SWAGE_PPL_USE_CODES } from '../components/common/table'; import { getData } from "@/components/lib/api"; @@ -347,15 +363,12 @@ export default function useOperationTab() { try { const RequestDTO: Record = { - size: '10000', + size: '100', bizId: String(detailBizId), }; - - const apiStartTime = performance.now(); + const res = await getData(`v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`); - const apiEndTime = performance.now(); - - const mappingStartTime = performance.now(); + // 헤더 매핑 정의 const headerMapping: { [key: string]: string } = { 'fcltMngNo': '관리번호', diff --git a/apps/sn/app/(map-layout)/map/searchModal/useReportTab.ts b/apps/sn/app/(map-layout)/map/searchModal/useReportTab.ts index 52fabc9f0..b93b6fb47 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/useReportTab.ts +++ b/apps/sn/app/(map-layout)/map/searchModal/useReportTab.ts @@ -1,7 +1,22 @@ +/** + * 📄 useReportTab Hook + * 검색 모달 보고서 탭 훅 + * + * - 계층적 폴더 구조 평탄화 및 데이터 변환 + * - 파일 목록 조회 및 페이징 처리 + * - 파일 다운로드 기능 + * - 셀 클릭 이벤트 처리 + * - Zustand를 통한 상태 관리 및 로딩 처리 + * - 데이터 매핑 및 코드 변환 (시도/시군구, 보고서 유형 등) + * + * 🔗 사용 API + * - 보고서 파일 조회: GET /api/v1/dc/file (dc-service) + * - 파일 다운로드: GET /api/v1/dc/file/download (dc-service) + */ import { getDcData } from '@/components/lib/api'; import { fileDownload } from '@/utils'; import { useReportTabStore } from '@/store/useReportTabStore'; -import useSearchModalStore from '@/app/store/useSearchModalStore'; +import useSearchModalStore from '@/store/useSearchModalStore'; export type Folder = { clsfSystmSn: string; diff --git a/apps/sn/app/(map-layout)/map/searchModal/useSearchModal.ts b/apps/sn/app/(map-layout)/map/searchModal/useSearchModal.ts index ba376290d..770a8700d 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/useSearchModal.ts +++ b/apps/sn/app/(map-layout)/map/searchModal/useSearchModal.ts @@ -1,4 +1,17 @@ -import { useEffect } from 'react'; +/** + * 📄 useSearchModal Hook + * 검색 모달 훅 + * + * - 탭 기반 검색 인터페이스 관리 (기본정보, 운영정보, 보고서) + * - 필터링된 데이터 조회 및 포맷팅 + * - 조회 버튼을 통한 데이터 검색 트리거 + * - 여러 시설 보기 기능 + * - Zustand를 통한 상태 관리 및 로딩 처리 + * - 데이터 매핑 및 코드 변환 (사업 유형 등) + * + * 🔗 사용 API + * - 운영정보 목록 조회: GET /api/v1/bizInfo (sewerage-service) + */ import { getData } from "@/components/lib/api"; import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue'; import useStore from '../../../store/useStore'; @@ -9,11 +22,9 @@ import useOperationTab from './useOperationTab'; export default function useSearchModal() { const { - activeTab, basicType, workType, - showTable, + activeTab, workType, tableData, detailTableData, - curPage, detailCurPage, - detailBizId, + curPage, var1, var2, yearFilter, todayYear, todayMonth, todayDate, @@ -25,12 +36,10 @@ export default function useSearchModal() { setIsLoading, setIsResetPage, setIsResetDetailPage, setIsResetSelection, setIsResetDetailSelection, - setDetailBizId, - resetFilters, getDateString } = useSearchModalStore(); const { fetchBasicFilteredData } = useBasicTab(); - const { OPERATION_TABLE_SIZE, handleOperationPageNation } = useOperationTab(); + const { OPERATION_TABLE_SIZE } = useOperationTab(); const { BIZ_TY_CD } = useStore(); const TABS = [ @@ -39,25 +48,6 @@ export default function useSearchModal() { { val: "report", text: "하수도정비기본계획보고서" }, ]; - useEffect(() => { - resetFilters(); - }, [activeTab, basicType, workType]); - - // 페이지 변경 시마다 데이터 fetch - useEffect(() => { - setIsResetPage(false); - setIsResetDetailPage(true); - setDetailBizId(0); - console.log(`curPage: ${curPage}, showTable: ${showTable}`); - if (showTable && curPage > 1) fetchFilteredData(); - }, [curPage]); - - // 페이지 변경 시마다 데이터 fetch - useEffect(() => { - setIsResetDetailSelection(false); - if (showTable) handleOperationPageNation(Number(detailBizId)); - }, [detailCurPage]); - // 검색 API 호출 함수 const fetchFilteredData = async () => { setIsLoading(true); // 로딩 시작 @@ -167,5 +157,5 @@ export default function useSearchModal() { } } - return { TABS, getDateString, handleSearch, viewMultipleFeature }; + return { TABS, getDateString, handleSearch, viewMultipleFeature, fetchFilteredData }; }; diff --git a/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx b/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx index be78c069c..6a5c3f893 100644 --- a/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx +++ b/apps/sn/app/(map-layout)/map/waterDepth/waterDepth.tsx @@ -1,3 +1,15 @@ +/** + * ➡️ 경로 : 하수관망도 메인페이지 내 침수심 범례 + * + * 📄 WaterDepth Component + * 침수심 범례 컴포넌트 + * + * - 침수심 레이어의 범례 표시 및 애니메이션 재생 제어 + * - 진행률 바를 통한 애니메이션 상태 시각화 + * - 플레이/일시정지 버튼을 통한 사용자 상호작용 + * - 범례 항목별 색상과 레이블 표시 + */ + "use client"; import { Label } from "@common/components/ui/label"; diff --git a/apps/sn/app/(with-base-layout)/fileValidation.tsx b/apps/sn/app/(with-base-layout)/fileValidation.tsx index c0711a7d2..987883251 100644 --- a/apps/sn/app/(with-base-layout)/fileValidation.tsx +++ b/apps/sn/app/(with-base-layout)/fileValidation.tsx @@ -1,5 +1,13 @@ /** + * 📄 File Validation Utility * 파일 확장자 검증 유틸리티 + * + * - 파일 확장자 검증 함수 (단일 및 다중 파일 지원) + * - 검증 결과 타입 정의 및 에러 메시지 생성 + * - 자주 사용되는 파일 확장자 상수 제공 + * - 파일 업로드 전 검증 로직 구현 + * - 사용자 친화적인 에러 메시지 출력 + * - 다양한 파일 타입(INP, EXCEL, OFFICE 등) 지원 */ // 파일 확장자 검증 함수 diff --git a/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx b/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx index af178ac59..43648114c 100644 --- a/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx +++ b/apps/sn/app/(with-base-layout)/ii/BaseLayout.tsx @@ -1,3 +1,16 @@ +/** + * ➡️ 경로 : I/I 분석 모든 페이지 + * + * 📄 Base Layout + * 분석 페이지 기본 레이아웃 컴포넌트 + * + * - 검색 및 필터링 UI 제공 (시도/시군구/하수처리시설 선택) + * - 날짜 범위 선택 기능 + * - 파일 다운로드 및 삭제 버튼 지원 + * - 분석 실행 버튼 및 확인 토스트 처리 + * - 양식 파일 다운로드 링크 제공 + * - 폼 제출 및 이벤트 핸들링 + */ 'use client' import { DateMonthPicker, Form, SelectBox } from '@common/business_components/ui' import ListDiv from '@common/business_components/ui/list_div' diff --git a/apps/sn/app/(with-base-layout)/ii/fileupload/page.tsx b/apps/sn/app/(with-base-layout)/ii/fileupload/page.tsx index 75ddd89a0..9f90d5ead 100644 --- a/apps/sn/app/(with-base-layout)/ii/fileupload/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/fileupload/page.tsx @@ -1,3 +1,21 @@ +/** + * ➡️ 경로 : /ii/fileupload + * + * 📄 File Upload Page + * 파일 업로드 테스트 페이지 컴포넌트 + * + * - 파일 선택 및 텍스트 입력 기능 + * - JSON 데이터와 파일을 함께 서버에 업로드 + * - 쿠키 기반 인증 토큰을 통한 사용자 조회 + * - 두 가지 방식의 사용자 조회 API 호출 지원 + * - Axios를 통한 파일 업로드 처리 + * - 폼 제출 및 에러 핸들링 + * + * 🔗 사용 API + * - 사이트 정보 조회: POST /api/v1/inftwtAnls/users/{userId} (sewerage-service) + * - 침입수분석 등록 첨부파일INP 포함: POST /api/v1/rdiiAnls/savewithfile (sewerage-service) + * - 사용자 단 건 조회: GET /api/v1/users/{userUnqId} (user-service) + */ 'use client' // FileUpload.js diff --git a/apps/sn/app/(with-base-layout)/ii/irsetting/page.tsx b/apps/sn/app/(with-base-layout)/ii/irsetting/page.tsx index 97864aa20..e2a23759b 100644 --- a/apps/sn/app/(with-base-layout)/ii/irsetting/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/irsetting/page.tsx @@ -1,3 +1,20 @@ +/** + * ➡️ 경로 : I/I 분석 - 침입수 분석 + * + * 📄 IrSetting Page + * 침입수 분석 설정 페이지 컴포넌트 + * + * - 오수관망도, 수용가-맨홀 매칭결과, 오수량 시간패턴 등 파일 업로드 기능 + * - 오수전환율 및 분석 정보 입력 기능 + * - 엑셀 파일 데이터 파싱 및 JSON 변환 처리 + * - 분석 데이터 서버 제출 및 폼 초기화 기능 + * - 파일 확장자 및 입력 값 검증 기능 + * - 로딩 오버레이 및 에러 핸들링 지원 + * + * 🔗 사용 API + * - 침입수분석 등록 첨부파일INP 포함: POST /api/v1/inftwtAnls/savewithfile (sewerage-service) + * - 로그인된 사용자의 사용자 정보 조회: GET /api/v1/users/info/me (user-service) + */ 'use client' import { postMutiPart } from '@/components/lib/api' import FileUploadForm from '@/components/ui/fileUploadForm' @@ -130,15 +147,12 @@ const IrSetting = () => { }; return newData; }); - console.log(`Page: File data received for form index ${index}`, { fileName: selectedFile?.name, cd, id }); }; const registFile = async (analysisData: any) => { setIsLoadingResult(true); - console.log("Submitting combined analysis data to backend:", analysisData); const data = await postMutiPart('v1/inftwtAnls/savewithfile', analysisData); - console.log("Response from backend:", data); if (data) { setIsLoadingResult(false); alert("분석 데이터가 성공적으로 제출되었습니다."); @@ -151,7 +165,6 @@ const IrSetting = () => { // 침입수 분석 실행 버튼 클릭 핸들러 const handleAnalysisClick = async () => { - console.log('분석 시작'); setIsLoadingResult(true); // 로딩 상태 시작 // 기본 선택 항목들 검증 (환경청, 시도, 시군구, 하수처리장) @@ -165,19 +178,12 @@ const IrSetting = () => { return; } - console.log(uploadedFilesData); const file1 = uploadedFilesData[0]; // 오수관망도 const file2 = uploadedFilesData[1]; // 수용가-맨홀 매칭결과 const file3 = uploadedFilesData[2]; // 오수량 시간패턴 const file4 = uploadedFilesData[3]; // 유량자료 const file5 = uploadedFilesData[4]; // 수용가 상수사용량 - console.log("오수관망도 정보:", file1?.file); - console.log("수용가-맨홀 매칭결과 정보:", file2); - console.log("오수량 시간패턴 정보:", file3); - console.log("유량자료 정보:", file4); - console.log("수용가 상수사용량 정보:", file5); - // 모든 필수 파일이 선택되었는지 확인 (UploadedFileInfo 객체와 그 안의 file 객체 모두 확인) // 유량자료는 선택값 if (!file1?.file || !file2?.file || !file3?.file) { @@ -327,8 +333,6 @@ const IrSetting = () => { tbSnRcptrInfo: rcptrInfoData, // 수용가 상수사용량 (없을 수 있음) }; - console.log("통합 분석 데이터 (JSON):", jsonData); - const jsonBlob = new Blob([JSON.stringify(jsonData)], { type: 'application/json' }); diff --git a/apps/sn/app/(with-base-layout)/ii/rdii/page.tsx b/apps/sn/app/(with-base-layout)/ii/rdii/page.tsx index 8a27abb81..4fd6d947a 100644 --- a/apps/sn/app/(with-base-layout)/ii/rdii/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/rdii/page.tsx @@ -1,3 +1,21 @@ +/** + * ➡️ 경로 : I/I 분석 - RDII 분석 + * + * 📄 RDII Page + * RDII 분석 페이지 컴포넌트 + * + * - 오수관망도, 수용가-맨홀 매칭결과, 강우자료 등 파일 업로드 기능 + * - RTK계수 출처 및 RDII 기여면적 입력 기능 + * - 단위도 계수 및 초기 차단 깊이 테이블 편집 기능 + * - 엑셀 파일 데이터 파싱 및 JSON 변환 처리 + * - 분석 데이터 서버 제출 및 폼 초기화 기능 + * - 파일 확장자 및 입력 값 검증 기능 + * - 로딩 오버레이 및 에러 핸들링 지원 + * + * 🔗 사용 API + * - 침입수분석 등록 첨부파일INP 포함: POST /api/v1/inftwtAnls/savewithfile (sewerage-service) + * - 로그인된 사용자의 사용자 정보 조회: GET /api/v1/users/info/me (user-service) + */ "use client" import { postMutiPart } from '@/components/lib/api' @@ -153,14 +171,11 @@ export default function RTKForm() { }; return newData; }); - console.log(`Page: File data received for form index ${index}`, { fileName: selectedFile?.name, cd, id }); }; const registFile = async (analysisData: any) => { setIsLoadingResult(true); - console.log("Submitting combined analysis data to backend", analysisData); const data = await postMutiPart('v1/rdiiAnls/savewithfile', analysisData); - console.log("Response from backend:", data); if (data) { setIsLoadingResult(false); alert("분석 데이터가 성공적으로 제출되었습니다."); @@ -187,15 +202,10 @@ export default function RTKForm() { } const formData = form.getValues(); - console.log('uploadedFilesData', uploadedFilesData); const file1 = uploadedFilesData[0]; // 오수관망도 const file2 = uploadedFilesData[1]; // 수용가-맨홀 매칭결과 const file3 = uploadedFilesData[2]; // 강우자료 - console.log("오수관망도 정보:", file1?.file); - console.log("수용가-맨홀 매칭결과 정보:", file2); - console.log("강우자료:", file3); - // 모든 필수 파일이 선택되었는지 확인 if (!file1?.file || !file2?.file || !file3?.file) { setIsLoadingResult(false); @@ -351,8 +361,6 @@ export default function RTKForm() { tbSnRainData: rainData, // 강우자료 }; - console.log("통합 분석 데이터 (JSON):", jsonData); - const jsonBlob = new Blob([JSON.stringify(jsonData)], { type: 'application/json' }); 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 354467d9d..52685aaf8 100644 --- a/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx @@ -1,3 +1,22 @@ +/** + * ➡️ 경로 : I/I 분석 - RDII 분석결과 + * + * 📄 RDII Result Page + * RDII 분석 결과 페이지 컴포넌트 + * + * - RDII 분석 결과 조회 및 테이블 표시 + * - 페이징 및 검색 기능 (시도/시군구/하수처리시설/기간 기반) + * - 분석 결과 선택 및 엑셀 다운로드 기능 + * - 분석 결과 파일 삭제 기능 + * - 로딩 오버레이 및 에러 핸들링 지원 + * - Zustand를 통한 상태 관리 및 데이터 포맷팅 + * + * 🔗 사용 API + * - RDII분석 목록 조회: GET /api/v1/rdiiAnls (sewerage-service) + * - RDII분석결과관로 목록 조회: GET /api/v1/rdiiAnlsRslt/ppl/{rainInfwtAnlsSn} (sewerage-service) + * - RDII분석결과 삭제: DELETE /api/v1/rdiiAnlsRslt/{rainInfwtAnlsSn} (sewerage-service) + * - RDII분석 삭제: DELETE /api/v1/rdiiAnls/{rainInfwtAnlsSn} (sewerage-service) + */ 'use client' import { deleteData, getData, useCookieAuth } from '@/components/lib/api' import { UiTable, downloadExcelWithKoreanHeaders } from '@common/business_components/ui' @@ -8,7 +27,7 @@ import { z } from 'zod' import BaseLayout from '../BaseLayout' import { handleDelete } from '@/components/lib/utils' import { formatDisplayData } from '@/components/lib/utils/formatDisplayValue'; -import useStore from '../../../store/useStore'; +import useStore from '@/store/useStore'; const formSchema = z.object({ @@ -107,7 +126,6 @@ const Result = () => { setResetSelection(true); const formValues = form.getValues(); // react-hook-form에서 현재 값 가져오기 - console.log("formValues", formValues); const inftwtAnlsSearchDto = { aplcnYmFrom: formValues.aplcnYmFrom?.trim() ? formValues.aplcnYmFrom : null, @@ -118,8 +136,6 @@ const Result = () => { auth: AUTH, }; - console.log("Search DTO:", inftwtAnlsSearchDto); - const queryParams = new URLSearchParams({ page: `${curPage - 1}`, size: '10', @@ -132,7 +148,6 @@ const Result = () => { }); const queryString = queryParams.toString(); - console.log("API: ", `v1/rdiiAnls${queryString ? `?${queryString}` : ''}`); try { const data = await getData(`v1/rdiiAnls${queryString ? `?${queryString}` : ''}`); @@ -158,8 +173,6 @@ const Result = () => { setTableData(dataWithRowNumber); setTotalData(dataWithRowNumber.length); - console.log("response:", data); - console.log("response data:", dataWithRowNumber); setIsLoadingResult(false); } catch (error) { setIsLoadingResult(false); @@ -176,14 +189,12 @@ const Result = () => { const handleCellClick = (index: number | undefined, headId: string) => { if (index !== undefined && tableData[index]) { setSelectedRowData(tableData[index]); - console.log("Selected row data:", tableData[index]); } }; // Excel 다운로드 핸들러 추가 const handleExcelDownload = async () => { setIsLoadingResult(true); - console.log("Selected row data for download:", selectedRowData); if (!selectedRowData || selectedRowData.rainInfwtAnlsSn === undefined) { setIsLoadingResult(false); alert('다운로드할 데이터를 선택해주세요.'); @@ -225,7 +236,6 @@ const Result = () => { // 파일 삭제 핸들러 추가 const handleFileDelete = async () => { setIsLoadingResult(true); - console.log("Selected row data for deletion:", selectedRowData); if (!selectedRowData || selectedRowData.rainInfwtAnlsSn === undefined) { alert('삭제할 파일을 선택해주세요.'); return; @@ -238,16 +248,14 @@ const Result = () => { try { // 삭제 API 호출 - const response1 = await deleteData(`v1/rdiiAnlsRslt/${selectedRowData.rainInfwtAnlsSn}`); - const response2 = await deleteData(`v1/rdiiAnls/${selectedRowData.rainInfwtAnlsSn}`); + await deleteData(`v1/rdiiAnlsRslt/${selectedRowData.rainInfwtAnlsSn}`); + await deleteData(`v1/rdiiAnls/${selectedRowData.rainInfwtAnlsSn}`); // 첨부파일(inp파일) 삭제 API 호출 handleDelete(selectedRowData.atflCd, { handleDeleteStart: () => console.log("파일 삭제 시작"), handleDeleteSuccess: (response) => console.log("파일 삭제 성공:", response), handleDeleteError: (error) => console.error("파일 삭제 실패:", error), }); - console.log("File delete response1:", response1); - console.log("File delete response2:", response2); // 테이블 선택 상태 초기화 트리거 setResetSelection(true); 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 8df0a60a8..59ccf0b08 100644 --- a/apps/sn/app/(with-base-layout)/ii/result/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/result/page.tsx @@ -1,3 +1,22 @@ +/** + * ➡️ 경로 : I/I 분석 - 침입수 분석결과 + * + * 📄 Result Page + * 침입수 분석 결과 페이지 컴포넌트 + * + * - 침입수 분석 결과 조회 및 테이블 표시 + * - 페이징 및 검색 기능 (시도/시군구/하수처리시설/기간 기반) + * - 분석 결과 선택 및 엑셀 다운로드 기능 + * - 분석 결과 파일 삭제 기능 + * - 로딩 오버레이 및 에러 핸들링 지원 + * - Zustand를 통한 상태 관리 및 데이터 포맷팅 + * + * 🔗 사용 API + * - 침입수분석 목록 조회: GET /api/v1/inftwtAnls (sewerage-service) + * - 침입수분석결과관로 목록 조회: GET /api/v1/inftwtAnlsRslt/ppl/{inftwtAnlsSn} (sewerage-service) + * - 침입수분석결과 삭제: DELETE /api/v1/inftwtAnlsRslt/{inftwtAnlsSn} (sewerage-service) + * - 침입수분석 삭제: DELETE /api/v1/inftwtAnls/{inftwtAnlsSn} (sewerage-service) + */ 'use client' import { deleteData, getData, useCookieAuth } from '@/components/lib/api' import { UiTable, downloadExcelWithKoreanHeaders } from '@common/business_components/ui' @@ -101,7 +120,6 @@ const Result = () => { setIsLoadingResult(true); setResetSelection(true); const formValues = form.getValues(); // react-hook-form에서 현재 값 가져오기 - console.log("formValues", formValues); let inftwtAnlsSearchDto = { "aplcnYmFrom": formValues.aplcnYmFrom && formValues.aplcnYmFrom !== '' ? formValues.aplcnYmFrom : null, @@ -112,8 +130,6 @@ const Result = () => { "auth": AUTH, }; - console.log("Search DTO:", inftwtAnlsSearchDto); - const queryParams = new URLSearchParams({ page: `${curPage - 1}`, size: '10', @@ -125,11 +141,8 @@ const Result = () => { } }); const queryString = queryParams.toString(); - - console.log("API: ", `v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); try { const data = await getData(`v1/inftwtAnls${queryString ? `?${queryString}` : ''}`); - console.log("API response:", data); // 🎯 각 아이템을 개별적으로 포맷팅하면서 일련번호 추가 const dataWithRowNumber = (data.content || []).map((item: any, index: number) => { @@ -153,8 +166,6 @@ const Result = () => { setTableData(dataWithRowNumber); setTotalData(data?.totalElements || 0); // totalElements가 없을 경우 0으로 설정 - console.log("response:", data); - console.log("response data:", dataWithRowNumber); setIsLoadingResult(false); } catch (error) { setIsLoadingResult(false); @@ -171,14 +182,12 @@ const Result = () => { const handleCellClick = (index: number | undefined, headId: string) => { if (index !== undefined && tableData[index]) { setSelectedRowData(tableData[index]); - console.log("Selected row data:", tableData[index]); } }; // Excel 다운로드 핸들러 추가 const handleExcelDownload = async () => { setIsLoadingResult(true); - console.log("Selected row data for download:", selectedRowData); if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) { setIsLoadingResult(false); alert('다운로드할 데이터를 선택해주세요.'); @@ -220,7 +229,6 @@ const Result = () => { // 파일 삭제 핸들러 추가 const handleFileDelete = async () => { setIsLoadingResult(true); - console.log("Selected row data for deletion:", selectedRowData); if (!selectedRowData || selectedRowData.inftwtAnlsSn === undefined) { setIsLoadingResult(false); alert('삭제할 파일을 선택해주세요.'); @@ -234,17 +242,14 @@ const Result = () => { try { // // 삭제 API 호출 - console.log("Deleting analysis result with inftwtAnlsSn:", selectedRowData.inftwtAnlsSn); - const response1 = await deleteData(`v1/inftwtAnlsRslt/${selectedRowData.inftwtAnlsSn}`); - const response2 = await deleteData(`v1/inftwtAnls/${selectedRowData.inftwtAnlsSn}`); + await deleteData(`v1/inftwtAnlsRslt/${selectedRowData.inftwtAnlsSn}`); + await deleteData(`v1/inftwtAnls/${selectedRowData.inftwtAnlsSn}`); // 첨부파일(inp파일) 삭제 API 호출 handleDelete(selectedRowData.atflCd, { handleDeleteStart: () => console.log("파일 삭제 시작"), handleDeleteSuccess: (response) => console.log("파일 삭제 성공:", response), handleDeleteError: (error) => console.error("파일 삭제 실패:", error), }); - console.log("File delete response1:", response1); - console.log("File delete response2:", response2); // 테이블 선택 상태 초기화 트리거 setResetSelection(true); diff --git a/apps/sn/app/(with-base-layout)/layout.tsx b/apps/sn/app/(with-base-layout)/layout.tsx index 229415e53..228db9a79 100644 --- a/apps/sn/app/(with-base-layout)/layout.tsx +++ b/apps/sn/app/(with-base-layout)/layout.tsx @@ -1,3 +1,16 @@ +/** + * ➡️ 경로 : I/I분석, 운영정보 모든 페이지 + * + * 📄 With Base Layout + * Next.js App Router (app/) 기반 분석 페이지 기본 레이아웃 컴포넌트 + * + * - 메뉴 클릭 이벤트 처리 및 라우팅 + * - 현재 메뉴 정보 Zustand를 통한 상태 관리 + * - 시도/시군구/사업 구분/사업 유형 데이터 초기 로드 + * - BaseLayout을 통한 공통 레이아웃 적용 + * - QueryClient를 통한 데이터 캐싱 및 관리 + * - 경로 변경 시 메뉴 정보 동기화 + */ "use client"; import React, { useEffect} from 'react'; diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx index f16178003..b6cc5d249 100644 --- a/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx +++ b/apps/sn/app/(with-base-layout)/oper/floodPre/headMakeFloodPre.tsx @@ -1,3 +1,13 @@ +/** + * 📄 HeadMakeFloodPre Component + * 침수예방 테이블 헤더 생성 컴포넌트 + * + * - 테이블 상단 헤더 생성 및 렌더링 + * - 하위 헤더 목록 기반 동적 헤더 구성 + * - rowspan 및 colspan을 통한 테이블 구조 조정 + * - 가시성 필터링 및 조건부 렌더링 지원 + * - 상위 헤더와 하위 헤더의 계층적 표시 + */ import { TableHead, TableRow } from "@common/components/ui"; diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx index 0058b47d1..c064319a6 100644 --- a/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx +++ b/apps/sn/app/(with-base-layout)/oper/floodPre/inputTableBody.tsx @@ -1,3 +1,14 @@ +/** + * 📄 InputTableBody Component + * 침수예방 입력 테이블 바디 컴포넌트 + * + * - 숫자 입력 및 콤마 포맷팅 기능 + * - mergeCell을 통한 셀 병합 처리 + * - 편집 가능/불가능 상태 관리 + * - 소계/총합계 행 스타일링 및 표시 + * - 입력 값 검증 및 변경 핸들링 + * - 빈 데이터 상태 처리 + */ import type { TableUpperProps } from "./headMakeFloodPre"; import { Input, TableCell, TableRow } from "@common/components/ui"; @@ -81,7 +92,6 @@ export const InputTableBody = ( return ( {headList.map((head, headIndex) => { - // console.log('head, head.id', head, head.id); const isTextColumn = head.id === "__EMPTY_3"; const textAlignClass = isTextColumn ? "text-center" diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/page.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/page.tsx index 08ac017be..3b547cf09 100644 --- a/apps/sn/app/(with-base-layout)/oper/floodPre/page.tsx +++ b/apps/sn/app/(with-base-layout)/oper/floodPre/page.tsx @@ -1,3 +1,21 @@ +/** + * ➡️ 경로 : 운영정보 - 도시침수예방사업 + * + * 📄 FloodPre Page + * 침수예방 사업 정보 등록 및 조회 페이지 컴포넌트 + * + * - 사업 정보 등록 현황 조회 및 테이블 표시 + * - 페이징 및 검색 기능 (등록기간/등록자/파일명 기반) + * - 파일 업로드 및 등록 기능 + * - 파일 다운로드 및 삭제 기능 + * - 엑셀 데이터 테이블 모달 표시 + * - 로딩 오버레이 및 에러 핸들링 지원 + * + * 🔗 사용 API + * - 도시침수예방사업 목록 조회: GET /api/v1/sbmrgPrevnt (sewerage-service) + * - 도시침수예방사업 등록: POST /api/v1/sbmrgPrevnt (sewerage-service) + * - 첨부파일 삭제및 Soft Delete 삭제: DELETE /api/v1/atfl/attachments/{atflId} (attach-service) + */ 'use client' import { deleteData, postData, useCookieAuth } from '@/components/lib/api' import { searchData } from '@/components/lib/common/apiHelpers' @@ -133,7 +151,6 @@ const Page = () => { sbmrgPrevntBizNm: fileName, rgtr: tokenManager.getToken(AUTH_USER_ID) || null } - console.log('request DTO', json); const data = await postData('v1/sbmrgPrevnt', json) if (data) { alert('파일이 등록되었습니다.'); diff --git a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx index a4c7939c8..ad8fcf72f 100644 --- a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx +++ b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx @@ -1,11 +1,25 @@ +/** + * 📄 Table Modal + * 침수예방 엑셀 데이터 테이블 모달 컴포넌트 + * + * - 엑셀 파일 다운로드 및 특정 시트 파싱 기능 + * - 탭 기반 테이블 표시 (관리SHEET, 운영관리현황 점검결과) + * - 데이터 필터링 및 빈 행 제거 처리 + * - 로딩 오버레이 및 에러 핸들링 지원 + * - XLSX 라이브러리를 통한 엑셀 데이터 변환 + * - 테이블 헤더 및 데이터 동적 생성 + * + * 🔗 사용 API + * - 첨부파일 다운로드(파일ID): GET /attach-service/api/v1/download/{atflId} (attach-service) + */ 'use client' import { useState, useEffect } from 'react' import LoadingOverlay from '@/components/ui/LoadingBar' import { UITab, UiTable } from '@common/business_components/ui' -import { Table, TableBody, TableHeader } from "@common/components/ui"; import * as XLSX from 'xlsx'; -import { HeadMakeFloodPre } from './headMakeFloodPre'; -import { InputTableBody } from './inputTableBody'; +// import { Table, TableBody, TableHeader } from "@common/components/ui"; +// import { HeadMakeFloodPre } from './headMakeFloodPre'; +// import { InputTableBody } from './inputTableBody'; const TABS = [ { val: "management", text: "관리SHEET" }, @@ -71,15 +85,12 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { })); setManagementTableHeader(filteredManagementHeader); - console.log('managementTableHeader', filteredManagementHeader); const managementData = Array.isArray(jsonDataBySheet['관리SHEET']) ? jsonDataBySheet['관리SHEET'].slice(8) : []; - // console.log('변환 후:', excelToManagementData(managementData)); const filteredManagementData = filterEmptyRows(managementData); setManagementTableData(filteredManagementData); - console.log('managementTableData', filteredManagementData); // 운영관리현황 점검결과 const resultHeader = jsonDataBySheet['운영관리현황 점검결과']?.[2] || []; @@ -96,14 +107,12 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { mergeCell: false }); setResultTableHeader(dynamicResultHeader); - console.log('resultTableHeader', dynamicResultHeader); const resultData = Array.isArray(jsonDataBySheet['운영관리현황 점검결과']) ? jsonDataBySheet['운영관리현황 점검결과'].slice(3) : []; const filteredResultData = filterEmptyRows(resultData); setResultTableData(filteredResultData); - console.log('resultTableData', filteredResultData); } catch (error) { console.error('파일 처리 중 오류 발생:', error); alert('파일 처리 중 오류가 발생했습니다.'); @@ -174,7 +183,6 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { if (sheetName) { const sheet = wb.Sheets[sheetName]; if (sheet) { - console.log(`Found sheet: "${sheetName}"`); const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false }); result[targetSheetName] = jsonData; } diff --git a/apps/sn/app/(with-base-layout)/oper/index.ts b/apps/sn/app/(with-base-layout)/oper/index.ts index b94e5a600..b04f724bc 100644 --- a/apps/sn/app/(with-base-layout)/oper/index.ts +++ b/apps/sn/app/(with-base-layout)/oper/index.ts @@ -1,3 +1,14 @@ +/** + * 📄 Oper Index Configuration + * 운영 관련 테이블 헤더 설정 파일 + * + * - 침수예방 및 노후 하수관로 테이블 헤더 정의 + * - 일련번호, 파일명, 년도, 분기, 등록 일자, 등록자 필드 포함 + * - 테이블 컴포넌트에서 재사용 가능한 헤더 구조 제공 + * - 데이터 표시 및 정렬을 위한 표준화된 헤더 포맷 + * - 운영 관리 페이지에서 공통으로 사용되는 헤더 리스트 + * - 동적 테이블 렌더링을 위한 ID와 타이틀 매핑 + */ export const tableHeadlist = [ { id: 'rowNumber', title: '일련번호' }, { id: 'sbmrgPrevntBizNm', title: '파일명' }, diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts b/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts index 516302720..4efaf4fe9 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/headList.ts @@ -1,3 +1,14 @@ +/** + * 📄 HeadList Configuration + * 오래된 하수관로 테이블 헤더 및 노드 설정 파일 + * + * - 테이블 헤더 및 노드 구조 정의 (oldPpTable2, oldPpTable6) + * - Zod 스키마를 통한 타입 검증 및 안전성 보장 + * - rowspan 및 colspan을 통한 복잡한 테이블 구조 지원 + * - 가시성 및 계층적 헤더 구성 (상위/하위 헤더) + * - 연도별 사업비 및 물량 데이터 헤더 관리 + * - 검토자 및 사업 정보 필드 포함 + */ import { z } from "zod"; export const oldPpHeadListType = z.array( diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx index 8fc09b5f4..93151a938 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx @@ -1,3 +1,21 @@ +/** + * ➡️ 경로 : 운영정보 - 노후 하수관로 정비사업 + * + * 📄 OldPp Page + * 노후 하수관로 정비사업 추진현황 페이지 컴포넌트 + * + * - 사업 정보 등록 현황 조회 및 테이블 표시 + * - 페이징 및 검색 기능 (등록기간/등록자/파일명 기반) + * - 파일 업로드 및 등록 기능 + * - 파일 다운로드 및 삭제 기능 + * - 엑셀 데이터 테이블 모달 표시 + * - 로딩 오버레이 및 에러 핸들링 지원 + * + * 🔗 사용 API + * - 노후관로정비사업 목록 조회: GET /api/v1/dcrpPpl (sewerage-service) + * - 노후관로정비사업 목록 등록: POST /api/v1/dcrpPpl (sewerage-service) + * - 첨부파일 삭제및 Soft Delete 삭제: DELETE /api/v1/atfl/attachments/{atflId} (attach-service) + */ 'use client' import { deleteData, postData, useCookieAuth } from '@/components/lib/api' import { searchData } from '@/components/lib/common/apiHelpers' diff --git a/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx index 169ae0895..dece4c4f8 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx @@ -1,3 +1,17 @@ +/** + * 📄 Table Modal + * 노후 하수관로 엑셀 데이터 테이블 모달 컴포넌트 + * + * - 엑셀 파일 다운로드 및 특정 시트 파싱 기능 + * - 탭 기반 테이블 표시 (row data, 정밀조사, 정비사업 등) + * - 데이터 필터링 및 빈 행 제거 처리 + * - 로딩 오버레이 및 에러 핸들링 지원 + * - XLSX 라이브러리를 통한 엑셀 데이터 변환 + * - 테이블 헤더 및 데이터 동적 생성 + * + * 🔗 사용 API + * - 첨부파일 다운로드(파일ID): GET /attach-service/api/v1/download/{atflId} (attach-service) + */ 'use client' import { useState, useEffect } from 'react' import LoadingOverlay from '@/components/ui/LoadingBar' diff --git a/apps/sn/app/(with-base-layout)/selectionValidation.tsx b/apps/sn/app/(with-base-layout)/selectionValidation.tsx index e5cdb77ad..ce80bdd67 100644 --- a/apps/sn/app/(with-base-layout)/selectionValidation.tsx +++ b/apps/sn/app/(with-base-layout)/selectionValidation.tsx @@ -1,7 +1,14 @@ /** + * 📄 Selection Validation Utility * 선택 항목 검증 유틸리티 + * + * - 선택 항목 검증 함수 (단일 및 다중 선택 지원) + * - 검증 결과 타입 정의 및 에러 메시지 생성 + * - 자주 사용되는 선택 항목 상수 제공 + * - 선택 항목 검증 전 로직 구현 + * - 사용자 친화적인 에러 메시지 출력 + * - 다양한 선택 타입 지원 (환경청, 시도, 시군구 등) */ - export interface ApiSelectOption { text: string; val: string; diff --git a/apps/sn/app/api/proxy/[...url]/route.ts b/apps/sn/app/api/proxy/[...url]/route.ts index 791562e27..cf6447b1a 100644 --- a/apps/sn/app/api/proxy/[...url]/route.ts +++ b/apps/sn/app/api/proxy/[...url]/route.ts @@ -1,3 +1,14 @@ +/** + * 📄 Proxy Route + * API 프록시 라우트 + * + * - 서버 API로의 요청 프록시 처리 + * - 쿠키 기반 인증 토큰 및 리프레시 토큰 관리 + * - POST 및 PUT 요청 핸들링 + * - 사용자 인증 정보 검증 및 응답 처리 + * - 에러 핸들링 및 상태 코드 반환 + * - 사이트 ID 및 헤더 설정 + */ import { cookies } from "next/headers"; import { NextResponse } from "next/server"; diff --git a/apps/sn/app/components/lib/api/attachment/attachment-interface.tsx b/apps/sn/app/components/lib/api/attachment/attachment-interface.tsx index 351e76fcb..abcc751d6 100644 --- a/apps/sn/app/components/lib/api/attachment/attachment-interface.tsx +++ b/apps/sn/app/components/lib/api/attachment/attachment-interface.tsx @@ -1,3 +1,14 @@ +/** + * 📄 Attachment Interface + * 첨부 파일 관련 인터페이스 정의 파일 + * + * - 첨부 파일 목록 및 상세 정보 타입 정의 + * - 페이지네이션 및 정렬 설정 인터페이스 제공 + * - 첨부 파일 검색 및 필터링 파라미터 타입 지정 + * - 첨부 파일 서비스 메소드 인터페이스 정의 + * - Axios 응답 타입을 활용한 타입 안전성 보장 + * - 첨부 파일 CRUD 작업을 위한 표준화된 타입 구조 + */ import type { AxiosResponse } from "axios"; interface SortConfig { diff --git a/apps/sn/app/components/lib/api/attachment/attachment-service.tsx b/apps/sn/app/components/lib/api/attachment/attachment-service.tsx index ee3fb6cd9..40e3ea639 100644 --- a/apps/sn/app/components/lib/api/attachment/attachment-service.tsx +++ b/apps/sn/app/components/lib/api/attachment/attachment-service.tsx @@ -1,3 +1,18 @@ +/** + * 📄 Attachment Service + * 첨부 파일 서비스 클래스 + * + * - 첨부 파일 목록 조회 및 페이지네이션 지원 + * - 첨부 파일 상세 정보 조회 기능 + * - 첨부 파일 삭제 기능 + * - Axios 기반 HTTP 요청 처리 + * - 타입 안전성 보장을 위한 인터페이스 활용 + * - 첨부 파일 CRUD 작업을 위한 표준화된 서비스 메소드 + * + * 🔗 사용 API + * - 첨부 파일 조회: GET /attach-service/api/v1/atfl/attachments (attach-service) + * - 첨부 파일 삭제: DELETE /attach-service/api/v1/atfl/attachments/atflCd (attach-service) + */ import type { AxiosResponse } from "axios"; import type { Attachment, diff --git a/apps/sn/app/components/lib/api/index.ts b/apps/sn/app/components/lib/api/index.ts index 4ffab546b..e94c602c1 100644 --- a/apps/sn/app/components/lib/api/index.ts +++ b/apps/sn/app/components/lib/api/index.ts @@ -1,3 +1,14 @@ +/** + * 📄 API Utility + * API 호출 유틸리티 파일 + * + * - 다양한 HTTP 메소드의 API 호출 함수 (GET, POST, PUT, DELETE) + * - 쿠키 기반 인증 토큰 관리 및 사용자 조회 + * - 특정 서비스 (DC, CMS, GeoServer) 호출 지원 + * - Axios 및 Fetch 기반 HTTP 요청 처리 + * - 타입 안전성 보장을 위한 인터페이스 활용 + * - 에러 핸들링 및 응답 처리 표준화 + */ import { useEffect, useState } from "react"; import axios from 'axios'; diff --git a/apps/sn/app/components/lib/common/apiHelpers.ts b/apps/sn/app/components/lib/common/apiHelpers.ts index 4963516f7..8f9abbf08 100644 --- a/apps/sn/app/components/lib/common/apiHelpers.ts +++ b/apps/sn/app/components/lib/common/apiHelpers.ts @@ -1,3 +1,17 @@ +/** + * 📄 API Helpers + * 공통 코드 cs-service API 호출 유틸리티 + * + * - 검색 데이터 조회 및 파라미터 처리 + * - 상위 코드로 하위 코드 조회 기능 + * - URL 파라미터 생성 및 필터링 + * - 데이터 페이징 및 총 개수 반환 + * - Axios 기반 HTTP 요청 처리 + * - 타입 안전성 보장을 위한 제네릭 활용 + * + * 🔗 사용 API + * - 하위코드페이지 캐시 목록 조회: GET /api/v1/code/cache/{upCd} (cms-service) + */ import { getData } from "../api"; export const searchData = async>(url: string, paramObj: T) => { diff --git a/apps/sn/app/components/lib/utils/date.ts b/apps/sn/app/components/lib/utils/date.ts index 30bea45a0..f6e7e55cd 100644 --- a/apps/sn/app/components/lib/utils/date.ts +++ b/apps/sn/app/components/lib/utils/date.ts @@ -1,3 +1,14 @@ +/** + * 📄 Date Utility + * 날짜 관련 유틸리티 파일 + * + * - 날짜 포맷팅 및 유효성 검사 함수 + * - 년도 및 분기 옵션 생성 기능 + * - 날짜 문자열 변환 및 포맷팅 + * - SelectBox 옵션으로의 날짜 변환 + * - 8자리 또는 6자리 날짜 형식 지원 + * - Date 객체 기반 날짜 조작 및 검증 + */ export const formatDate = (date: Date): string => { if (!date) return ''; const year = date.getFullYear(); diff --git a/apps/sn/app/components/lib/utils/excelToJson.ts b/apps/sn/app/components/lib/utils/excelToJson.ts index b760dae13..597d1e1d0 100644 --- a/apps/sn/app/components/lib/utils/excelToJson.ts +++ b/apps/sn/app/components/lib/utils/excelToJson.ts @@ -1,3 +1,14 @@ +/** + * 📄 Excel to JSON Utility + * 엑셀 데이터 JSON 변환 유틸리티 + * + * - 엑셀 파일 데이터 파싱 및 JSON 변환 기능 + * - 날짜 및 시간 포맷팅 및 유효성 검사 + * - Zod 스키마를 통한 데이터 타입 검증 및 안전성 보장 + * - 수용가-맨홀 매칭결과, 시간패턴, 유량자료 등 데이터 변환 + * - 강우자료 및 수용가 물사용량 데이터 처리 + * - 다양한 날짜 형식(M/D/YYYY, YYYY-MM-DD 등) 지원 + */ export const TEST_UUID = '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e' import { z } from "zod"; diff --git a/apps/sn/app/components/lib/utils/fileDeleteUtil.tsx b/apps/sn/app/components/lib/utils/fileDeleteUtil.tsx index 4cadd12e8..768c3ef9c 100644 --- a/apps/sn/app/components/lib/utils/fileDeleteUtil.tsx +++ b/apps/sn/app/components/lib/utils/fileDeleteUtil.tsx @@ -1,3 +1,17 @@ +/** + * 📄 File Delete Utility + * 파일 삭제 유틸리티 + * + * - 첨부 파일 삭제 기능 (단일 파일 지원) + * - 쿠키 기반 인증 토큰 관리 및 사용자 조회 + * - Axios 기반 HTTP 요청 처리 + * - 타입 안전성 보장을 위한 인터페이스 활용 + * - 에러 핸들링 및 응답 처리 표준화 + * - 파일 삭제 진행 상태 콜백 지원 + * + * 🔗 사용 API + * - 첨부파일 삭제및 Soft Delete 삭제(첨부파일코드로 삭제): DELETE /api/v1/atfl/attachments/atflCd/{atflCd} (attach-service) + */ import { getCookie } from "@/shared/lib"; import { ENDPOINT } from "../api/attachment/attachment-service"; @@ -40,7 +54,6 @@ export const handleDelete = async ( } options?.handleDeleteSuccess?.(response); - console.log("파일 삭제 완료:", atflCd); } catch (error) { const deleteError = error instanceof Error @@ -95,7 +108,6 @@ export const handleDelete = async ( // } // options?.handleDeleteSuccess?.(new Response()); -// console.log("모든 파일 삭제 완료:", atflCds); // } catch (error) { // const deleteError = error instanceof Error diff --git a/apps/sn/app/components/lib/utils/fileDownload.ts b/apps/sn/app/components/lib/utils/fileDownload.ts index 047847256..855488692 100644 --- a/apps/sn/app/components/lib/utils/fileDownload.ts +++ b/apps/sn/app/components/lib/utils/fileDownload.ts @@ -1,3 +1,14 @@ +/** + * 📄 File Download Utility + * 파일 다운로드 유틸리티 + * + * - API를 통한 파일 다운로드 처리 + * - Blob 데이터를 임시 링크로 연결하여 다운로드 + * - 파일명 지정 및 메모리 해제 기능 + * - 에러 핸들링 및 사용자 친화적인 오류 메시지 + * - 다양한 파일 타입 지원 (엑셀, PDF 등) + * - Fetch 기반 HTTP 요청 처리 + */ export const handleDownload = async (api: string, fileNm: string) => { try { diff --git a/apps/sn/app/components/lib/utils/fileUploadUtil.tsx b/apps/sn/app/components/lib/utils/fileUploadUtil.tsx index 3bfb35f00..fdbab1560 100644 --- a/apps/sn/app/components/lib/utils/fileUploadUtil.tsx +++ b/apps/sn/app/components/lib/utils/fileUploadUtil.tsx @@ -1,3 +1,14 @@ +/** + * 📄 File Upload Utility + * 파일 업로드 유틸리티 + * + * - TUS 프로토콜을 통한 파일 업로드 처리 + * - 쿠키 기반 인증 토큰 관리 및 사용자 조회 + * - Axios 기반 HTTP 요청 처리 + * - 업로드 진행률 및 성공/실패 콜백 지원 + * - 파일 메타데이터 설정 및 헤더 추가 + * - 대용량 파일 청크 업로드 지원 + */ import { Upload, type HttpResponse } from "tus-js-client"; import { getCookie, setCookie } from "@/shared/lib"; import { ENDPOINT } from "../api/attachment/attachment-service"; diff --git a/apps/sn/app/components/lib/utils/formatDisplayValue.tsx b/apps/sn/app/components/lib/utils/formatDisplayValue.tsx index 55cdc278f..d6a564467 100644 --- a/apps/sn/app/components/lib/utils/formatDisplayValue.tsx +++ b/apps/sn/app/components/lib/utils/formatDisplayValue.tsx @@ -1,3 +1,15 @@ +/** + * 📄 Format Display Value Utility + * 데이터 표시 포맷팅 유틸리티 + * + * - 날짜 포맷팅 (yyyymmdd -> yyyy년 m월 d일) + * - 연월 포맷팅 (yyyymm -> yyyy년 m월) + * - 날짜시간 포맷팅 (yyyy-mm-dd hh:mm:ss -> yyyy년 m월 d일 hh:mm) + * - 숫자 포맷팅 (천 단위 구분자 및 소수점 처리) + * - 데이터 객체 전체 포맷팅 및 단일 값 포맷팅 지원 + * - null/undefined 값 처리 및 기본값 설정 + * - 다양한 필드 타입별 조건부 포맷팅 로직 + */ import { dateFields, numberFields, yearMonthFields, dateTimeFields } from "../../../(map-layout)/map/components/common/table"; import { formatDateString } from "./date"; diff --git a/apps/sn/app/components/ui/EditableFormTable.tsx b/apps/sn/app/components/ui/EditableFormTable.tsx index 89fd8f005..315c4e978 100644 --- a/apps/sn/app/components/ui/EditableFormTable.tsx +++ b/apps/sn/app/components/ui/EditableFormTable.tsx @@ -1,3 +1,14 @@ +/** + * 📄 EditableFormTable Component + * 편집 가능한 폼 테이블 컴포넌트 + * + * - react-hook-form과 통합된 편집 가능한 테이블 렌더링 + * - 필드 배열 기반 동적 행 생성 및 관리 + * - 숫자 입력 검증 (소수점 및 유효 문자 제한) + * - 테이블 헤더 및 셀 스타일링 및 정렬 지원 + * - Controller를 통한 폼 상태 관리 및 유효성 검사 + * - 커스텀 입력 필드 클래스 및 속성 지원 + */ import { Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components/ui"; import type { UseFormReturn, FieldArrayWithId, Path, FieldValues } from "react-hook-form"; import { Controller } from "react-hook-form"; diff --git a/apps/sn/app/components/ui/LoadingBar/index.tsx b/apps/sn/app/components/ui/LoadingBar/index.tsx index 37991d1d2..12251365b 100644 --- a/apps/sn/app/components/ui/LoadingBar/index.tsx +++ b/apps/sn/app/components/ui/LoadingBar/index.tsx @@ -1,3 +1,13 @@ +/** + * 📄 Loading Overlay Component + * 로딩 오버레이 컴포넌트 + * + * - 로딩 상태에 따른 오버레이 표시 및 숨김 + * - 반투명 배경을 통한 사용자 인터랙션 차단 + * - 애니메이션 로딩 아이콘 표시 + * - 고정 위치 및 z-index를 통한 최상위 레이어 배치 + * - 조건부 렌더링을 통한 성능 최적화 + */ import React from 'react'; import { LoadingWithAnimation } from '@common/components/ui/loading'; diff --git a/apps/sn/app/components/ui/YearRangeSelectBox.tsx b/apps/sn/app/components/ui/YearRangeSelectBox.tsx index 8450a2b60..35f1dd6a9 100644 --- a/apps/sn/app/components/ui/YearRangeSelectBox.tsx +++ b/apps/sn/app/components/ui/YearRangeSelectBox.tsx @@ -1,3 +1,14 @@ +/** + * 📄 YearRangeSelectBox Component + * 년도 범위 선택 컴포넌트 + * + * - 시작년도와 종료년도 선택 기능 + * - 년도 범위 유효성 검증 (시작년도 <= 종료년도) + * - 동적 옵션 생성 및 필터링 + * - 전체 선택 옵션 제공 + * - 커스텀 라벨 및 스타일링 지원 + * - 콜백 함수를 통한 선택 값 전달 + */ import React from "react"; import { SelectBox } from '@common/business_components/ui' diff --git a/apps/sn/app/components/ui/contentLayout.tsx b/apps/sn/app/components/ui/contentLayout.tsx index de4406efd..bd13fc2c3 100644 --- a/apps/sn/app/components/ui/contentLayout.tsx +++ b/apps/sn/app/components/ui/contentLayout.tsx @@ -1,3 +1,14 @@ +/** + * 📄 Content Layout Component + * 콘텐츠 레이아웃 컴포넌트 + * + * - 제목 표시 및 콘텐츠 영역 제공 + * - 로딩 오버레이를 통한 사용자 피드백 + * - 공통 레이아웃 구조 적용 (MainDiv, Title, ContentsDiv) + * - 조건부 로딩 상태 렌더링 + * - 클래스명 기반 스타일링 지원 + * - 재사용 가능한 레이아웃 컴포넌트 + */ import { ContentsDiv, MainDiv, Title } from '@common/business_components/ui' import React, { type ReactNode } from 'react' import LoadingOverlay from './LoadingBar' diff --git a/apps/sn/app/components/ui/ctpvSggPrcsFcltSelectBox.tsx b/apps/sn/app/components/ui/ctpvSggPrcsFcltSelectBox.tsx index 1a800fb35..25eb0a9d1 100644 --- a/apps/sn/app/components/ui/ctpvSggPrcsFcltSelectBox.tsx +++ b/apps/sn/app/components/ui/ctpvSggPrcsFcltSelectBox.tsx @@ -1,3 +1,17 @@ +/** + * 📄 CtpvSggPrcsFcltSelectBox Component + * 시도/시군구/하수처리시설 선택 컴포넌트 + * + * - 시도 선택 및 시군구 필터링 기능 + * - 시군구 선택 시 하수처리시설 목록 조회 + * - 선택 값 변경 시 콜백 함수 호출 + * - 로딩 상태 관리 및 에러 핸들링 + * - Zustand를 통한 시도/시군구 데이터 관리 + * - CQL 필터를 통한 시설물 검색 조건 설정 + * + * 🔗 사용 API + * - 관망도 시설물 목록 조회: GET /api/v1/fclts (sewerage-service) + */ import React, { useState, useEffect } from "react"; import { SelectBox } from '@common/business_components/ui' import { Label } from '@common/components'; @@ -63,7 +77,6 @@ export function CtpvSggPrcsFcltSelectBox({ const fetchData = async () => { if (!sggName) { - console.log("BaseLayout: Skipping fetchData because sigungu.val is:", sggName); setPrcsFcltOptions([]); if (setIsLoading) setIsLoading(false); return; @@ -82,12 +95,8 @@ export function CtpvSggPrcsFcltSelectBox({ if (sggName) cqlFiltersFacility.push(`sgg_nm ILIKE '%${sggName}%'`); if (cqlFiltersFacility.length > 0) queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and ')); - console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`); - const facilityRes = await getData(`v1/fclts?${queryParamsFacility.toString()}`); - console.log('facilityRes.data', facilityRes.data); - const facilities = (facilityRes.data || []) .map((item: any) => ({ text: item.swtrmtFcltNm, diff --git a/apps/sn/app/components/ui/fileUploadForm.tsx b/apps/sn/app/components/ui/fileUploadForm.tsx index 1272488a1..fc1e2b779 100644 --- a/apps/sn/app/components/ui/fileUploadForm.tsx +++ b/apps/sn/app/components/ui/fileUploadForm.tsx @@ -1,3 +1,14 @@ +/** + * 📄 File Upload Form Component + * 파일 업로드 폼 컴포넌트 + * + * - 파일 선택 및 업로드 기능 + * - 년도 및 분기 선택 옵션 제공 + * - 파일 등록 및 콜백 처리 + * - 업로드 진행률 및 성공/실패 핸들링 + * - 파일 형식 검증 및 미리보기 지원 + * - TUS 프로토콜을 통한 대용량 파일 업로드 + */ "use client" import { FileUploader } from "@common/components"; import { Button } from '@common/components/ui'; @@ -42,7 +53,6 @@ const FileUploadForm = ({ const [selectedQuarter, setSelectedQuarter] = useState(quater[0]?.val || ''); function registFile() { - console.log(files?.[0]?.name) if (!currentFile) { alert('파일을 선택해주세요.'); return; @@ -88,7 +98,6 @@ const FileUploadForm = ({ } const { atflCd: newAtflCd, atflId: newAtflId } = JSON.parse(fileInfo) ?? {}; - console.log(`FileUploadForm (idx: ${fileIdx ?? 'N/A'}) - Upload completed:`, newAtflCd, newAtflId); // 내부 상태도 업데이트 (다른 용도로 사용할 수 있음) setInternalAtflCd(newAtflCd); diff --git a/apps/sn/app/components/ui/formSection.tsx b/apps/sn/app/components/ui/formSection.tsx index 4f33fbbe5..f1b7542a0 100644 --- a/apps/sn/app/components/ui/formSection.tsx +++ b/apps/sn/app/components/ui/formSection.tsx @@ -1,3 +1,14 @@ +/** + * 📄 Form Section Component + * 폼 섹션 컴포넌트 + * + * - 폼 필드 렌더링 및 제목 표시 + * - 필수 입력 필드 표시 (별표 표시) + * - FormField를 통한 폼 상태 관리 + * - 그리드 레이아웃을 통한 정렬 및 배치 + * - 재사용 가능한 폼 섹션 구조 제공 + * - react-hook-form 통합 지원 + */ import { FormField } from '@common/business_components/ui' import React, { type ReactElement } from 'react' diff --git a/apps/sn/app/components/ui/modal.tsx b/apps/sn/app/components/ui/modal.tsx index afc2b5c9a..dce0ee2b5 100644 --- a/apps/sn/app/components/ui/modal.tsx +++ b/apps/sn/app/components/ui/modal.tsx @@ -1,3 +1,14 @@ +/** + * 📄 Modal Component + * 모달 컴포넌트 + * + * - 모달 열기/닫기 상태 관리 + * - 제목 및 내용 표시 + * - 저장 및 닫기 버튼 지원 + * - 반응형 크기 조정 (최대/최소 너비 및 높이) + * - 오버레이 및 z-index를 통한 최상위 레이어 배치 + * - 접근성 지원 (aria-describedby) + */ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogOverlay } from '@common/components/ui' import React from 'react' diff --git a/apps/sn/app/components/ui/operFileUploadForm.tsx b/apps/sn/app/components/ui/operFileUploadForm.tsx index 3c37673d2..d4c2e5eeb 100644 --- a/apps/sn/app/components/ui/operFileUploadForm.tsx +++ b/apps/sn/app/components/ui/operFileUploadForm.tsx @@ -1,3 +1,14 @@ +/** + * 📄 Oper File Upload Form Component + * 운영 파일 업로드 폼 컴포넌트 + * + * - 년도 및 분기 선택 기능 + * - 파일 업로드 및 등록 처리 + * - 년도 변경 시 분기 옵션 동적 업데이트 + * - 파일 형식 검증 및 미리보기 지원 + * - 콜백 함수를 통한 업로드 결과 전달 + * - TUS 프로토콜을 통한 대용량 파일 업로드 + */ "use client" import { SelectBox } from '@common/business_components/ui'; import React, { useState, useEffect } from 'react' @@ -5,9 +16,6 @@ import FileUploadForm from './fileUploadForm'; import { yearOptions, getQuarterOptions } from '@/components/lib/utils'; const operFileUploadForm = ({ title, onSubmit }: { title: string, onSubmit: (files: string, year: string, quarter: string, code: string, id: string) => void }) => { - const [atflCd, setAtflCd] = useState(null); - const [atflId, setAtflId] = useState(null); - const [selectedYear, setSelectedYear] = useState(yearOptions[0]?.val || ''); const [quaterOptions, setQuaterOptions] = useState(() => getQuarterOptions(selectedYear)); const [selectedQuarter, setSelectedQuarter] = useState(quaterOptions[0]?.val || ''); diff --git a/apps/sn/app/components/ui/toast.tsx b/apps/sn/app/components/ui/toast.tsx index b1e021651..06054a4aa 100644 --- a/apps/sn/app/components/ui/toast.tsx +++ b/apps/sn/app/components/ui/toast.tsx @@ -1,3 +1,14 @@ +/** + * 📄 Toast Component + * 토스트 알림 컴포넌트 + * + * - 확인/취소 버튼이 있는 토스트 표시 기능 + * - 메시지 표시 토스트 기능 + * - react-hot-toast 라이브러리 기반 구현 + * - 중복 토스트 방지 및 수동 닫기 지원 + * - 커스텀 스타일링 및 애니메이션 적용 + * - 사용자 상호작용을 위한 버튼 이벤트 핸들링 + */ import { Button } from "@common/components/ui"; import toast from "react-hot-toast"; diff --git a/apps/sn/app/components/ui/verticalTable.tsx b/apps/sn/app/components/ui/verticalTable.tsx index 14c61bec8..1ed617243 100644 --- a/apps/sn/app/components/ui/verticalTable.tsx +++ b/apps/sn/app/components/ui/verticalTable.tsx @@ -1,3 +1,14 @@ +/** + * 📄 VerticalTable Component + * 세로 방향 테이블 컴포넌트 + * + * - 세로 방향 테이블 렌더링 및 데이터 표시 + * - 편집 가능 필드 지원 (select, input 타입) + * - 입력 값 검증 및 에러 메시지 표시 + * - 페이지네이션 및 데이터 페이징 처리 + * - 두 개의 테이블 동시 표시 지원 + * - 폼 데이터 변경 콜백 및 저장 기능 + */ import UiPageNations from "@common/business_components/ui/table/uiPageNations"; import { Table, TableBody, TableCell, TableRow, Button } from "@common/components"; import { useEffect, useState } from "react"; diff --git a/apps/sn/app/layout.tsx b/apps/sn/app/layout.tsx index 066d9646b..9363fe185 100644 --- a/apps/sn/app/layout.tsx +++ b/apps/sn/app/layout.tsx @@ -1,3 +1,16 @@ +/** + * ➡️ 경로 : 모든 페이지 + * + * 📄 Root Layout + * 루트 레이아웃 컴포넌트 + * + * - 메타데이터 설정 (title, description, keywords, OpenGraph) + * - App 컴포넌트 렌더링 및 전체 앱 구조 정의 + * - SEO 및 소셜 미디어 공유를 위한 메타 태그 관리 + * - 디지털 하수관로 시스템의 기본 레이아웃 제공 + * - Next.js Metadata API를 통한 동적 메타데이터 설정 + * - 앱 전체의 공통 스타일 및 스크립트 적용 + */ import type { Metadata } from "next"; import { App } from "@/app"; diff --git a/apps/sn/app/page.tsx b/apps/sn/app/page.tsx index 27dd1de1c..d3e22baee 100644 --- a/apps/sn/app/page.tsx +++ b/apps/sn/app/page.tsx @@ -1,3 +1,19 @@ +/** + * ➡️ 경로 : 루트 (/) + * + * 📄 Home Page + * 홈 페이지 컴포넌트 + * + * - 쿠키 기반 인증 토큰 검증 및 자동 로그인 처리 + * - 로그인 성공 시 지도 페이지로 리다이렉트 + * - 기존 토큰 존재 시 바로 지도 페이지 이동 + * - 로그인 실패 시 에러 로깅 및 처리 + * - 사용자 세션 관리 및 초기 라우팅 제어 + * - Next.js useRouter를 통한 클라이언트 사이드 라우팅 + * + * 🔗 사용 API + * - 로그인: POST /api/v1/auth/login (user-service) + */ "use client"; import { LoginApi } from "@/entities/auth"; import { useEffect } from "react"; diff --git a/apps/sn/app/store/index.ts b/apps/sn/app/store/index.ts index 28afbd570..91577ae1a 100644 --- a/apps/sn/app/store/index.ts +++ b/apps/sn/app/store/index.ts @@ -1,3 +1,20 @@ +/** + * 📄 Store Index + * Zustand 스토어 인덱스 파일 + * + * - 시도 데이터 조회 및 커스텀 정렬 기능 + * - 시군구 데이터 조회 및 알파벳 정렬 기능 + * - 사업 구분 코드 조회 및 상태 관리 + * - 사업 유형 코드 조회 및 필터링 기능 + * - GeoServer WFS를 통한 지리 데이터 가져오기 + * - CMS 서비스를 통한 코드 데이터 가져오기 + * + * 🔗 사용 API + * - 시도 데이터 조회: GET /geoserver/hasudo/ows (GeoServer) + * - 시군구 데이터 조회: GET /geoserver/hasudo/ows (GeoServer) + * - 사업 구분 코드 조회: GET /api/v1/code/cache/BIZSECD (cms-service) + * - 사업 유형 코드 조회: GET /api/v1/code/cache/BIZTYCD (cms-service) + */ import { getCmsData } from "@/components/lib/api"; @@ -9,6 +26,7 @@ export type BIZ_CD_TYPE = { prntLwpoCd: null }; +// 시도 데이터 조회 export const fetchCtpv = async (set: (state: any) => void) => { const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_ctpv&outputFormat=application/json&propertyName=mctpv_korn_nm,mctpv_cd`; const res = await fetch(url).then(res => res.json()); @@ -55,11 +73,10 @@ export const fetchCtpv = async (set: (state: any) => void) => { // 둘 다 커스텀 순서에 없으면 기본 알파벳 순서 return a.text.localeCompare(b.text, 'ko'); }); - - console.log('시도 데이터', list); set({ ctpv: list }); }; +// 시군구 데이터 조회 export const fetchSgg = async (set: (state: any) => void) => { const url = `/geoserver/hasudo/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=hasudo:tb_ms_sgg&outputFormat=application/json&propertyName=sgg_cd,sgg_korn_nm`; const res = await fetch(url).then(res => res.json()); diff --git a/apps/sn/app/store/useReportTabStore.ts b/apps/sn/app/store/useReportTabStore.ts index 05f43ebc5..bb2cd875a 100644 --- a/apps/sn/app/store/useReportTabStore.ts +++ b/apps/sn/app/store/useReportTabStore.ts @@ -1,4 +1,19 @@ -import useReportTab, { type Folder, type ReportDataFile } from '../(map-layout)/map/searchModal/useReportTab'; +/** + * 📄 useReportTabStore + * 보고서 탭 Zustand 스토어 + * + * - 보고서 탭 모달 열기/닫기 상태 관리 + * - 보고서 파일 목록 및 트리 구조 상태 관리 + * - DC 트리 데이터 조회 및 캐싱 기능 + * - DC 파일 목록 조회 및 상태 업데이트 + * - Zustand를 통한 중앙 집중식 상태 관리 + * - 데이터 변경 감지 및 불필요한 재렌더링 방지 + * + * 🔗 사용 API + * - DC 트리 데이터 조회: GET /dc-service//api/v1/dc/clsf + * - DC 파일 목록 조회: GET /dc-service//api/v1/dc/file + */ +import { type Folder, type ReportDataFile } from '../(map-layout)/map/searchModal/useReportTab'; import { create } from 'zustand'; import { getDcData } from '@/components/lib/api'; @@ -30,7 +45,16 @@ export const useReportTabStore = create((set, get) => ({ } }, fetchDcFiles: async (clsfSystmNm: string) => { - const { getDcFiles } = useReportTab(); + const getDcFiles = async (clsfSystmSn: string): Promise => { + if (!clsfSystmSn) { + console.error("clsfSystmSn is required to get files."); + return []; + } + const queryString = 'clsfSystmSn=' + clsfSystmSn; + const result = await getDcData(`/api/v1/dc/file${queryString ? `?${queryString}` : ''}`); + return result; + }; + const { dcFiles } = get(); try { const result = await getDcFiles(clsfSystmNm); diff --git a/apps/sn/app/store/useSearchModalStore.ts b/apps/sn/app/store/useSearchModalStore.ts index acb93969d..4d8702a08 100644 --- a/apps/sn/app/store/useSearchModalStore.ts +++ b/apps/sn/app/store/useSearchModalStore.ts @@ -1,5 +1,16 @@ +/** + * 📄 useSearchModalStore + * 검색 모달 Zustand 스토어 + * + * - 검색 모달 열기/닫기 및 탭 전환 상태 관리 + * - 기본정보 및 운영정보 탭 데이터 필터링 및 조회 + * - 테이블 데이터 및 페이지네이션 상태 관리 + * - 지역(시도/시군구) 및 날짜 범위 필터링 기능 + * - 로딩 상태 및 리셋 플래그 관리 + * - Zustand를 통한 중앙 집중식 상태 관리 + * - 데이터 변경 감지 및 불필요한 재렌더링 방지 + */ import { create } from "zustand"; -import { type SelectDataType } from "@common/business_components"; // 날짜 조합 함수 diff --git a/apps/sn/app/store/useStore.ts b/apps/sn/app/store/useStore.ts index 678090ed7..2e8932005 100644 --- a/apps/sn/app/store/useStore.ts +++ b/apps/sn/app/store/useStore.ts @@ -1,3 +1,14 @@ +/** + * 📄 useStore + * SN 앱 Zustand 스토어 + * + * - 시도 데이터 상태 관리 및 조회 기능 + * - 시군구 데이터 상태 관리 및 조회 기능 + * - 사업 구분 코드 상태 관리 및 조회 기능 + * - 사업 유형 코드 상태 관리 및 조회 기능 + * - Zustand를 통한 중앙 집중식 상태 관리 + * - 데이터 변경 감지 및 불필요한 재렌더링 방지 + */ import { create } from "zustand"; import { fetchCtpv, fetchSgg, fetchBIZ_SE_CD, fetchBIZ_TY_CD } from "./index"; import { type SelectDataType } from "@common/business_components"; diff --git a/apps/sn/middleware.ts b/apps/sn/middleware.ts index 8a1a2e716..cd5d27e05 100644 --- a/apps/sn/middleware.ts +++ b/apps/sn/middleware.ts @@ -50,6 +50,14 @@ export function middleware(req: NextRequest) { return rewriteWith(newUrl, req, true); } + if (pathname.startsWith("/api/proxy")) { + const decodedQuery = toDecodedQueryString(searchParams); + const newUrl = `${SERVER_API_URL}${pathname}${decodedQuery ? `?${decodedQuery}` : "" + }`; + console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`); + return rewriteWith(newUrl, req, true); + } + if (pathname.startsWith("/geoserver")) { let queryParams = searchParams.toString(); const typename = searchParams.get("TYPENAME"); @@ -96,17 +104,31 @@ export function middleware(req: NextRequest) { || pathname.startsWith("/cms-service") || pathname.startsWith("/user-service") ) { - const decodedQuery = toDecodedQueryString(searchParams); - const newUrl = `${SERVER_API_URL}${pathname}${decodedQuery ? `?${decodedQuery}` : ""}`; - console.log(`[Middleware] Rewriting from '${pathname}' path to: ${newUrl}`); - return rewriteWith(newUrl, req, true); - } + const requestHeaders = new Headers(req.headers); + const token = req.cookies.get(CLAIM_NAME)?.value; + const userId = req.cookies.get(AUTH_USER_ID)?.value; + const newUrl = `${SERVER_API_URL}${pathname}`; + if (token) requestHeaders.set(CLAIM_NAME, token); + if (userId) requestHeaders.set(AUTH_USER_ID, userId); + + console.log(`[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`); + return NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); + } + if (pathname.startsWith("/dc-service")) { - const decodedQuery = toDecodedQueryString(searchParams); - const newUrl = `${DC_URL}${pathname}${decodedQuery ? `?${decodedQuery}` : ""}`; - console.log(`[Middleware] Rewriting from '${pathname}' path to: ${newUrl}`); - return rewriteWith(newUrl, req, true); + const requestHeaders = new Headers(req.headers); + const decodedParams = Array.from(searchParams.entries()) + .map(([key, value]) => `${key}=${decodeURIComponent(value)}`) + .join("&"); + + const newUrl = `${DC_URL}${pathname}${decodedParams ? `?${decodedParams}` : ""}`; + console.log(`[Middleware] Rewriting from '/dc-service' path to: ${newUrl}`); + return NextResponse.rewrite(new URL(newUrl), { + headers: requestHeaders, + }); } if (pathname.startsWith("/sewerage-service")) { diff --git a/apps/sn/src/entities/auth/lib/auth-wrapper.tsx b/apps/sn/src/entities/auth/lib/auth-wrapper.tsx index f0710e249..5d93b000d 100644 --- a/apps/sn/src/entities/auth/lib/auth-wrapper.tsx +++ b/apps/sn/src/entities/auth/lib/auth-wrapper.tsx @@ -9,7 +9,8 @@ import { ENDPOINT, AUTH_USER_ID } from "@/shared/config"; import { getCookie } from "@/shared/lib"; import { LoginApi } from "../api/login-service"; -const CLAIM_NAME = process.env.NEXT_PUBLIC_CLAIM_NAME || "Authorization"; + +const LOGIN_PAGE_URL = process.env.NEXT_PUBLIC_DEV_CM_LOGIN_PAGE_URL || "http://localhost:3000/auth/login"; // 로그인 페이지 URL const AuthWrapper = ({ children }: { children: React.ReactNode }) => { const router = useRouter(); @@ -40,7 +41,10 @@ const AuthWrapper = ({ children }: { children: React.ReactNode }) => { } catch (refreshError) { console.error("Token refresh failed:", refreshError); setUserInfo(null); - router.push("/"); + // router.push("/"); // 개발시 홈으로 돌아가기 + + window.location.href = LOGIN_PAGE_URL; // 세션 만료 시 CM 로그인 페이지로 리다이렉트 + // router.push는 같은 Next.js 앱 내에서만 작동하므로 다른 앱으로 이동할 때는 window.location.href 사용 } } })(); diff --git a/apps/sn/src/shared/store/data-store.ts b/apps/sn/src/shared/store/data-store.ts index fec870234..4414ac69f 100644 --- a/apps/sn/src/shared/store/data-store.ts +++ b/apps/sn/src/shared/store/data-store.ts @@ -36,7 +36,6 @@ export const defaultInitState: DataState = { const fetchCtpvSggData = async (set: (state: any) => void) => { try { const ctpvData = await getCmsData('/api/v1/code/cache/ADSTDSTRCD'); - console.log("CTPV Data:", ctpvData); const ctpvList: Option[] = ctpvData .filter((item: any) => typeof item.lwpoCd === 'string' && item.lwpoCd.length === 2) .map((feature: any) => ({ diff --git a/apps/wr/app/(popUp-layout)/mapFeaturePopup/page.tsx b/apps/wr/app/(popUp-layout)/mapFeaturePopup/page.tsx index 680f637d4..90b1cbc8a 100644 --- a/apps/wr/app/(popUp-layout)/mapFeaturePopup/page.tsx +++ b/apps/wr/app/(popUp-layout)/mapFeaturePopup/page.tsx @@ -55,12 +55,14 @@ export default function MapFeaturePopup() { useEffect(() => { + console.log(' layerNm ' , layerNm) if (isFeatureCd && layerNm) { if (layerNm === "tb_wr_bdst_ruse_fclt") { setIsDetail(isFeatureCd); } else if (layerNm === "tb_il_swage_prcs_fclt") { pbnMapDetaile(isFeatureCd).then((res) => { - setIsDetail(res); + console.log('res', res) + setIsDetail([res]); }); } else if (layerNm === "tb_wr_rnwtr_utztn_fclt") { rainMapDetile(isFeatureCd).then((res) => { diff --git a/apps/wr/app/(with-layout)/matMng/coMng/drgtSttn/page.tsx b/apps/wr/app/(with-layout)/drgtSttn/page.tsx similarity index 100% rename from apps/wr/app/(with-layout)/matMng/coMng/drgtSttn/page.tsx rename to apps/wr/app/(with-layout)/drgtSttn/page.tsx diff --git a/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx index a3ed891a8..472b8222f 100644 --- a/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx +++ b/apps/wr/app/(with-layout)/matMng/coMat/coMatRvw/page.tsx @@ -40,6 +40,14 @@ import { useForm, useWatch } from "react-hook-form"; import toast, { Toaster } from "react-hot-toast"; import { z } from "zod"; + +/** + * 📄 CoMatRvw 수요매칭 검토 + * Next.js App Router (app/) 기반 페이지 컴포넌트 예시 + * + * - 대민에서 신청하는 수요처의 수요등록 정보를 운영담당자가 수요 매칭 검토를 진행한다. + * - 전체적으로 form을 만들어서 form안에 데이터를 넣고 api를 호출하여 저장한다. + */ export default function CoMatRvw() { const { auth, code, coRvw, coMatRvwInit, coMatRvwSearch, coMatRvwInqua } = useWrStore((state) => state); @@ -70,6 +78,9 @@ export default function CoMatRvw() { ); const [selectionVersion, setSelectionVersion] = useState(0); + + + //수요 매칭 검색 const getSearch = ( startYear: number, endYear: number, @@ -117,7 +128,7 @@ export default function CoMatRvw() { if (coMatRvwRes && coMatRvwRes.length > 0) { const data = coMatRvwRes?.map((item) => { let flag = ""; - + // 수요처의 매칭된 정보를 확인할수 있도록 한다. flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg || undefined); return { @@ -227,9 +238,9 @@ export default function CoMatRvw() { - +
-
+
- @@ -137,7 +139,9 @@ export default function Home() { total={htdflResCount} headName={"시설물 목록"} cellClick={(val, headId) => { - cellClick(val || undefined, headId); + if (val !== null && val !== undefined) { + cellClick(val, headId); + } }} onPageChange={setPageNation} > diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 219d5cfbe..d5d0e9b33 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -12,7 +12,7 @@ import { import { Button } from "@common/components"; import { useWrStore } from "../../../../store"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import ListDiv from "@common/business_components/ui/list_div"; import { confirmToast, tableData } from "@/components/lib/func/commom"; import type { @@ -35,6 +35,17 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createDefaultPbnstItem } from "./utilsZod"; import { useTranslation } from "react-i18next"; +/** + * 재이용시설 등록 - 하수재이용 시설등록 + * + * - layout.tsx에 의해 공통 레이아웃이 적용됨 + * - with-layout 적용 + * - 하수처리시설에 하수재이용 시설을 등록 한다. + * - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다 + * indexMng: 시설정보 + * indexBiz: 차수별 정보 + * 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다. + * */ export default function PublicReuseFaciltyInsert() { const { @@ -47,21 +58,22 @@ export default function PublicReuseFaciltyInsert() { pbnstRuseFcltUpdate, pubHasuSearch, pbnstRuseBizUpdate, + getLaeSeCdCheck, } = useWrStore((state) => state); const { t } = useTranslation("base"); const { pubFacHeadList, pbnstHasuResCount, pbnstHasuRes, pbnstRes } = pbnst; - const { regAuthrtYn, mdfcnAuthrtYn } = auth; + const { regAuthrtYn, mdfcnAuthrtYn, laeSeCd } = auth; const [, setCurrentTab] = useState("mng"); const [isRuseReg, setIsRuseReg] = useState<{ isModal: boolean; }>({ isModal: false }); - const [resetPage, isResetPage] = useState(false); const [indexMng, setIndexMng] = useState(0); const [indexBiz, setIndexBiz] = useState(0); const [searchTxt, setSearchTxt] = useState(); const [bdstTable, setbdstTable] = useState(); const [selectRow, setSelectRow] = useState(); + const [resetPage, isResetPage] = useState(false); const [pageNation, setPageNation] = useState(1); const form = useForm<{ @@ -83,17 +95,20 @@ export default function PublicReuseFaciltyInsert() { }); const formWatch = form.watch("items"); + const useInitRef = useRef(false); + useEffect(() => { - if (!pbnst.isInit) { - pubHasuInit("1", "41"); + getLaeSeCdCheck(); + useInitRef.current = true; + }, []); + + useEffect(() => { + if (useInitRef.current == true && laeSeCd !== undefined) { + pubHasuInit("1", laeSeCd); } - }, [pbnst.isInit, pubHasuInit]); + }, [useInitRef.current, laeSeCd]); const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => { - // if (!isDirty) { - // toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시 - // return; - // } const data = writeRgtrAndMdfr(valuse.items); let bizs = [] as fcBizType[]; data.forEach((fclt) => { @@ -133,7 +148,7 @@ export default function PublicReuseFaciltyInsert() { message += "하수재이용 시설 사업 "; } toast.error(message + "오류 입니다 "); - pubHasuInit("1", "41"); + pubHasuInit("1", laeSeCd); } }); }; @@ -220,7 +235,7 @@ export default function PublicReuseFaciltyInsert() { setSelectRow(pbnstHasuRes?.[val]); if (selectRow) { pbnstRegClick(selectRow); - setIndexMng(0) + setIndexMng(0); } else { console.error("선택된 행이 없습니다."); } @@ -237,7 +252,6 @@ export default function PublicReuseFaciltyInsert() { }, [indexMng]); useEffect(() => { - if (pbnst.pbnstRes && pbnst.pbnstRes?.length > 0) { form.reset({ items: pbnst.pbnstRes }); } else { @@ -263,7 +277,7 @@ export default function PublicReuseFaciltyInsert() { }, [pbnstRes, append, selectRow]); useEffect(() => { - pubHasuInit(String(pageNation), "41"); + pubHasuInit(String(pageNation), laeSeCd); isResetPage(false); }, [pageNation, pubHasuInit]); @@ -289,13 +303,12 @@ export default function PublicReuseFaciltyInsert() { size={"sm"} onClick={() => { if (searchTxt && searchTxt?.length > 0) { - pubHasuSearch(String(pageNation), "41", searchTxt); + pubHasuSearch(String(pageNation), laeSeCd, searchTxt); } else { - pubHasuInit(String(pageNation), "41"); + pubHasuInit(String(pageNation), laeSeCd); } isResetPage(true); }} - > 조회 @@ -428,7 +441,7 @@ export default function PublicReuseFaciltyInsert() { } }} onInvalid={onInvalid} - newIndexMng={(formWatch?.length -1)} + newIndexMng={formWatch?.length - 1} > } bodyClass="w-[68vw] max-w-none h-[90vh]" diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/page.tsx index f2d121887..f3567210d 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltReg/rainReg/page.tsx @@ -1,7 +1,10 @@ "use client"; import { useWrStore } from "@/app/store"; -import { rainRegSize, type customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { formatArchArea, tableData } from "@/components/lib/func/commom"; +import { + rainRegSize, + type customRainBdst, +} from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { formatArchArea, tableData } from "@/components/lib/func/commom"; import RainRegForm from "@/components/ui/form/fcltReg/rainReg/rainRegForm"; import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; import { @@ -16,33 +19,54 @@ import { } from "@common/business_components"; import ListDiv from "@common/business_components/ui/list_div"; import { Button } from "@common/components"; -import { useEffect, useState } from "react"; -import { Toaster } from "react-hot-toast"; +import { useEffect, useRef, useState } from "react"; +import { Toaster } from "react-hot-toast"; + + +/** + * 밧물이용시설 등록 + * 재이용시설 등록 - 빗물시설 등록 + * - layout.tsx에 의해 공통 레이아웃이 적용됨 + * - with-layout 적용 + * 왼쪽 테이블에는 건축물 리스트 / 오른쪽 폼에는 건축물에 해당하는 빗물이용시설 데이터가 보인다. + * 신규 등록 버튼을 눌러 건축물 정보부터 입력한다. + * + * */ export default function Home() { - const { auth, rain, code, initRain, rainSearch, getRainData } = useWrStore( - (state) => { - return state; - } - ); - - const { regAuthrtYn, mdfcnAuthrtYn } = auth; - + const { + auth, + rain, + code, + initRain, + rainSearch, + getRainData, + getLaeSeCdCheck, + } = useWrStore((state) => { + return state; + }); + const { regAuthrtYn, mdfcnAuthrtYn, laeSeCd } = auth; const { rainRes, rainResCount } = rain; + const useInitRef = useRef(false); const [rainForm, setRainForm] = useState(); const [issNewReg, setIsNewReg] = useState(false); const [pageNation, setPageNation] = useState(1); const [bdstTable, setbdstTable] = useState(); const [searchTxt, setSearchTxt] = useState(); + useEffect(() => { + getLaeSeCdCheck(); + useInitRef.current = true; + }, []); + useEffect(() => { setIsNewReg(false); - if (!rain.isInit) { - initRain("41"); + if (useInitRef.current == true && laeSeCd !== undefined) { + initRain(laeSeCd); } - }, [rain.isInit, initRain]); + }, [useInitRef.current, laeSeCd]); useEffect(() => { if (code.sggCd.length > 0) { @@ -51,9 +75,9 @@ export default function Home() { (item: customRainBdst) => { return { ...item, - archArea: formatArchArea(item?.archArea,1), + archArea: formatArchArea(item?.archArea, 1), bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N", - frstArchPrmsnDt:item?.frstArchPrmsnDt||'확인불가' + frstArchPrmsnDt: item?.frstArchPrmsnDt || "확인불가", }; } ); @@ -71,7 +95,7 @@ export default function Home() { }; useEffect(() => { - getRainData(pageNation, "41"); + getRainData(pageNation, laeSeCd); }, [pageNation]); return ( @@ -95,7 +119,7 @@ export default function Home() { className="" size={"sm"} onClick={() => { - rainSearch(searchTxt || "", 1, "41"); + rainSearch(searchTxt || "", 1, laeSeCd); //rainSearch(searchTxt || "", pageNation, "41"); }} > @@ -105,7 +129,7 @@ export default function Home() { size={"sm"} className="" onClick={() => { - setIsNewReg(!issNewReg); + setIsNewReg(!issNewReg); }} disabled={regAuthrtYn === "N"} > @@ -138,7 +162,7 @@ export default function Home() {
- + state - ); - const { regAuthrtYn, mdfcnAuthrtYn } = auth; + const { + auth, + code, + rswt, + initRswt, + rswtBdstSearch, + getRswtBdstData, + getLaeSeCdCheck, + } = useWrStore((state) => state); + const { regAuthrtYn, mdfcnAuthrtYn, laeSeCd } = auth; const [rswtForm, setRswtForm] = useState(); const [searchTxt, setSearchTxt] = useState(); @@ -32,14 +50,22 @@ export default function Home() { const [selectVal, setSelect] = useState(); const [bdstTable, setbdstTable] = useState(); const { rswtRes, rswtResCount } = rswt; + const useInitRef = useRef(false); + useEffect(() => { - if (!rswt.isInit) { - initRswt("41"); + getLaeSeCdCheck(); + useInitRef.current = true; + }, []); + + useEffect(() => { + setIsNewReg(false); + if (useInitRef.current == true && laeSeCd !== undefined) { + initRswt(laeSeCd); } - }, [rswt.isInit, initRswt]); + }, [useInitRef.current, laeSeCd]); + useEffect(() => { if (code.sggCd.length > 0) { - if (rswtRes?.length > 0) { const rswtData = tableData(rswtRes, { code })?.map( (item: customRswtBdst) => { @@ -63,7 +89,6 @@ export default function Home() { } } // }, [code, rswtRes, selectVal]); - }, [code, rswtRes]); useEffect(() => { if (rswtRes && rswtRes.length > 0) { @@ -79,11 +104,10 @@ export default function Home() { setSelect(val); } } - }; useEffect(() => { - getRswtBdstData(pageNation, "41"); + getRswtBdstData(pageNation,laeSeCd); }, [pageNation]); return ( @@ -107,7 +131,7 @@ export default function Home() { size={"sm"} className="" onClick={() => { - rswtBdstSearch(searchTxt || "", pageNation, "41"); + rswtBdstSearch(searchTxt || "", pageNation,laeSeCd); }} > 조회 diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index bbab4d9ce..ca0b04f31 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -24,6 +24,15 @@ import { useCallback, useEffect, useRef, useState } from "react"; import toast, { Toaster } from "react-hot-toast"; import { useTranslation } from "react-i18next"; +/** + * 하수재이용 시설 현황 + * 재이용시설 현황 - 하수재이용시설 현황 + * - layout.tsx에 의해 공통 레이아웃이 적용됨 + * - with-layout 적용 + * 하수처리시설. 하수재이용시설 , 하수재이용시설 실적에 대한 정보를 확인한다. + * 모달 : 테이블의 헤더를 원하는대로 조절해서 볼수 있다. + * 클릭시 해당 재이용ㅇ + * */ export default function PbnstSttn() { const { code, @@ -32,7 +41,7 @@ export default function PbnstSttn() { pbnSttnInit, getPbnStnDetail, getFlcts, - resetPbnstDetail + resetPbnstDetail, } = useWrStore((state) => state); const { pbnstSttnRes, fclts, pbnstSttnResCount } = pbnstSttn; @@ -50,7 +59,7 @@ export default function PbnstSttn() { }>({ isModal: false, data: {} as customPbnst }); const isDownloadTriggered = useRef(false); const [pbnRuseNm, setPbnRuseNm] = useState(""); - const { t } = useTranslation('base'); + const { t } = useTranslation("base"); const excelClick = useCallback(() => { isDownloadTriggered.current = true; pbnstSttnSearch( @@ -79,7 +88,6 @@ export default function PbnstSttn() { } }, [pbnstSttn.isInit]); useEffect(() => { - pbnSttnInit("1", "15", ref.current, searchYear, fclts); }, [fclts]); @@ -91,7 +99,6 @@ export default function PbnstSttn() { } }, [pbnstSttnRes]); - useEffect(() => { if (!isDownloadTriggered.current) { return; @@ -105,12 +112,11 @@ export default function PbnstSttn() { 3 ); } else { - toast.error(t('excelDownErrMsg')); + toast.error(t("excelDownErrMsg")); } isDownloadTriggered.current = false; }, [pbnstSttn.excelList]); - useEffect(() => { if (pbnstSttn.pbnstDetail.pbnstRuseFcltId) setPbnDetaileData({ @@ -211,7 +217,6 @@ export default function PbnstSttn() { ); setIsReset(false); }} - resetPageNo={isReset} > diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx index 8055a2917..f5ec6e8c8 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rainSttn/page.tsx @@ -92,7 +92,7 @@ export default function RainSttn() { useEffect(() => { if (!rainSttn.isInit) { - rainSttnInit(false, 1, rainSttnSize, "0", fcltNm, code.cityCd, code.sggCd); + rainSttnInit(false, 1, rainSttnSize, "0", fcltNm, code as unknown as Record); } }, [rainSttn.isInit, rainSttnInit]); @@ -146,8 +146,7 @@ export default function RainSttn() { rainSttnSize, String(getConValue()), fcltNm, - code.cityCd, - code.sggCd + code as unknown as Record ); isResetPage(false); }, [pageNation]); @@ -177,8 +176,7 @@ export default function RainSttn() { rainSttnResCount, String(getConValue()), fcltNm, - code.cityCd, - code.sggCd + code as unknown as Record ); }, [ rainSttnSearch, @@ -237,8 +235,7 @@ export default function RainSttn() { rainSttnSize, String(getConValue()), fcltNm, - code.cityCd, - code.sggCd + code as unknown as Record ); isResetPage(true); }} diff --git a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx index b917a4105..7cb81d209 100644 --- a/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx +++ b/apps/wr/app/(with-layout)/ruseFcltMng/fcltSttn/rswtSttn/page.tsx @@ -34,6 +34,7 @@ export default function RswtSttn() { const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore( (state) => state ); + const [pageNation, setPageNation] = useState(1); const { rswtSttnRes, rswtSttnResCount } = rswtSttn; @@ -83,8 +84,8 @@ export default function RswtSttn() { }; useEffect(() => { - if (!rswtSttn.isInit) { - rswtSttnInit(false, 1, rswtSttnSize, "0", fcltNm, code.cityCd, code.sggCd); + if (!rswtSttn.isInit&&code) { + rswtSttnInit(false, 1, rswtSttnSize, code.userSiSggCd, fcltNm, code as unknown as Record); } }, [rswtSttn.isInit, rswtSttnInit]); @@ -93,6 +94,8 @@ export default function RswtSttn() { const chData = data .map((item: customRswtBdst) => { const isOrgwtKndCd = item.reuseBuilding[0]?.rswtrObj.orgwtKndCd + + return { ...item, ...item.reuseBuilding[0], @@ -101,7 +104,7 @@ export default function RswtSttn() { chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N', instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst, instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt, - archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가' + archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가', } }) .filter( @@ -131,11 +134,11 @@ export default function RswtSttn() { const excelClick = useCallback(() => { isDownloadTriggered.current = true; - rswtSttnSearch(true, 1, rswtSttnResCount, String(getConValue()), fcltNm, code.cityCd, code.sggCd); + rswtSttnSearch(true, 1, rswtSttnResCount, String(getConValue()), fcltNm, code as unknown as Record); }, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, rswtSttnResCount]); useEffect(() => { - rswtSttnSearch(false, pageNation, rswtSttnSize, String(getConValue()), fcltNm, code.cityCd, code.sggCd); + rswtSttnSearch(false, pageNation, rswtSttnSize, String(getConValue()), fcltNm, code as unknown as Record); isResetPage(false) }, [pageNation]); @@ -186,7 +189,7 @@ export default function RswtSttn() { @@ -270,7 +290,7 @@ export default function PrfmncPrfmncReg() { setIsExcelOPen({ ...isExcelOpen, isModal: true }); } }} - disabled={regAuthrtYn === 'N'} + disabled={regAuthrtYn === "N"} > 파일등록 @@ -289,7 +309,7 @@ export default function PrfmncPrfmncReg() { { - if (searchTxt && searchTxt?.length > 0) { - prfmncHasuNmSearch(page, '41', searchYear, searchTxt,prfPbnFclts) - } else { - prfmncHasuInit(page, '41', searchYear,prfPbnFclts) - } - setIsReset(false); - }} - resetPageNo={isReset} + onPageChange={(page: number) => { + if (searchTxt && searchTxt?.length > 0) { + prfmncHasuNmSearch( + page, + laeSeCd, + searchYear, + searchTxt, + prfPbnFclts + ); + } else { + prfmncHasuInit(page, laeSeCd, searchYear, prfPbnFclts); + } + setIsReset(false); + }} + resetPageNo={isReset} /> @@ -324,8 +349,13 @@ export default function PrfmncPrfmncReg() { {headMakeprfmnc(monthHeadList, [])} - - {InputTableBody(inputData ?? [], monthHeadList, setInputData, mdfcnAuthrtYn === 'N' ? false : true)} + + {InputTableBody( + inputData ?? [], + monthHeadList, + setInputData, + mdfcnAuthrtYn === "N" ? false : true + )} @@ -338,17 +368,12 @@ export default function PrfmncPrfmncReg() { { - setIsExcelOPen({ ...isExcelOpen, isModal: open }) + setIsExcelOPen({ ...isExcelOpen, isModal: open }); }} setModalExcelData={async (excelData) => { - await prfmnRegData(1, '41', - excelData, - searchYear - ,prfPbnFclts - ); + await prfmnRegData(1, laeSeCd, excelData, searchYear, prfPbnFclts); // 데이터 저장 후 UI 업데이트는 useEffect가 감지하여 처리하므로 여기서는 호출하지 않습니다. - } - } + }} > } open={isExcelOpen.isModal} diff --git a/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx b/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx index 21ca5112a..de9bc86cf 100644 --- a/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx +++ b/apps/wr/app/(with-layout)/stats/rswtStat/page.tsx @@ -27,7 +27,7 @@ export default function RswtStat() { const { t } = useTranslation('base'); useEffect(() => { - searchRswtStatList(searchYear, code.cityCd) + searchRswtStatList(searchYear, code.cityCd,code.rswtBdstType) }, [searchRswtStatList, code.cityCd]) const excelClick = () => { @@ -251,7 +251,7 @@ export default function RswtStat() { className="" size="sm" onClick={() => { - searchRswtStatList(searchYear, code.cityCd) + searchRswtStatList(searchYear, code.cityCd,code.rswtBdstType) }} > 조회 diff --git a/apps/wr/app/layout.tsx b/apps/wr/app/layout.tsx index 17945be51..f728f5de0 100644 --- a/apps/wr/app/layout.tsx +++ b/apps/wr/app/layout.tsx @@ -7,33 +7,38 @@ import { StoreProvider } from "./store"; import { LoginApi } from "@/src/entities/auth"; import { useEffect } from "react"; +const i18n = i18next.createInstance(); +i18n.init({ + lng: "ko", + fallbackLng: "ko", + resources: { + ko: { + base: koBase, + }, + }, +}); + export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { - i18next.init({ - lng: "ko", - fallbackLng: "ko", - resources: { - ko: { - base: koBase, - }, - }, - }); useEffect(() => { // 렌더 중이 아니라 클라이언트에서만 실행 + 에러 캐치 void LoginApi.login({ userId: "CLEANWATER", password: "gktneh12!@" }) + .finally(()=>{ + // getCommonUpCd() + } ) .catch((e) => { console.error("Auto login failed:", e); }); }, []); return ( - + - + {children} diff --git a/apps/wr/app/store/common/auth/index.tsx b/apps/wr/app/store/common/auth/index.tsx index 21be6e01c..5e65f3b6a 100644 --- a/apps/wr/app/store/common/auth/index.tsx +++ b/apps/wr/app/store/common/auth/index.tsx @@ -1,4 +1,5 @@ -import { getFetchWithCount } from "@/components/lib/api"; +import { fetchType, getFetchWithCount } from "@/components/lib/api"; +import { getUserInfo } from "@common/components/api"; import toast from "react-hot-toast"; export type authState = { @@ -8,6 +9,7 @@ export type authState = { regAuthrtYn: string; mdfcnAuthrtYn: string; delAuthrtYn: string; + laeSeCd: string; }; }; @@ -20,26 +22,32 @@ export const authStateExport: authState = { regAuthrtYn: "Y", mdfcnAuthrtYn: "Y", delAuthrtYn: "Y", + laeSeCd: "", }, }; export type authActions = { getMenuAuthrts: (menuCd: number) => void; + getLaeSeCdCheck: () => Promise; }; -export const authActionsExport: (set: any) => authActions = (set: any) => { +export const authActionsExport: (set: any, get: any) => authActions = ( + set: any, + get: any +) => { return { getMenuAuthrts: async (menuCd: number) => { - try{ + try { + const response = await getFetchWithCount( + fetchType.LOCAL, - const response = await getFetchWithCount( 'LOCAL', - `/cms-service/api/v1/menu-authrts/pageinfo/${menuCd}` ); set((state: authState) => { return { ...state, auth: { + ...state.auth, mngAuthrtYn: response[0].mngAuthrtYn, inqAuthrtYn: response[0].mngAuthrtYn, regAuthrtYn: response[0].mngAuthrtYn, @@ -48,12 +56,32 @@ export const authActionsExport: (set: any) => authActions = (set: any) => { }, }; }); - - }catch(e){ - - toast.error('권한 정보를 가져오는 중 오류가 발생했습니다. 관리자에게 문의하세요.'); - console.error('Error fetching menu authorities:', e); + } catch (e) { + toast.error( + "권한 정보를 가져오는 중 오류가 발생했습니다. 관리자에게 문의하세요." + ); + console.error("Error fetching menu authorities:", e); + } + }, + getLaeSeCdCheck: async () => { + try { + const current = get().auth.laeSeCd; + if (current && current !== "") { + return; + } + const infoMe = await getUserInfo(); + const isLaeSeCd = + infoMe.laeSeCd.slice(0, 2) === "G3" ? infoMe.laeSeCd.slice(2) : "0"; + set((state: authState) => ({ + ...state, + auth: { + ...state.auth, + laeSeCd: isLaeSeCd, + }, + })); + } catch (e) { + console.error("laeSeCd check error", e); } }, }; diff --git a/apps/wr/app/store/common/code/basicCode.tsx b/apps/wr/app/store/common/code/basicCode.tsx index 5fc13c16d..5f6981288 100644 --- a/apps/wr/app/store/common/code/basicCode.tsx +++ b/apps/wr/app/store/common/code/basicCode.tsx @@ -3,6 +3,7 @@ import type { SelectDataType } from "@common/business_components"; export const numSize = 12; export const txtSize = 20; +//export const lwCds: Record = {}; export const yn: SelectDataType[] = [ { val: "Y", text: "Y" }, { val: "N", text: "N" }, @@ -14,29 +15,35 @@ export const bdstFilterYn: SelectDataType[] = [ { val: "F", text: "미가동" }, ]; // 최우수(그린1)/우수(그린2), 우량(그린3), 일반(그린4), 확인불가 체크 -export const bdstGrntchClass: SelectDataType[] = [ - { val: "최우수(그린1)", text: "최우수(그린1)" }, - { val: "우수(그린2)", text: "우수(그린2)" }, - { val: "우량(그린3)", text: "우량(그린3)" }, - { val: "일반(그린4)", text: "일반(그린4)" }, - { val: "확인불가", text: "확인불가" }, -]; +//export const bdstGrntchClass: SelectDataType[] = lwCds['bdstGrntchClass']??[] + +// [ +// { val: "최우수(그린1)", text: "최우수(그린1)" }, +// { val: "우수(그린2)", text: "우수(그린2)" }, +// { val: "우량(그린3)", text: "우량(그린3)" }, +// { val: "일반(그린4)", text: "일반(그린4)" }, +// { val: "확인불가", text: "확인불가" }, +// ]; export const bdstIncenYn: SelectDataType[] = [ { val: "Y", text: "Y" }, { val: "N", text: "N" }, { val: "D", text: "확인불가" }, ]; //처리장연계/자체+연계/자체처리 -export const erctUswtrPrcsMeth: SelectDataType[] = [ - { val: "처리장연계", text: "처리장연계" }, - { val: "자체+연계", text: "자체+연계" }, - { val: "자체처리", text: "자체처리" }, -]; +//export const erctUswtrPrcsMeth: SelectDataType[] = lwCds['erctUswtrPrcsMeth']??[] -export const rusePrcsMthdCd: SelectDataType[] = [ - { val: "물리학적처리", text: "물리학적처리" }, - { val: "생물학적처리", text: "생물학적처리" }, -]; +// [ +// { val: "처리장연계", text: "처리장연계" }, +// { val: "자체+연계", text: "자체+연계" }, +// { val: "자체처리", text: "자체처리" }, +// ]; + +// export const rusePrcsMthdCd: SelectDataType[] = lwCds['rusePrcsMthdCd']??[] + +// [ +// { val: "물리학적처리", text: "물리학적처리" }, +// { val: "생물학적처리", text: "생물학적처리" }, +// ]; export const ruseSeCd: SelectDataType[] = [ { val: "신규", text: "신규" }, @@ -53,94 +60,100 @@ export const ruseBizMthdCd: SelectDataType[] = [ ]; // 공통 건축물 용도 -export const bdstUsgCd: SelectDataType[] = [ - { val: "-1", text: "확인불가" }, - { val: "1", text: "운동장" }, - { val: "2", text: "체육관" }, - { val: "3", text: "공공업무시설" }, - { val: "4", text: "공공기관의청사" }, - { val: "5", text: "아파트" }, - { val: "6", text: "연립주택" }, - { val: "7", text: "다세대주택" }, - { val: "8", text: "기숙사" }, - { val: "9", text: "초등학교" }, - { val: "10", text: "중학교" }, - { val: "11", text: "고등학교" }, - { val: "12", text: "전문대학" }, - { val: "13", text: "대학및대학교" }, - { val: "14", text: "골프장" }, - { val: "15", text: "대규모점포" }, - { val: "16", text: "기타" }, - { val: "17", text: "숙박업" }, - { val: "18", text: "목욕장업" }, - { val: "19", text: "공장" }, - { val: "20", text: "발전시설" }, - { val: "21", text: "관광단지개발사업" }, - { val: "22", text: "도시개발사업" }, - { val: "23", text: "산업단지개발사업" }, - { val: "24", text: "택지개발사업" }, - { val: "25", text: "대규모점포(대형마트)" }, - { val: "26", text: "대규모점포(전문점)" }, - { val: "27", text: "대규모점포(백화점)" }, - { val: "28", text: "대규모점포(쇼핑센터)" }, - { val: "29", text: "대규모점포(복합쇼핑몰)" }, - { val: "30", text: "물류시설" }, - { val: "31", text: "운수시설(여객자동차터미널)" }, - { val: "32", text: "운수시설(철도시설)" }, - { val: "33", text: "운수시설(공항시설)" }, - { val: "34", text: "운수시설(항만시설)" }, - { val: "35", text: "업무시설(공공업무시설)" }, - { val: "36", text: "업무시설(금융업소)" }, - { val: "37", text: "업무시설(사무소)" }, - { val: "38", text: "업무시설(결혼상담소 등 소개업소)" }, - { val: "39", text: "업무시설(출판사)" }, - { val: "40", text: "업무시설(신문사)" }, - { val: "41", text: "업무시설(오피스텔)" }, - { val: "42", text: "교정시설" }, - { val: "43", text: "방송국" }, - { val: "44", text: "전신전화국" }, - { val: "45", text: "기타" }, -]; +//export const bdstUsgCd: SelectDataType[] =lwCds?.bdstUsgCd?.concat(lwCds?.rswtBdstType??[])??[] -export const rswtBdstType: SelectDataType[] = [ - { val: "17", text: "숙박업" }, - { val: "18", text: "목욕장업" }, - { val: "19", text: "공장" }, - { val: "20", text: "발전시설" }, - { val: "21", text: "관광단지개발사업" }, - { val: "22", text: "도시개발사업" }, - { val: "23", text: "산업단지개발사업" }, - { val: "24", text: "택지개발사업" }, - { val: "25", text: "대규모점포(대형마트)" }, - { val: "26", text: "대규모점포(전문점)" }, - { val: "27", text: "대규모점포(백화점)" }, - { val: "28", text: "대규모점포(쇼핑센터)" }, - { val: "29", text: "대규모점포(복합쇼핑몰)" }, - { val: "30", text: "물류시설" }, - { val: "31", text: "운수시설(여객자동차터미널)" }, - { val: "32", text: "운수시설(철도시설)" }, - { val: "33", text: "운수시설(공항시설)" }, - { val: "34", text: "운수시설(항만시설)" }, - { val: "35", text: "업무시설(공공업무시설)" }, - { val: "36", text: "업무시설(금융업소)" }, - { val: "37", text: "업무시설(사무소)" }, - { val: "38", text: "업무시설(결혼상담소 등 소개업소)" }, - { val: "39", text: "업무시설(출판사)" }, - { val: "40", text: "업무시설(신문사)" }, - { val: "41", text: "업무시설(오피스텔)" }, - { val: "42", text: "교정시설" }, - { val: "43", text: "방송국" }, - { val: "44", text: "전신전화국" }, - { val: "45", text: "기타" }, -]; +// [ +// { val: "-1", text: "확인불가" }, +// { val: "1", text: "운동장" }, +// { val: "2", text: "체육관" }, +// { val: "3", text: "공공업무시설" }, +// { val: "4", text: "공공기관의청사" }, +// { val: "5", text: "아파트" }, +// { val: "6", text: "연립주택" }, +// { val: "7", text: "다세대주택" }, +// { val: "8", text: "기숙사" }, +// { val: "9", text: "초등학교" }, +// { val: "10", text: "중학교" }, +// { val: "11", text: "고등학교" }, +// { val: "12", text: "전문대학" }, +// { val: "13", text: "대학및대학교" }, +// { val: "14", text: "골프장" }, +// { val: "15", text: "대규모점포" }, +// { val: "16", text: "기타" }, +// { val: "17", text: "숙박업" }, +// { val: "18", text: "목욕장업" }, +// { val: "19", text: "공장" }, +// { val: "20", text: "발전시설" }, +// { val: "21", text: "관광단지개발사업" }, +// { val: "22", text: "도시개발사업" }, +// { val: "23", text: "산업단지개발사업" }, +// { val: "24", text: "택지개발사업" }, +// { val: "25", text: "대규모점포(대형마트)" }, +// { val: "26", text: "대규모점포(전문점)" }, +// { val: "27", text: "대규모점포(백화점)" }, +// { val: "28", text: "대규모점포(쇼핑센터)" }, +// { val: "29", text: "대규모점포(복합쇼핑몰)" }, +// { val: "30", text: "물류시설" }, +// { val: "31", text: "운수시설(여객자동차터미널)" }, +// { val: "32", text: "운수시설(철도시설)" }, +// { val: "33", text: "운수시설(공항시설)" }, +// { val: "34", text: "운수시설(항만시설)" }, +// { val: "35", text: "업무시설(공공업무시설)" }, +// { val: "36", text: "업무시설(금융업소)" }, +// { val: "37", text: "업무시설(사무소)" }, +// { val: "38", text: "업무시설(결혼상담소 등 소개업소)" }, +// { val: "39", text: "업무시설(출판사)" }, +// { val: "40", text: "업무시설(신문사)" }, +// { val: "41", text: "업무시설(오피스텔)" }, +// { val: "42", text: "교정시설" }, +// { val: "43", text: "방송국" }, +// { val: "44", text: "전신전화국" }, +// { val: "45", text: "기타" }, +// ]; -export const orgwtKndCd = [ - { text: "오수(변기 오수 제외)", val: "01" }, - { text: "오수", val: "02" }, - { text: "폐수", val: "03" }, - { text: "오수 및 폐수", val: "04" }, - { text: "기타", val: "05" }, -]; +// export const rswtBdstType: SelectDataType[] = lwCds?.rswtBdstType??[] +//[ +// { val: "17", text: "숙박업" }, +// { val: "18", text: "목욕장업" }, +// { val: "19", text: "공장" }, +// { val: "20", text: "발전시설" }, +// { val: "21", text: "관광단지개발사업" }, +// { val: "22", text: "도시개발사업" }, +// { val: "23", text: "산업단지개발사업" }, +// { val: "24", text: "택지개발사업" }, +// { val: "25", text: "대규모점포(대형마트)" }, +// { val: "26", text: "대규모점포(전문점)" }, +// { val: "27", text: "대규모점포(백화점)" }, +// { val: "28", text: "대규모점포(쇼핑센터)" }, +// { val: "29", text: "대규모점포(복합쇼핑몰)" }, +// { val: "30", text: "물류시설" }, +// { val: "31", text: "운수시설(여객자동차터미널)" }, +// { val: "32", text: "운수시설(철도시설)" }, +// { val: "33", text: "운수시설(공항시설)" }, +// { val: "34", text: "운수시설(항만시설)" }, +// { val: "35", text: "업무시설(공공업무시설)" }, +// { val: "36", text: "업무시설(금융업소)" }, +// { val: "37", text: "업무시설(사무소)" }, +// { val: "38", text: "업무시설(결혼상담소 등 소개업소)" }, +// { val: "39", text: "업무시설(출판사)" }, +// { val: "40", text: "업무시설(신문사)" }, +// { val: "41", text: "업무시설(오피스텔)" }, +// { val: "42", text: "교정시설" }, +// { val: "43", text: "방송국" }, +// { val: "44", text: "전신전화국" }, +// { val: "45", text: "기타" }, +// ]; + +//export const orgwtKndCd =lwCds['orgwtKndCd']??[] + + +// [ +// { text: "오수(변기 오수 제외)", val: "01" }, +// { text: "오수", val: "02" }, +// { text: "폐수", val: "03" }, +// { text: "오수 및 폐수", val: "04" }, +// { text: "기타", val: "05" }, +// ]; export const chBuCd = [ { val: "증축", text: "증축" }, @@ -148,97 +161,104 @@ export const chBuCd = [ { val: "재축", text: "재축" }, ]; -export const dmdUszCd = [ - { val: "조경용수", text: "조경용수" }, - { val: "청소화장실용수", text: "청소화장실용수" }, - { val: "농업용수", text: "농업용수" }, - { val: "공업용수", text: "공업용수" }, - { val: "친수용수", text: "친수용수" }, - { val: "기타", text: "기타" }, -]; +// export const dmdUszCd = [ +// { val: "조경용수", text: "조경용수" }, +// { val: "청소화장실용수", text: "청소화장실용수" }, +// { val: "농업용수", text: "농업용수" }, +// { val: "공업용수", text: "공업용수" }, +// { val: "친수용수", text: "친수용수" }, +// { val: "기타", text: "기타" }, +// ]; -export const ruseMngMtd = [ - { val: "자체운영", text: "자체운영" }, - { val: "공기업", text: "공기업" }, - { val: "민간(대행)", text: "민간(대행)" }, -]; -export const pplQulity = [ - { val: "도복장강관", text: "도복장강관" }, - { val: "PE관", text: "PE관" }, - { val: "스테인레스관", text: "스테인레스관" }, - { val: "덕타일주철관", text: "덕타일주철관" }, - { val: "유리섬유복합관", text: "유리섬유복합관" }, - { val: "기타", text: "기타" }, -]; -export const pplLenght = [ - { val: "D100", text: "D100" }, - { val: "D200", text: "D200" }, - { val: "D250", text: "D250" }, - { val: "D300", text: "D300" }, - { val: "D350", text: "D350" }, - { val: "D400", text: "D400" }, - { val: "D450", text: "D450" }, - { val: "D500", text: "D500" }, - { val: "D700", text: "D700" }, - { val: "D900", text: "D900" }, - { val: "D1000​", text: "D1000​" }, -]; -export const rainFcltCd = [ - { val: "10", text: "확인불가" }, - { val: "01", text: "지붕" }, - { val: "02", text: "건물옥상" }, - { val: "03", text: "골프장 연못" }, - { val: "04", text: "운동장 바닥" }, - { val: "05", text: "운동장 지붕" }, - { val: "06", text: "주차장" }, - { val: "07", text: "태양광패널" }, - { val: "08", text: "연못" }, - { val: "09", text: "기타" }, -]; +// export const ruseMngMtd = lwCds['ruseMngMtd'] +// [ +// { val: "자체운영", text: "자체운영" }, +// { val: "공기업", text: "공기업" }, +// { val: "민간(대행)", text: "민간(대행)" }, +// ]; + +// export const pplQulity = +// [ +// { val: "도복장강관", text: "도복장강관" }, +// { val: "PE관", text: "PE관" }, +// { val: "스테인레스관", text: "스테인레스관" }, +// { val: "덕타일주철관", text: "덕타일주철관" }, +// { val: "유리섬유복합관", text: "유리섬유복합관" }, +// { val: "기타", text: "기타" }, +// ]; +// export const pplLenght = [ +// { val: "D100", text: "D100" }, +// { val: "D200", text: "D200" }, +// { val: "D250", text: "D250" }, +// { val: "D300", text: "D300" }, +// { val: "D350", text: "D350" }, +// { val: "D400", text: "D400" }, +// { val: "D450", text: "D450" }, +// { val: "D500", text: "D500" }, +// { val: "D700", text: "D700" }, +// { val: "D900", text: "D900" }, +// { val: "D1000​", text: "D1000​" }, +// ]; + +// export const rainFcltCd = lwCds?.rainFcltCd??[] + + +// [ +// { val: "10", text: "확인불가" }, +// { val: "01", text: "지붕" }, +// { val: "02", text: "건물옥상" }, +// { val: "03", text: "골프장 연못" }, +// { val: "04", text: "운동장 바닥" }, +// { val: "05", text: "운동장 지붕" }, +// { val: "06", text: "주차장" }, +// { val: "07", text: "태양광패널" }, +// { val: "08", text: "연못" }, +// { val: "09", text: "기타" }, +// ]; //물리화학적처리(스크린, 응집, 침전)/생물학적처리(활성슬러지법 등)/소독(염소, UV 등)/기타 -export const rswtPrscCdMthdCd = [ - { - val: "물리화학적처리(스크린,응집,침전)", - text: "물리화학적처리(스크린,응집,침전)", - }, - { - val: "생물학적처리(활성슬러지법 등)", - text: "생물학적처리(활성슬러지법 등)", - }, - { val: "소독(염소, UV 등)", text: "소독(염소, UV 등)" }, - { val: "기타", text: "기타" }, - { val: "확인불가", text: "확인불가" }, -]; +//export const rswtPrscCdMthdCd = lwCds['rswtPrscCdMthdCd']??[] +// { +// val: "물리화학적처리(스크린,응집,침전)", +// text: "물리화학적처리(스크린,응집,침전)", +// }, +// { +// val: "생물학적처리(활성슬러지법 등)", +// text: "생물학적처리(활성슬러지법 등)", +// }, +// { val: "소독(염소, UV 등)", text: "소독(염소, UV 등)" }, +// { val: "기타", text: "기타" }, +// { val: "확인불가", text: "확인불가" }, +// ]; -export const htdPowerMthdCd= [ - { - val: "해당없음", - text: "해당없음", - }, - { - val: "석탄화력발전", - text: "석탄화력발전", - }, - { - val: "화력발전", - text: "화력발전", - }, - { - val: "수력발전", - text: "수력발전", - }, - { - val: "태양관발전", - text: "태양관발전", - }, -]; +// export const htdPowerMthdCd = [ +// { +// val: "해당없음", +// text: "해당없음", +// }, +// { +// val: "석탄화력발전", +// text: "석탄화력발전", +// }, +// { +// val: "화력발전", +// text: "화력발전", +// }, +// { +// val: "수력발전", +// text: "수력발전", +// }, +// { +// val: "태양관발전", +// text: "태양관발전", +// }, +// ]; //(공업용수/양식장/농업용수) -export const htdUtztnUsgCd= [ +export const htdUtztnUsgCd = [ { val: "공업용수", text: "공업용수", @@ -252,3 +272,171 @@ export const htdUtztnUsgCd= [ text: "농업용수", }, ]; + +export const ruseFcltSpot = [] +//(공업용수/양식장/농업용수) +export const rainRswtMng = [ + { + val: "위탁", + text: "01", + }, + { + val: "자체", + text: "02", + }, +]; + +export const rainFcltFlowRate = [ + { + val: "01", + text: "유량계", + }, + { + val: "02", + text: "수위계", + }, + { + val: "03", + text: "펌프적산전력계", + }, + { + val: "04", + text: "기타", + }, +]; +export const rainRswtUse = [ + { + val: "01", + text: "유량계", + }, + { + val: "02", + text: "수위계", + }, + { + val: "03", + text: "펌프적산전력계", + }, + { + val: "04", + text: "기타", + }, +]; + +export const sewageInFcltUse = [ + { + val: "01", + text: "세척수", + }, + { + val: "02", + text: "냉각수", + }, + { + val: "03", + text: "청소수", + }, + { + val: "04", + text: "삭수대", + }, + { + val: "05", + text: "희석용수", + }, + { + val: "06", + text: "중수도", + }, + { + val: "07", + text: "기타", + }, +]; + +export const sewageOutFclttUse = [ + { + val: "01", + text: "청소화장실용수", + }, + { + val: "02", + text: "세척살수용수", + }, + { + val: "03", + text: "조경용수", + }, + { + val: "04", + text: "친수용수", + }, + { + val: "05", + text: "지하수충전", + }, + { + val: "06", + text: "농업용수", + }, + { + val: "07", + text: "하천등유지용수", + }, + { + val: "08", + text: "공업용수", + }, +]; +// const codeMApping = { +// WR001: "bdstUsgCd", +// WR002: "rswtBdstType", +// WR003: "rainFcltCd", +// WR004: "bdstGrntchClass", +// WR005: "rswtPrscCdMthdCd", // 아직 디 못바꿈 +// WR006: "orgwtKndCd", //작업 완ㅛ +// WR007: "ruseMngMtd", // 작업완료 +// WR008: "rusePrcsMthdCd", //w작업완료 +// WR009: "erctUswtrPrcsMeth",//w작업완료 +// WR010: "ruseFcltSpot",// inout은 yn 만 사용해야 함으로 해당 코드는 사용안함. +// WR011: "pplQulity", +// WR012: "pplLenght", +// WR013: "bdstFilterYn", // 사용 불가 yn만 사용해야함으로 해당코드 사용 안함 +// WR014: "rainRswtMng", // 지도점검 등록 시변경 +// WR015: "rainFcltFlowRate", //지도점검 등록 시변경 +// WR016: "dmdUszCd", // 지도점검 등록 시변경 +// WR017: "sewageInFcltUse", //하수재이용 장내 +// WR018: "sewageOutFclttUse", // 하수재이용 장외 +// WR019: "htdPowerMthdCd", +// WR020: "htdUtztnUsgCd", +// }; +// export const getCommonUpCd = async () => { +// const upCd = await getFetchWithCount( +// fetchType.LOCAL, +// "/cms-service/api/v1/up-codes?keyword=&upCd=&cdSe=&useYn=Y&siteId=WR&page=0&size=100&sort=string" +// ); + +// const upWrCode: string[] = upCd.content +// .filter((item: any) => item.upCd.slice(0, 2) === "WR") +// .map((cd: any) => cd.upCd); + +// await Promise.all( +// upWrCode.map(async (cd) => { +// const mapping = codeMApping[cd as keyof typeof codeMApping]; +// if (!mapping) return; + +// const lwCd = await getFetchWithCount( +// fetchType.LOCAL, +// `/cms-service/api/v1/lwpo-cds/up-cd/${cd}` +// ); + +// const list = Array.isArray(lwCd) ? lwCd : lwCd.content ?? []; + +// lwCds[mapping] = list.map((it: any) => ({ +// text: it.lwpoCdNm, +// val: it.lwpoCd, +// })); +// }) +// ); +// console.log('lwCds ', lwCds) +// }; \ No newline at end of file diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index 72e910aad..0601c5e41 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -1,32 +1,97 @@ -import { getFetch } from "@/components/lib/api"; +import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api"; import type { EnvPartSelectDataType, SelectDataType, } from "@common/business_components/ui"; import { bdstFilterYn, - bdstGrntchClass, bdstIncenYn, - bdstUsgCd, chBuCd, - dmdUszCd, - erctUswtrPrcsMeth, - htdPowerMthdCd, - htdUtztnUsgCd, - orgwtKndCd, - pplLenght, - pplQulity, - rainFcltCd, - rswtPrscCdMthdCd, ruseBizMthdCd, - ruseMngMtd, - rusePrcsMthdCd, ruseSeCd, yn, } from "./basicCode"; export const btnClass = "p-4 m-2 text-white rounded-sm text-lg font-medium "; const laeSecd = "41"; +export const lwCds: Record = {}; + +const codeMApping = { + WR001: "bdstUsgCd", + WR002: "rswtBdstType", + WR003: "rainFcltCd", + WR004: "bdstGrntchClass", + WR005: "rswtPrscCdMthdCd", // 아직 디 못바꿈 + WR006: "orgwtKndCd", //작업 완ㅛ + WR007: "ruseMngMtd", // 작업완료 + WR008: "rusePrcsMthdCd", //w작업완료 + WR009: "erctUswtrPrcsMeth", //w작업완료 + WR010: "ruseFcltSpot", // inout은 yn 만 사용해야 함으로 해당 코드는 사용안함. + WR011: "pplQulity", + WR012: "pplLenght", + WR013: "bdstFilterYn", // 사용 불가 yn만 사용해야함으로 해당코드 사용 안함 + WR014: "rainRswtMng", // 지도점검 등록 시변경 + WR015: "rainFcltFlowRate", //지도점검 등록 시변경 + WR016: "dmdUszCd", // 지도점검 등록 시변경 + WR017: "sewageInFcltUse", //하수재이용 장내 + WR018: "sewageOutFclttUse", // 하수재이용 장외 + WR019: "htdPowerMthdCd", + WR020: "htdUtztnUsgCd", +}; +export const getCommonUpCd = async (set: any) => { + try { + let lwCdCode: Record = {}; + const upCd = await getFetchWithCount( + fetchType.LOCAL, + "/cms-service/api/v1/up-codes?keyword=&upCd=&cdSe=&useYn=Y&siteId=WR&page=0&size=100&sort=string" + ); + + const upWrCode: string[] = upCd.content + .filter((item: any) => item.upCd.slice(0, 2) === "WR") + .map((cd: any) => cd.upCd); + + await Promise.all( + upWrCode.map(async (cd) => { + const mapping = codeMApping[cd as keyof typeof codeMApping]; + if (!mapping) return; + + const lwCd = await getFetchWithCount( + fetchType.LOCAL, + `/cms-service/api/v1/lwpo-cds/up-cd/${cd}` + ); + + const list = Array.isArray(lwCd) ? lwCd : (lwCd.content ?? []); + lwCds[mapping] = list.map((it: any) => ({ + text: it.lwpoCdNm, + val: it.lwpoCd, + })); + }) + ); + lwCdCode = lwCds; + set((state: comCodeState) => ({ + code: { + ...state.code, + rainFcltCd: lwCdCode["rainFcltCd"] ?? [], + bdstUsgCd: lwCdCode["bdstUsgCd"] ?? [], + orgwtKndCd: lwCdCode["orgwtKndCd"] ?? [], + pplQulity: lwCdCode["pplQulity"] ?? [], + pplLenght: lwCdCode["pplLenght"] ?? [], + dmdUszCd: lwCdCode["dmdUszCd"] ?? [], + ruseMngMtd: lwCdCode["ruseMngMtd"] ?? [], + rusePrcsMthdCd: lwCdCode["rusePrcsMthdCd"] ?? [], + erctUswtrPrcsMeth: lwCdCode["erctUswtrPrcsMeth"] ?? [], + bdstGrntchClass: lwCdCode["bdstGrntchClass"] ?? [], + htdPowerMthdCd: lwCdCode["htdPowerMthdCd"] ?? [], + htdUtztnUsgCd: lwCdCode["htdUtztnUsgCd"] ?? [], + rswtBdstType: lwCdCode["rswtBdstType"] ?? [], + bdstTotalUsgType: + lwCdCode["bdstUsgCd"]?.concat(lwCdCode["rswtBdstType"] || []) ?? [], + }, + })); + } catch (e) { + console.log("com code error ", e); + } +}; //물재이용 주소 코드: devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM= export const buildingType = { RST: "RST", @@ -181,9 +246,11 @@ export type comCodeState = { bdstFilterYn: SelectDataType[]; bdstIncenYn: SelectDataType[]; bdstGrntchClass: SelectDataType[]; - rswtPrscCdMthdCd: SelectDataType[]; + // rswtPrscCdMthdCd: SelectDataType[]; htdPowerMthdCd: SelectDataType[]; htdUtztnUsgCd: SelectDataType[]; + rswtBdstType: SelectDataType[]; + bdstTotalUsgType: SelectDataType[]; userSiSggCd: string; }; }; @@ -193,50 +260,56 @@ export type comCodeType = comCodeState & comCodeActions; export const comCodeStateExport: comCodeState = { code: { isInit: false, - rainFcltCd: rainFcltCd, - bdstUsgCd: bdstUsgCd, + rainFcltCd: lwCds["rainFcltCd"] ?? [], + bdstUsgCd: lwCds["bdstUsgCd"] ?? [], chBuCd: chBuCd, - orgwtKndCd: orgwtKndCd, + orgwtKndCd: lwCds["orgwtKndCd"] ?? [], cityCd: [], sggCd: [], rvbsnCd: [], mdmbsnCd: [], lgbsnCd: [], lclgvrnmntCd: [], - pplQulity: pplQulity, - pplLenght: pplLenght, + pplQulity: lwCds["pplQulity"] ?? [], + pplLenght: lwCds["pplLenght"] ?? [], yn: yn, - dmdUszCd: dmdUszCd, + dmdUszCd: lwCds["dmdUszCd"] ?? [], buildingType: buildingType, - ruseMngMtd: ruseMngMtd, + ruseMngMtd: lwCds["ruseMngMtd"] ?? [], ruseSeCd: ruseSeCd, ruseBizMthdCd: ruseBizMthdCd, - rusePrcsMthdCd: rusePrcsMthdCd, - erctUswtrPrcsMeth: erctUswtrPrcsMeth, + rusePrcsMthdCd: lwCds["rusePrcsMthdCd"] ?? [], + erctUswtrPrcsMeth: lwCds["erctUswtrPrcsMeth"] ?? [], bdstFilterYn: bdstFilterYn, bdstIncenYn: bdstIncenYn, - bdstGrntchClass: bdstGrntchClass, - rswtPrscCdMthdCd: rswtPrscCdMthdCd, - htdPowerMthdCd: htdPowerMthdCd, - htdUtztnUsgCd: htdUtztnUsgCd, + bdstGrntchClass: lwCds["bdstGrntchClass"] ?? [], + // rswtPrscCdMthdCd: rswtPrscCdMthdCd, // 공단연락오면 바꿔야함 + htdPowerMthdCd: lwCds["htdPowerMthdCd"] ?? [], + htdUtztnUsgCd: lwCds["htdUtztnUsgCd"] ?? [], userSiSggCd: laeSecd, + rswtBdstType: lwCds["rswtBdstType"] ?? [], + bdstTotalUsgType: lwCds["bdstTotalUsgType"] ?? [], }, }; export type comCodeActions = { returnCodeText: (val: string, codeName: string) => string; + returnTextCode: (text: string, codeName: string) => string; }; -export const codeActionExport: (set: any) => comCodeActions = (set: any) => { +export const codeActionExport: (set: any, get:any) => comCodeActions = (set: any, get:any) => { return { returnCodeText: (val: string, codeName: string) => { - console.log('val', val, 'codeName', codeName); - return set((state: comCodeState) => { - const codeList = state.code[codeName] || []; - const found = codeList.find((item) => item.val === val); - return found ? found.text : val; - } - ); + + const codeList = get().code[codeName] || []; + const found = codeList.find((item) => item.val === val); + + return found ? found.text : val; + }, + returnTextCode: (text: string, codeName: string) => { + const codeList = get().code[codeName] || []; + const found = codeList.find((item) => item.text === text); + return found ? found.val : text; }, }; }; diff --git a/apps/wr/app/store/common/code/type.ts b/apps/wr/app/store/common/code/type.ts new file mode 100644 index 000000000..55f684f55 --- /dev/null +++ b/apps/wr/app/store/common/code/type.ts @@ -0,0 +1,31 @@ + +export type LwCdType= { + lwpoCd: string, + upCd: string, + lwpoCdNm:string, + lwpoCdExpln:string, + unit: string, + prntLwpoCd: string, + useYn: string, + sortSeq: number, + regDt: Date, + rgtr: string, + mdfcnDt: Date, + mdfr: string +} + + +export type UPCdType= { + upCd: string, + upCdNm: string, + upCdExpln: string, + cdSe: string, + useYn: string, + delYn: string, + siteId: string, + regDt:Date, + rgtr: string + mdfcnDt: Date, + mdfr: string + +} diff --git a/apps/wr/app/store/map/rainMap/index.tsx b/apps/wr/app/store/map/rainMap/index.tsx index 1d23e7991..050639096 100644 --- a/apps/wr/app/store/map/rainMap/index.tsx +++ b/apps/wr/app/store/map/rainMap/index.tsx @@ -23,9 +23,7 @@ export type rainMapState = { type rainMapActions = { rainMapInit: (page: number, total: number, cityOrSgg:string) => void; - rainMapSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + rainMapSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string,code:Record) => void; rainMapDetile:(featureCd:string) => Promise; }; @@ -72,8 +70,7 @@ export const rainMapActionsExport: (set: any) => rainMapActions = ( } }, rainMapSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { + code :Record) => { try { const rainMapRes = await getFetchWithCount( fetchType.WR, @@ -84,7 +81,7 @@ export const rainMapActionsExport: (set: any) => rainMapActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rainMapExcelList = excelRainSttnParsing(rainMapRes, sidoCode, sggCode); + const rainMapExcelList = excelRainSttnParsing(rainMapRes, code); set((state: rainMapState) => { return { diff --git a/apps/wr/app/store/map/rswtMap/index.tsx b/apps/wr/app/store/map/rswtMap/index.tsx index 4acc0e321..1c98a4dd2 100644 --- a/apps/wr/app/store/map/rswtMap/index.tsx +++ b/apps/wr/app/store/map/rswtMap/index.tsx @@ -23,9 +23,7 @@ export type rswtMapState = { type rswtMapActions = { rswtMapInit: (page: number, total: number, cityOrSgg: string) => void; rswtMapSearch: ( - isExcel: boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[] + isExcel: boolean, page: number, total: string, con: string, txt: string, code:Record ) => void; rswtMapDetile: (featureCd: string) => Promise; }; @@ -72,9 +70,7 @@ export const rswtMapActionsExport: (set: any) => rswtMapActions = ( console.log(e); } }, - rswtMapSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[] + rswtMapSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string,code:Record ) => { try { const rswtMapRes = await getFetchWithCount( @@ -86,7 +82,7 @@ export const rswtMapActionsExport: (set: any) => rswtMapActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rswtMapExcelList = excelRSwtSttnParsing(rswtMapRes, sidoCode, sggCode); + const rswtMapExcelList = excelRSwtSttnParsing(rswtMapRes, code); set((state: rswtMapState) => { return { ...state, diff --git a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx index 024f40fe7..8ed65ee7d 100644 --- a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx +++ b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx @@ -167,7 +167,7 @@ export const ruseCaseHeadListExport: TableUpperProps[] = [ }, { id: "grnteWqPh", - title: "수소이온농도(ph)​", + title: "수소이온농도(pH)​", visible: true, row: 1, }, @@ -313,7 +313,7 @@ export const ruseCaseHeadListExport: TableUpperProps[] = [ }, { id: "prcmPlanEcqrRt", - title: "국고비율", + title: "국고비율(%)", visible: true, row: 1, }, @@ -350,7 +350,7 @@ export const ruseCaseHeadListExport: TableUpperProps[] = [ }, { id: "clclnEcqrRt", - title: "국고비율", + title: "국고비율(%)", visible: true, row: 1, }, diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx index 38e2cab7f..21636860a 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/excel.tsx @@ -7,6 +7,7 @@ import { parseRawValue, } from "@/components/lib/func/excelFunc"; import toast from "react-hot-toast"; +import { codeToText, textToCode } from "@/components/lib/func/commom"; export const useTypes = [ "조경용수", "청소화장실용수", @@ -17,17 +18,13 @@ export const useTypes = [ "기타", ]; - -export const chkMngType =[ - '위탁', - '자체' -] -export const chkSpwtPositnType = [ - '유량계', - '수위계', - '펌프적산전력계', - '기타' -] +export const chkMngType = { "01": "위탁", "02": "자체" }; +export const rainFcltFlowRateType = { + "01": "유량계", + "02": "수위계", + "03": "펌프적산전력계", + "04": "기타", +}; export type Buildingtype = { bdstInfoSn: number; @@ -118,7 +115,7 @@ export const excelToRainChkData = (excelData: any, year: string) => { const ruseData = parseRawValue(item[`빗물_${month}월`]); if (month.length < 2) month = "0" + month; return { - utztnUsgCd: item["이용용도"], + utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd") ?? undefined, ym: year + month, chckYmd: checkYmd, splyUswtrUtztnQnt: splyData, @@ -133,14 +130,14 @@ export const excelToRainChkData = (excelData: any, year: string) => { bdstRuseFcltSn: Number(item["NO"]), chckYmd: checkYmd, rgtr: TEST_UUID, - operMngCd: item["운영관리형태"] ?? "", + operMngCd: textToCode(item["운영관리형태"], "rainRswtMng") ??item["운영관리형태"], anlOperCst: parseRawValue(item["연간운영비(원/년)"]), - oilqMeasMthd: item["유량측정방법"] ?? "", + oilqMeasMthd: textToCode( item["유량측정방법"],"rainFcltFlowRate",)??item["유량측정방법"], guideDetails: makeGuidDetail, rainyDetails: [ { ph: item["PH"], - utztnUsgCd: item["이용용도"], + utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"], trbt: parseRawValue(item["탁도"]), grssClfg: parseRawValue(item["총대장균군수"]), etc: item["기타"] || "", // 필드 누락 방지 @@ -156,10 +153,10 @@ export const excelToRainChkData = (excelData: any, year: string) => { }) .filter((el: any) => el !== undefined); -console.log("rainChkgdData", rainChkgdData); + console.log('rainChkgdData ', rainChkgdData) if (rainChkgdData.length > 0) { rainChkgdData.forEach((rain: any) => { - const defaultMessage = `[시설명: ${rain.bdstNm}, 점검일: ${rain.chckYmd}, 이용용도: ${rain.guideDetails[0]?.utztnUsgCd}] 항목에서 `; + const defaultMessage = `[시설명: ${rain.bdstNm}, 점검일: ${rain.chckYmd}, 이용용도: ${codeToText(rain.guideDetails[0]?.utztnUsgCd, "dmdUszCd") ??rain.guideDetails[0]?.utztnUsgCd}] 항목에서 `; if (rain.chckYmd && isInvalidDate(rain.chckYmd)) { issues.push( @@ -173,28 +170,36 @@ console.log("rainChkgdData", rainChkgdData); ); } - if (rain.operMngCd.length > 1 && !chkMngType.includes(rain.operMngCd)) { + if (rain.operMngCd.length > 1 && !chkMngType[rain.operMngCd]) { issues.push( - defaultMessage + `운영관리 형태: 위탁 혹은 자체 만 허용) /입력값:${rain.oilqMeasMthd}` + defaultMessage + + `운영관리 형태: 위탁 혹은 자체 만 허용) /입력값:${rain.operMngCd}` ); } - if (rain.oilqMeasMthd.length > 1 && !chkSpwtPositnType.includes(rain.oilqMeasMthd)) { + if ( + rain.oilqMeasMthd.length > 1 && + !rainFcltFlowRateType[rain.oilqMeasMthd] + ) { issues.push( - defaultMessage + `유량측정방법: 유량계, 수위계, 펌프적산전력계, 기타) /입력값:${rain.oilqMeasMthd}` + defaultMessage + + `유량측정방법: 유량계, 수위계, 펌프적산전력계, 기타) /입력값:${rain.oilqMeasMthd}` ); } rain.rainyDetails?.forEach((key) => { if (key.ph?.length > 1 && isInvalidNumber(key.ph)) { - issues.push(defaultMessage + `PH: 숫자 형식 아님 /입력값:${key.ph}`); + issues.push(defaultMessage + `pH: 숫자 형식 아님 /입력값:${key.ph}`); } if (key.trbt?.length > 1 && isInvalidNumber(key.trbt)) { - issues.push(defaultMessage + `탁도: 숫자 형식 아님 /입력값:${key.trbt}`); + issues.push( + defaultMessage + `탁도: 숫자 형식 아님 /입력값:${key.trbt}` + ); } if (key.grssClfg?.length > 1 && isInvalidNumber(key.grssClfg)) { issues.push( - defaultMessage + `총대장균군수: 숫자 형식 아님 /입력값:${key.grssClfg}` + defaultMessage + + `총대장균군수: 숫자 형식 아님 /입력값:${key.grssClfg}` ); } if (key.levyAmt?.length > 1 && isInvalidNumber(key.levyAmt)) { @@ -226,7 +231,7 @@ console.log("rainChkgdData", rainChkgdData); } }); }); - }else{ + } else { toast.error("데이터가 없습니다. 점검 데이터를 확인해주세요."); } diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx index 2b03d86df..b615b6532 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx @@ -87,6 +87,7 @@ export type chHeadType = { export type splRuseWaterType = { utztnUsgCd: string; + utztnUsgCdText: string; splTotal: number; spl01: number; spl02: number; @@ -141,17 +142,17 @@ export const rainChkgdnHeadListExport: TableUpperProps[] = [ { id: "cityText", title: "시도", mergeCell: true }, { id: "sggText", title: "시군구", mergeCell: true }, { id: "bdstNm", title: "시설명", mergeCell: true }, - { id: "operMngCd", title: "운영관리형태", mergeCell: true }, - { id: "oilqMeasMthd", title: "유량측정방법", mergeCell: true }, + { id: "operMngCdText", title: "운영관리형태", mergeCell: true }, + { id: "oilqMeasMthdText", title: "유량측정방법", mergeCell: true }, { id: "anlOperCst", title: "연간운영비(원/년)", mergeCell: true }, { id: "dtfcltCpct", title: "빗물저류조용량(m³)", mergeCell: true }, { id: "chckYmd", title: "점검일", mergeCell: true }, - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "totalSplyUswtrUtztnQnt", title: "연간대체수이용량(m³)" }, { id: "totalRuseFcltUtztnQnt", title: "연간빗물이용량(m³)" }, { id: "ph", - title: "수소이온농도(ph)", + title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 1, type: "number", @@ -201,7 +202,7 @@ export const rainChkgdnHeadListExport: TableUpperProps[] = [ ]; export const ruseHeadListExport: TableUpperProps[] = [ - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "ruseTotal", title: "계", upName: "ruseWater", upSequnce: 1 }, { id: "ruse01", title: "1월", upName: "ruseWater", upSequnce: 2 , edit: true }, { id: "ruse02", title: "2월", upName: "ruseWater", upSequnce: 3 , edit: true }, @@ -218,7 +219,7 @@ export const ruseHeadListExport: TableUpperProps[] = [ ]; export const splHeadListExport: TableUpperProps[] = [ - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "splTotal", title: "계", upName: "splWater", upSequnce: 1}, { id: "spl01", title: "1월", upName: "splWater", upSequnce: 2, edit: true }, { id: "spl02", title: "2월", upName: "splWater", upSequnce: 3, edit: true }, diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx index d2c8e18e1..1a0af3fad 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx @@ -72,7 +72,8 @@ type rainChkgdnActions = { rainChkGuidUpdate(rainChk: rainChkZodType): Promise; rainChkExcelDownload( sidoCode: SelectDataType[], - sggCode: SelectDataType[] + sggCode: SelectDataType[], + sggCd:string ): Promise; rainChkExcelDataUPload(excelData: rainChkZodType[] ,year :string) : Promise; rainChkDelete(chkgdnSns: number[] ,year :string): Promise; @@ -151,12 +152,13 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( return { rainChkExcelDownload: async ( sidoCode: SelectDataType[], - sggCode: SelectDataType[] + sggCode: SelectDataType[], + sggCd: string, ) => { // 로그인한 아이디의 시도 or 시군구로 들어가야하는데 현재는 그냥 0으로 하드코딩 const data = await getFetch( fetchType.WR, - `/reuseFc/buildingFlg/${buildingType.RNB}/41` + `/reuseFc/buildingFlg/${buildingType.RNB}/${sggCd}` ); const excelList = buildingToExcelType(data, sidoCode, sggCode); set((state: rainChkgdnState) => ({ @@ -262,7 +264,7 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( const res = await putFectch("/reuseChk/rainy/list", chData); if (res) { toast.success( - "지도점검 대체수 및 밋물이용량 수정이 완료되었습니다. " + "지도점검 대체수 및 빗물이용량 수정이 완료되었습니다. " ); const rainChkRes = await initFetch( 1, @@ -279,11 +281,11 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( }, })); } else { - toast.error("지도점검 대체수 및 밋물이용량 수정 오류입니다."); + toast.error("지도점검 대체수 및 빗물이용량 수정 오류입니다."); } } catch (error) { console.log(error); - toast.error("지도점검 대체수 및 밋물이용량 수정 오류입니다."); + toast.error("지도점검 대체수 및 빗물이용량 수정 오류입니다."); } }, rainChkGuidUpdate: async (rainChk: rainChkZodType) => { diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx index a3372639b..5edba24b5 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/excel.tsx @@ -11,6 +11,7 @@ import { useTypes, type Buildingtype } from "../rainChkgdn/excel"; +import { codeToText, textToCode } from "@/components/lib/func/commom"; export const rswtMakeExcelSample = ( buildings: Buildingtype[], @@ -158,12 +159,12 @@ export const excelToRswtGuideData = ( if (checkYmd.length > 7) { return { bdstRuseFcltSn: Number(item["NO"]), - operMngCd: item["운영관리형태"], + operMngCd: textToCode(item["운영관리형태"], "rainRswtMng") ??item["운영관리형태"], anlOperCst: parseCommaRawValue(item["연간운영비(원/년)"]), prcsCpct: parseRawValue(item[`처리용량(m³)`]), spwtPositn: item["채수지점"], chckYmd: checkYmd, - utztnUsgCd: item["이용용도"], + utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"], guideDetails: makeGuidDetail, rgtr: TEST_UUID, mdfr: TEST_UUID, @@ -226,7 +227,7 @@ export const excelToRswtPolution = (excelData: any) => { return { bdstRuseFcltSn: Number(item["NO"]), chckYmd: checkYmd, - utztnUsgCd: item["이용용도"], + utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"], operMngCd: item["운영관리형태"], anlOperCst: parseCommaRawValue(item["연간운영비(원/년)"]), prcsCpct: parseRawValue(item["처리용량(m³)"]), @@ -236,7 +237,7 @@ export const excelToRswtPolution = (excelData: any) => { mdfr: TEST_UUID, rswtrDetails: [ { - utztnUsgCd: item["이용용도"], + utztnUsgCd: textToCode(item["이용용도"], "dmdUszCd")??item["이용용도"], vltnDt: vltnDt, vltnMttr: item["위반사항"], levyAmt: Number(item["과태료 부과금액(천원)"]) ?? 0, @@ -248,13 +249,6 @@ export const excelToRswtPolution = (excelData: any) => { } }) .filter((el: any) => el !== undefined); - // if (rswtChkgdData.length > 0) { - // rswtExcelDataCheck(rswtChkgdData, issues); - // } - - // if (issues.length > 0) { - // return { data: [], issues }; - // } return rswtChkgdData }; @@ -265,7 +259,7 @@ export const rswtExcelDataCheck = ( ) => { rswtChkgdData.forEach((rswt: any) => { - const defaultMessage = `*중수도 수질 [NO: ${rswt.bdstRuseFcltSn}, 점검일: ${rswt.chckYmd}, 이용용도: ${rswt.utztnUsgCd}] 항목에서 `; + const defaultMessage = `*중수도 수질 [NO: ${rswt.bdstRuseFcltSn}, 점검일: ${rswt.chckYmd}, 이용용도: ${codeToText(rswt.utztnUsgCd ,"dmdUszCd")??rswt.utztnUsgCd}] 항목에서 `; if (rswt.chckYmd && isInvalidDate(rswt.chckYmd)) { issues.push(defaultMessage + `점검일: 날짜 형식 아님 (${rswt.chckYmd})`); @@ -284,7 +278,7 @@ export const rswtExcelDataCheck = ( } // if ( // rswt.spwtPositn.length > 1 && - // !chkSpwtPositnType.includes(rswt.spwtPositn) + // !rainFcltFlowRateType[rswt.spwtPositn] // ) { // issues.push( // defaultMessage + diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx index 56ee59197..6e94ec4e6 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx @@ -53,6 +53,7 @@ const buildingZod = z.object({ }); export const rswtrPolutionsZode = z.object({ + utztnUsgCdText:z.string().nullish(), chkgdnDtlFk: z.string().nullish(), utztnUsgCd: z.string().nullish(), node: z.string().nullish(), @@ -143,7 +144,7 @@ export const rswtChkHeadListExport: TableUpperProps[] = [ { id: "prcsCpct", title: "처리용량(m³)" ,mergeCell: true}, { id: "spwtPositn", title: "채수지점" ,mergeCell: true}, { id: "chckYmd", title: "점검일" ,mergeCell: true}, - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "splyUswtrUtztnQnt", title: "연간대체수이용량(m³)" ,type: "number"}, { id: "ruseFcltUtztnQnt", title: "연간중수도이용량(m³)",type: "number"}, @@ -167,7 +168,7 @@ export const rswtChkHeadListExport: TableUpperProps[] = [ { id: "crmty", title: "색도(도)", upName: "useQuilty", upSequnce: 6 ,type: "number"}, { id: "tn", title: "총질소(T-N)(mg/L)", upName: "useQuilty", upSequnce: 7 ,type: "number"}, { id: "tph", title: "총인(T-P)(mg/L)", upName: "useQuilty", upSequnce: 8 ,type: "number"}, - { id: "ph", title: "수소이온농도(ph)", upName: "useQuilty", upSequnce: 9,type: "text" }, + { id: "ph", title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 9,type: "text" }, { id: "clIonQnt", title: "염화물(mg/L)", upName: "useQuilty", upSequnce: 10 ,type: "number"}, { @@ -197,7 +198,7 @@ export const rswtChkHeadListExport: TableUpperProps[] = [ export const rswtDetailHeadListExport: TableUpperProps[] = [ - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "grssClfgUswtr", @@ -237,7 +238,7 @@ export const rswtChkHeadListExport: TableUpperProps[] = [ }, { id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8, edit: true }, { id: "tph", title: "T-P", upName: "detailQulity", upSequnce: 9, edit: true }, - { id: "ph", title: "PH", upName: "detailQulity", upSequnce: 10, edit: true }, + { id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10, edit: true }, { id: "clIonQnt", title: "염화물", diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx index afba2f813..e9ebdab8d 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/index.tsx @@ -75,7 +75,8 @@ type rswtChkgdnActions = { ) => void; rswtrChkExcelDownload( sidoCode: SelectDataType[], - sggCode: SelectDataType[] + sggCode: SelectDataType[], + sggCd: string, ): Promise; rswtChkExceDataUpload: (excelData: rswtChkZodType[]) => void; rswtChkDelete: (chkgdnSns: number[] ,year:string) => void; @@ -84,6 +85,7 @@ type rswtChkgdnActions = { rswtChkPolInit: () => void; rwstPolAndGuideUpdate: (rswtChk: rswtChkZodType[]) => void; rswtChkHeadChange: (rswtChkgdn: rswtChkgdnState, isEdit: boolean) => void; + setRswtChkLoading:(status:boolean) =>void }; export type rswtChkgdnType = rswtChkgdnState & rswtChkgdnActions; @@ -153,11 +155,12 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( return { rswtrChkExcelDownload: async ( sidoCode: SelectDataType[], - sggCode: SelectDataType[] + sggCode: SelectDataType[], + sggCd: string, ) => { const data = await getFetch( fetchType.WR, - `/reuseFc/buildingFlg/${buildingType.RST}/41` + `/reuseFc/buildingFlg/${buildingType.RST}/${sggCd}` ); const excelList: any = []; const exceldata = rswtMakeExcelSample(data, sidoCode, sggCode); @@ -394,6 +397,15 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = ( } catch (e) { console.error(e); } - }, + },setRswtChkLoading:(status:boolean) =>{ + set((state: rswtChkgdnState) => ({ + ...state, + rswtChkgdn: { + ...state.rswtChkgdn, + isLoading: status, + }, + })); + } + }; }; diff --git a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx index bfd2838d0..51b9634d3 100644 --- a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx +++ b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx @@ -5,17 +5,17 @@ export const rainChkgdnHeadSttnExport: TableUpperProps[] = [ { id: "cityText", title: "시도", mergeCell: true }, { id: "sggText", title: "시군구", mergeCell: true }, { id: "bdstNm", title: "시설명", mergeCell: true }, - { id: "operMngCd", title: "운영관리형태", mergeCell: true }, - { id: "oilqMeasMthd", title: "유량측정방법", mergeCell: true }, + { id: "operMngCdText", title: "운영관리형태", mergeCell: true }, + { id: "oilqMeasMthdText", title: "유량측정방법", mergeCell: true }, { id: "anlOperCst", title: "연간운영비(원/년)", mergeCell: true }, { id: "dtfcltCpct", title: "빗물저류조용량(m³)", mergeCell: true }, { id: "chckYmd", title: "점검일", mergeCell: true }, - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "totalSplyUswtrUtztnQnt", title: "연간대체수이용량(m³)" }, { id: "totalRuseFcltUtztnQnt", title: "연간빗물이용량(m³)" }, { id: "ph", - title: "수소이온농도(ph)", + title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 1, type: "number", @@ -59,7 +59,7 @@ export const rainChkgdnHeadSttnExport: TableUpperProps[] = [ ]; export const ruseSttnHeadListExport: TableUpperProps[] = [ - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "ruseTotal", title: "계", upName: "ruseWater", upSequnce: 1 }, { id: "ruse01", title: "1월", upName: "ruseWater", upSequnce: 2 }, { id: "ruse02", title: "2월", upName: "ruseWater", upSequnce: 3 }, @@ -76,7 +76,7 @@ export const ruseSttnHeadListExport: TableUpperProps[] = [ ]; export const splSttnHeadListExport: TableUpperProps[] = [ - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "splTotal", title: "계", upName: "splWater", upSequnce: 1 }, { id: "spl01", title: "1월", upName: "splWater", upSequnce: 2 }, { id: "spl02", title: "2월", upName: "splWater", upSequnce: 3 }, @@ -108,7 +108,7 @@ export const splSttnHeadListExport: TableUpperProps[] = [ ]; export const rswtDetailHeadListExport: TableUpperProps[] = [ - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "grssClfgUswtr", @@ -153,7 +153,7 @@ export const rswtDetailHeadListExport: TableUpperProps[] = [ upName: "detailQulity", upSequnce: 9, }, - { id: "ph", title: "PH", upName: "detailQulity", upSequnce: 10 }, + { id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10 }, { id: "clIonQnt", title: "염화물", diff --git a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx index 382396566..831266e36 100644 --- a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx +++ b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx @@ -10,7 +10,7 @@ export const rswtChkSttnHeadListExport: TableUpperProps[] = [ { id: "prcsCpct", title: "처리용량(m³)", mergeCell: true }, { id: "spwtPositn", title: "채수지점", mergeCell: true }, { id: "chckYmd", title: "점검일", mergeCell: true }, - { id: "utztnUsgCd", title: "이용용도" }, + { id: "utztnUsgCdText", title: "이용용도" }, { id: "splyUswtrUtztnQnt", title: "연간보급수이용량(m³)", type: "number" }, { id: "ruseFcltUtztnQnt", title: "연간중수도이용량(m³)", type: "number" }, @@ -64,7 +64,7 @@ export const rswtChkSttnHeadListExport: TableUpperProps[] = [ upSequnce: 8, type: "number", }, - { id: "ph", title: "수소이온농도(ph)", upName: "useQuilty", upSequnce: 9, type: "text" }, + { id: "ph", title: "수소이온농도(pH)", upName: "useQuilty", upSequnce: 9, type: "text" }, { id: "clIonQnt", title: "염화물(mg/L)", @@ -132,7 +132,7 @@ export const rswtDetailSttnHeadListExport: TableUpperProps[] = [ }, { id: "tn", title: "T-N", upName: "detailQulity", upSequnce: 8}, { id: "tph", title: "T-P", upName: "detailQulity", upSequnce: 9 }, - { id: "ph", title: "PH", upName: "detailQulity", upSequnce: 10 }, + { id: "ph", title: "pH", upName: "detailQulity", upSequnce: 10 }, { id: "clIonQnt", title: "염화물", diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx index 1d9a0f6af..837b669ec 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx @@ -1,201 +1,266 @@ import { getFetch } from "@/components/lib/api"; -import { TEST_UUID, type customRainBdst } from "../rainReg"; +import { TEST_UUID, type customRainBdst } from "../rainReg"; import type { customHtdflBdst } from "../htdflReg"; import type { customRswtBdst } from "../rswtReg"; import type { TableUpperProps } from "@/app/store/common/type/header"; +import type { SelectDataType } from "@common/business_components/ui"; +const moUpHeadList: TableUpperProps[] = [ + { id: "cityText", title: "시도" }, + { id: "sggText", title: "시군구" }, + { id: "bdstNm", title: "시설명" }, + { id: "daddr", title: "위치" }, + { id: "frstArchPrmsnDt", title: "최초건축허가일" }, + { id: "archArea", title: "건축면적(㎡)" }, +]; - const moUpHeadList: TableUpperProps[] = [ - { id: "cityText", title: "시도" }, - { id: "sggText", title: "시군구" }, - { id: "bdstNm", title: "시설명" }, - { id: "daddr", title: "위치" }, - { id: "frstArchPrmsnDt", title: "최초건축허가일" }, - { id: "archArea", title: "건축면적(㎡)", }, - ]; +const bdstChgHeadList: TableUpperProps[] = [ + { id: "bdstChgNm", title: "구분" }, + { id: "archChgPrmsnDt", title: "허가일" }, + { id: "archChgArea", title: "변경면적(㎡)" }, +]; +const bdstBase: any[] = []; - const bdstChgHeadList: TableUpperProps[] = [ - { id: "bdstChgNm", title: "구분" }, - { id: "archChgPrmsnDt", title: "허가일" }, - { id: "archChgArea", title: "변경면적(㎡)" }, - - ]; - - - -const bdstBase:any[] = []; - - -const isRainBdst = (data: any): data is customRainBdst=> { +const isRainBdst = (data: any): data is customRainBdst => { return data.reuseBuilding?.[0]?.rainyObj !== undefined; -} +}; -const isHtdflBdst = (data: any): data is customHtdflBdst=> { +const isHtdflBdst = (data: any): data is customHtdflBdst => { return data.reuseBuilding?.[0]?.htdflObj !== undefined; -} +}; -const isRswtBdst = (data: any): data is customRswtBdst =>{ +const isRswtBdst = (data: any): data is customRswtBdst => { return data.reuseBuilding?.[0]?.rswtrObj !== undefined; -} +}; +export const makeRstr = ( + data: customRainBdst | customHtdflBdst | customRswtBdst +) => { + data.rgtr = TEST_UUID; - - export const makeRstr =(data:customRainBdst|customHtdflBdst|customRswtBdst) =>{ - data.rgtr = TEST_UUID; - - let chData - if(isRainBdst(data)){ + let chData; + if (isRainBdst(data)) { chData = data.reuseBuilding.map((item) => ({ ...item, - rgtr : TEST_UUID, - rainyObj:{ + rgtr: TEST_UUID, + rainyObj: { ...item.rainyObj, - rgtr:TEST_UUID - } + rgtr: TEST_UUID, + }, })); - data.reuseBuilding=chData; - }else if(isHtdflBdst(data)){ + data.reuseBuilding = chData; + } else if (isHtdflBdst(data)) { chData = data.reuseBuilding.map((item) => ({ ...item, - rgtr : TEST_UUID, - htdflObj:{ + rgtr: TEST_UUID, + htdflObj: { ...item.htdflObj, - rgtr:TEST_UUID - } + rgtr: TEST_UUID, + }, })); - data.reuseBuilding=chData; - }else if (isRswtBdst(data)){ + data.reuseBuilding = chData; + } else if (isRswtBdst(data)) { chData = data.reuseBuilding.map((item) => ({ ...item, - rgtr : TEST_UUID, - rswtrObj:{ + rgtr: TEST_UUID, + rswtrObj: { ...item.rswtrObj, - rgtr:TEST_UUID - } + rgtr: TEST_UUID, + }, })); - data.reuseBuilding=chData; + data.reuseBuilding = chData; } - - if('chgBuilding' in data && Array.isArray(data.chgBuilding) && data.chgBuilding.length > 0){ - const chRgtr = data.chgBuilding.map((item) =>({...item, rgtr:TEST_UUID, mdfr: item.mdfr ?? null })) - data.chgBuilding =chRgtr; - } - return data; - + if ( + "chgBuilding" in data && + Array.isArray(data.chgBuilding) && + data.chgBuilding.length > 0 + ) { + const chRgtr = data.chgBuilding.map((item) => ({ + ...item, + rgtr: TEST_UUID, + mdfr: item.mdfr ?? null, + })); + data.chgBuilding = chRgtr; } + return data; +}; - export const makeMdfr =(data:customRainBdst|customHtdflBdst|customRswtBdst) =>{ - data.mdfr = TEST_UUID; - let chData - if(isRainBdst(data)){ - chData = data.reuseBuilding.map((item) => ({ - ...item, - mdfr : TEST_UUID, - rainyObj:{ - ...item.rainyObj, - mdfr:TEST_UUID - } - })); - if(data?.chgBuilding.length>0){ - const chRgtr = data.chgBuilding.map((item) =>({...item, rgtr:TEST_UUID, mdfr: item.mdfr ?? null })) - data.chgBuilding =chRgtr; - } - - data.reuseBuilding=chData - }else if(isHtdflBdst(data)){ - chData = data.reuseBuilding.map((item) => ({ +export const makeMdfr = ( + data: customRainBdst | customHtdflBdst | customRswtBdst +) => { + data.mdfr = TEST_UUID; + let chData; + if (isRainBdst(data)) { + chData = data.reuseBuilding.map((item) => ({ + ...item, + mdfr: TEST_UUID, + rainyObj: { + ...item.rainyObj, + mdfr: TEST_UUID, + }, + })); + if (data?.chgBuilding.length > 0) { + const chRgtr = data.chgBuilding.map((item) => ({ ...item, - mdfr : TEST_UUID, - htdflObj:{ - ...item.htdflObj, - mdfr:TEST_UUID - } + rgtr: TEST_UUID, + mdfr: item.mdfr ?? null, })); - data.reuseBuilding=chData; - }else if (isRswtBdst(data)){ - chData = data.reuseBuilding.map((item) => ({ - ...item, - mdfr : TEST_UUID, - rswtrObj:{ - ...item.rswtrObj, - mdfr:TEST_UUID - } - })); - data.reuseBuilding=chData; + data.chgBuilding = chRgtr; } - if('chgBuilding' in data && Array.isArray(data.chgBuilding) && data.chgBuilding.length > 0){ - const chMdfr = data.chgBuilding.map((item) =>({...item, mdfr:TEST_UUID, archChgArea: item.archChgArea ?? '' })) - data.chgBuilding =chMdfr; - } - - return data; - + data.reuseBuilding = chData; + } else if (isHtdflBdst(data)) { + chData = data.reuseBuilding.map((item) => ({ + ...item, + mdfr: TEST_UUID, + htdflObj: { + ...item.htdflObj, + mdfr: TEST_UUID, + }, + })); + data.reuseBuilding = chData; + } else if (isRswtBdst(data)) { + chData = data.reuseBuilding.map((item) => ({ + ...item, + mdfr: TEST_UUID, + rswtrObj: { + ...item.rswtrObj, + mdfr: TEST_UUID, + }, + })); + data.reuseBuilding = chData; } + if ( + "chgBuilding" in data && + Array.isArray(data.chgBuilding) && + data.chgBuilding.length > 0 + ) { + const chMdfr = data.chgBuilding.map((item) => ({ + ...item, + mdfr: TEST_UUID, + archChgArea: item.archChgArea ?? "", + })); + data.chgBuilding = chMdfr; + } + + return data; +}; + export type bdstFulType = bdstState & bdstActions; - export type bdstState = { bdst: { bdstBase: any[]; - moUpHeadList:TableUpperProps[] - bdstChgHeadList:TableUpperProps[] + moUpHeadList: TableUpperProps[]; + bdstChgHeadList: TableUpperProps[]; + userCityCd: SelectDataType[]; + userSggCd: SelectDataType[]; }; }; type bdstActions = { - findBdst: (sggCd:string, searchTxt:string, flag:string) => void ; - }; - - - const findBdstInfo = async(sggCd:string, searchTxt:string ,flg:string)=>{ - return await getFetch('wr', `/reuseFc/building/${flg}/${sggCd}`+(searchTxt?`/${searchTxt}`:'' )) - - } - + findBdst: (sggCd: string, searchTxt: string, flag: string) => void; + setUserCitySggCd: ( + laeSeCd: string, + cityCd: SelectDataType[], + sggCd: SelectDataType[]) => void; + setUserSggCd: ( userCityCd: string,sggCd: SelectDataType[]) => void; +}; + +const findBdstInfo = async (sggCd: string, searchTxt: string, flg: string) => { + return await getFetch( + "wr", + `/reuseFc/building/${flg}/${sggCd}` + (searchTxt ? `/${searchTxt}` : "") + ); +}; + export const bdstStateExport: bdstState = { bdst: { bdstBase: bdstBase, // Updated to match the array type - moUpHeadList:moUpHeadList, - bdstChgHeadList:bdstChgHeadList, + userCityCd: [], + userSggCd: [], + moUpHeadList: moUpHeadList, + bdstChgHeadList: bdstChgHeadList, }, }; -export const bdstActionsExport: (set: any) => bdstActions = ( - set: any -) => { +export const bdstActionsExport: (set: any) => bdstActions = (set: any) => { return { - - findBdst: async(sggCd:string, searchTxt:string ,flg:string ) =>{ - try{ - - const bdst = await findBdstInfo(sggCd, searchTxt, flg); - const makeBdst = bdst.map((item:any) => { - return { - ...item, - reuseBuilding:[] - }; - }) - return set((state:bdstState) =>({ - ...state, - bdst:{ - ...state.bdst, - bdstBase:makeBdst - } - - })) - }catch(error1){ - console.log("error ", error1) - - }finally{ - - } + findBdst: async (sggCd: string, searchTxt: string, flg: string) => { + try { + const bdst = await findBdstInfo(sggCd, searchTxt, flg); + const makeBdst = bdst.map((item: any) => { + return { + ...item, + reuseBuilding: [], + }; + }); + return set((state: bdstState) => ({ + ...state, + bdst: { + ...state.bdst, + bdstBase: makeBdst, + }, + })); + } catch (error1) { + console.log("error ", error1); + } finally { + } }, + setUserCitySggCd: ( + laeSeCd: string, + cityCd: SelectDataType[], + sggCd: SelectDataType[] + ) => { + let city = [...cityCd]; + let sgg = [...sggCd] + console.log('sgg ', sgg) + if (laeSeCd === "0" && cityCd.length > 0) { + city = city; + sgg = [{ val: "0", text: "전체" }] + } else if (laeSeCd.length === 2 && cityCd.length > 0) { + city = cityCd.filter((item) => item.val === laeSeCd); + sgg = sggCd.filter((item) => item.val.slice(0, 2) === laeSeCd); + sggCd.unshift({ val: "0", text: "전체" }); + } else if ( + laeSeCd.length === 5 && + cityCd.length > 0 && + sggCd.length > 0 + ) { + city = cityCd.filter((item) => item.val === laeSeCd.slice(0, 2)); + sgg = sggCd.filter((item) => item.val === laeSeCd); + + + } + + return set((state: bdstState) => ({ + + + ...state, + bdst: { + ...state.bdst, + userCityCd: city, + userSggCd: sgg, + }, + })); + },setUserSggCd( userCityCd: string,sggCd: SelectDataType[]){ + + + const sgg = sggCd.filter((item) => item.val.slice(0, 2) === userCityCd); + + return set((state: bdstState) => ({ + ...state, + bdst: { + ...state.bdst, + userSggCd: sgg, + }, + })); + }, }; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 423c3c113..b1e0daf82 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -26,6 +26,12 @@ import { import type { TableUpperProps } from "@/app/store/common/type/header"; import toast from "react-hot-toast"; +/** + * 하수재이용시설 등록 (스토어) + * 재이용시설 등록 - 하수재이용시설 등록 + * 하수재이용시설 사용하는 api 및 타입 등을 관리한다. + * */ + const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }]; const pubFacHeadList = pubFacHeadListExport; const pbnstMngUpHeadList = pbnstMngUpHeadListExport; @@ -37,7 +43,6 @@ const fcOrgwtsHeadList = fcOrgwtsHeadListExport; export type pubFacState = { pbnst: { - isInit: boolean; pubFacHeadList: TableUpperProps[]; pbnstMngUpHeadList: TableUpperProps[]; pbnstMngNm: chHeadType[]; @@ -52,10 +57,10 @@ export type pubFacState = { fcOrgwtsHeadList: TableUpperProps[]; pbnstMngRegData: customPbnst[]; pbnsUpdateIndex: pbnstInsertIndex; - fcOrgwtsNmList:pubHasuType[]; + fcOrgwtsNmList: pubHasuType[]; dmdComList: any[]; - apiMessage:string; - pbnstHasuResCount:number + apiMessage: string; + pbnstHasuResCount: number; }; }; type pubFacActions = { @@ -63,19 +68,17 @@ type pubFacActions = { pbnstRegClick: (pubHasuRes: pubHasuType) => void; //pbnstReg: (txt: string | undefined) => void; pbnstInsert(pbnstRes: customPbnst): Promise; - appendRuseFclt(array: customPbnst[]): void; fileDelete: (atflCd: string) => void; fileDownLoad: (atflCd: string) => void; pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; - pubHasuSearch :(page: string, sggOrCity: string , searchTxt:string) => void - getFcOrgwts: (fcltPkList: string[], size:number) => void; + pubHasuSearch: (page: string, sggOrCity: string, searchTxt: string) => void; + getFcOrgwts: (fcltPkList: string[], size: number) => void; }; export type pubFacType = pubFacState & pubFacActions; export const pubFacStateExport: pubFacState = { pbnst: { - isInit: false, pubFacHeadList: pubFacHeadList, pbnstMngUpHeadList: pbnstMngUpHeadList, pbnstMngNm: pbnstMngNm, @@ -90,10 +93,10 @@ export const pubFacStateExport: pubFacState = { pbnstBizCycle: [{ text: "없음", val: "1" }], pbnstMngRegData: [], pbnsUpdateIndex: {} as pbnstInsertIndex, - fcOrgwtsNmList:[], + fcOrgwtsNmList: [], dmdComList: [], - apiMessage:'', - pbnstHasuResCount:1 + apiMessage: "", + pbnstHasuResCount: 1, }, }; @@ -102,22 +105,20 @@ export const checkWrRegList = async () => { return wrRegList; }; -const hasuListFetch = async (page: string, sggOrCity: string, searchTxt?:string) => { +const hasuListFetch = async ( + page: string, + sggOrCity: string, + searchTxt?: string +) => { const checkWrRegListRes = await checkWrRegList(); -let url = `/prcsFclt/ruseInfo/${page ? page : 1}/11/A/${sggOrCity? sggOrCity : "11"}/0/1/SW`; + let url = `/prcsFclt/ruseInfo/${page ? page : 1}/11/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`; - -const data = checkWrRegListRes.filter((item:string) => item !== "") -if(searchTxt){ - url= url +`/${searchTxt}` - -} - const rainRes = await postFectch( - url, - data, - fetchType.COMMON - ); + const data = checkWrRegListRes.filter((item: string) => item !== ""); + if (searchTxt) { + url = url + `/${searchTxt}`; + } + const rainRes = await postFectch(url, data, fetchType.COMMON); const hasuList = rainRes.data.map((item: any) => { return { @@ -127,54 +128,52 @@ if(searchTxt){ }; }); - return {data: hasuList, count:rainRes.count}; + return { data: hasuList, count: rainRes.count }; }; -const initFetch = async (ruseFcltPk: string | undefined) => { +const initFetch = async (ruseFcltPk: string | undefined) => { const pbnstRes = await getFetch("wr", `/reuseFc/pubFc/${ruseFcltPk}`); return pbnstRes; }; export const writeRgtrAndMdfr = (data: customPbnst[]) => { - data.forEach((pbnst) => { pbnst.rgtr = TEST_UUID; pbnst.mdfr = TEST_UUID; - pbnst.fcBizs = pbnst.fcBizs?.map((item) => { - item.rgtr = TEST_UUID; - item.mdfr = TEST_UUID; - item.fcOrgwts = item.fcOrgwts?.map((orgwt) => { - orgwt.mdfr = TEST_UUID; - orgwt.rgtr = TEST_UUID; - return orgwt; - }); + pbnst.fcBizs = pbnst.fcBizs?.map((item) => { + item.rgtr = TEST_UUID; + item.mdfr = TEST_UUID; + item.fcOrgwts = item.fcOrgwts?.map((orgwt) => { + orgwt.mdfr = TEST_UUID; + orgwt.rgtr = TEST_UUID; + return orgwt; + }); - item.fcDemands = item.fcDemands?.map((dmd) => { - dmd.mdfr = TEST_UUID; - dmd.rgtr = TEST_UUID; - return dmd; + item.fcDemands = item.fcDemands?.map((dmd) => { + dmd.mdfr = TEST_UUID; + dmd.rgtr = TEST_UUID; + return dmd; + }); + return item; + }); + pbnst.fcOpers = pbnst?.fcOpers?.map((oper) => { + oper.rgtr = TEST_UUID; + oper.mdfr = TEST_UUID; + return oper; + }); + pbnst.fcFiles = pbnst.fcFiles?.map((file) => { + file.rgtr = TEST_UUID; + file.mdfr = TEST_UUID; + return file; }); - return item; }); - pbnst.fcOpers = pbnst?.fcOpers?.map((oper) => { - oper.rgtr = TEST_UUID; - oper.mdfr = TEST_UUID; - return oper; - }); - pbnst.fcFiles = pbnst.fcFiles?.map((file) => { - file.rgtr = TEST_UUID; - file.mdfr = TEST_UUID; - return file; - }); -}); - - return data; }; export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { return { + // 하수처리시설을 조회한다(운영실태) pubHasuInit: async (page: string, sggOrCity: string) => { try { const pbnstHasuRes = await hasuListFetch(page, sggOrCity); @@ -183,30 +182,34 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { pbnst: { ...state.pbnst, pbnstHasuRes: pbnstHasuRes.data, - pbnstHasuResCount:pbnstHasuRes.count, - isInit: false, - }, - })); - } catch (errorHasu) { - console.log(errorHasu); - } - },pubHasuSearch : async(page: string, sggOrCity: string , searchTxt:string)=> { - - try{ - const pbnstHasuRes = await hasuListFetch(page, sggOrCity,searchTxt); - return set((state: pubFacState) => ({ - ...state, - pbnst: { - ...state.pbnst, - pbnstHasuRes: pbnstHasuRes.data, - pbnstHasuResCount:pbnstHasuRes.count, - isInit: false, + pbnstHasuResCount: pbnstHasuRes.count, }, })); } catch (errorHasu) { console.log(errorHasu); } }, + // 하수처리시설을 조회한다(운영실태) (처리시설명 포함) + pubHasuSearch: async ( + page: string, + sggOrCity: string, + searchTxt: string + ) => { + try { + const pbnstHasuRes = await hasuListFetch(page, sggOrCity, searchTxt); + return set((state: pubFacState) => ({ + ...state, + pbnst: { + ...state.pbnst, + pbnstHasuRes: pbnstHasuRes.data, + pbnstHasuResCount: pbnstHasuRes.count, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, + // 하수재이용시설을 조회한다 pbnstRegClick: async (pubHasuRes: pubHasuType) => { try { const pbnstRes = await initFetch(pubHasuRes.bscFctCd); @@ -215,79 +218,53 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { pbnst: { ...state.pbnst, pbnstRes: pbnstRes, - isInit: false, }, })); } catch (errorHasu) { console.log(errorHasu); } }, + // 하수재이용시설을 등록한다. pbnstInsert: async (pbnstRes: customPbnst) => { try { - - const response = await postFectch( - `/reuseFc/pubFc`, - pbnstRes - ); - if( response.status === 200) { - toast.success(`${pbnstRes.ruseUtztnFcltNm} 하수재이용 시설이 등록되었습니다.`); + const response = await postFectch(`/reuseFc/pubFc`, pbnstRes); + if (response.status === 200) { + toast.success( + `${pbnstRes.ruseUtztnFcltNm} 하수재이용 시설이 등록되었습니다.` + ); } - const newPbnstRes = await initFetch(pbnstRes.pbnstRuseFcltId.slice(0, 11)); + const newPbnstRes = await initFetch( + pbnstRes.pbnstRuseFcltId.slice(0, 11) + ); return set((state: pubFacState) => ({ ...state, pbnst: { ...state.pbnst, pbnstRes: newPbnstRes, - // isInit: false, }, })); - - } catch (error) { console.error("Error updating pbnst:", error); } - },pbnstRuseFcltUpdate : async(ruseRes:customPbnst[])=>{ - try { - - await putFectch( - `/reuseFc/pubFc`, - ruseRes - ); - - } catch (error) { - console.error("Error pbnstRuseFcltUpdate:", error); - } - } ,pbnstRuseBizUpdate : async(ruseRes:fcBizType[])=>{ - try { - - await putFectch( - `/reuseFc/pubFcBiz`, - ruseRes - ); - - } catch (error) { - console.error("Error pbnstRuseFcltUpdate:", error); - } - } , - getBizCycle: async (pbnstObj: customPbnst) => { - const pbnstBizCycle = pbnstObj.fcBizs.map((item) => { - return { - text: `${item.cycl}차`, - val: item.cycl, - }; - }); - - return set((state: pubFacState) => ({ - ...state, - pbnst: { - ...state.pbnst, - pbnstBizCycle: pbnstBizCycle, - pbnstResObj: pbnstObj, - isInit: false, - }, - })); }, + // 하수재이용시설을 업데이트한다.(사업제외) 다르게하는 이유는 객체가 너무커서 분활 처리하려고 + pbnstRuseFcltUpdate: async (ruseRes: customPbnst[]) => { + try { + await putFectch(`/reuseFc/pubFc`, ruseRes); + } catch (error) { + console.error("Error pbnstRuseFcltUpdate:", error); + } + }, + // 하수재이용시설을 업데이트한다.(사업포함) 다르게하는 이유는 객체가 너무커서 분활 처리하려고 + pbnstRuseBizUpdate: async (ruseRes: fcBizType[]) => { + try { + await putFectch(`/reuseFc/pubFcBiz`, ruseRes); + } catch (error) { + console.error("Error pbnstRuseFcltUpdate:", error); + } + }, + // 파일삭제 (attach-service) fileDelete: async (atflCd: string) => { try { const response = await deleteFectch( @@ -301,41 +278,26 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { ...state, pbnst: { ...state.pbnst, - isInit: false, }, })); } catch (error) { console.error("Error deleting file:", error); } }, + // 파일다운로드 (attach-service) fileDownLoad: async (atflCd: string) => { try { - await getFetch( + await getFetch( fetchType.CS, `/attach-service/api/v1/atflcd/download/${atflCd}` ); } catch (error) { console.error("Error downloading file:", error); throw new Error(`Error downloading file: ${error}`); - } }, - - appendRuseFclt: async (array: customPbnst[]) => { - try { - return set((state: pubFacState) => ({ - ...state, - pbnst: { - ...state.pbnst, - pbnstRes: array, - isInit: false, - }, - })); - } catch (e) { - console.log(e); - } - },getFcOrgwts : async (fcltPkList: string[] ,size:number) => { - + //원수취수 팝업의 하수처리 시설 리스트 조회 + getFcOrgwts: async (fcltPkList: string[], size: number) => { const fcOrgwtsNmList = await postFectch( `/prcsFclt/ruseInfo/1/${size}/A/0/0/1/SW`, fcltPkList, @@ -346,10 +308,9 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { ...state, pbnst: { ...state.pbnst, - fcOrgwtsNmList:fcOrgwtsNmList.data??[] + fcOrgwtsNmList: fcOrgwtsNmList.data ?? [], }, })); - } - + }, }; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index b44f5f700..565909a57 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -1,15 +1,31 @@ import type { TableUpperProps } from "@/app/store/common/type/header"; -import { getFetchWithCount, postFectch, putFectch } from "@/components/lib/api"; +import { + fetchType, + getFetchWithCount, + postFectch, + putFectch, +} from "@/components/lib/api"; import toast from "react-hot-toast"; import { z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; -import { baseReuseBuildingSchema, chgBuildingSchema, validationMessages } from "./type"; +import { + baseReuseBuildingSchema, + chgBuildingSchema, + validationMessages, +} from "./type"; +export const TEST_UUID = "2d4b151d-1828-41e0-91d9-4cd28ea1cc7e"; +export const rainRegSize = 15; -export const TEST_UUID = '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e' -export const rainRegSize =15 +/** + * 밧물이용시설 등록 (스토어) + * 재이용시설 등록 - 빗물시설 등록 + * 빗물이용시설에서 사용하는 api 및 타입 등을 관리한다. + * */ const rainyObjSchema = z.object({ bdstReuseFcltFk: z.number().nullish(), - pntfColKnd: z.string().min(1, { message: validationMessages.requiredSelect("종류") }), + pntfColKnd: z + .string() + .min(1, { message: validationMessages.requiredSelect("종류") }), pntfColArea: z.number().nullish(), dtfcltCpct: z.number().default(0), filtrTrtmfctYn: z.string().default("Y"), @@ -21,10 +37,9 @@ const rainyObjSchema = z.object({ mdfr: z.string().nullish(), }); - const rainBuildingSchema = baseReuseBuildingSchema.extend({ rainyObj: rainyObjSchema, -}) +}); export const rainZod = z.object({ bdstInfoSn: z.number().optional(), @@ -34,23 +49,23 @@ export const rainZod = z.object({ bdstNm: z.string().default(""), frstArchPrmsnDt: z.date().default(() => new Date()), archChgPrmsnDt: z.coerce.date().nullish().default(null), - archArea: z.string().default(''), + archArea: z.string().default(""), archChgArea: z.number().default(0), rgtr: z.string().nullish(), mdfr: z.string().nullish(), reuseBuilding: z.array(rainBuildingSchema).default([]), - chgBuilding: z.array(chgBuildingSchema).default([]) -}) + chgBuilding: z.array(chgBuildingSchema).default([]), +}); export type chgBuilding = { - bdstInfoSn?: number | null, - archChgPrmsnDt?: Date, - archChgArea?: string, - bdstChgNm?: string + bdstInfoSn?: number | null; + archChgPrmsnDt?: Date; + archChgArea?: string; + bdstChgNm?: string; rgtr?: string | null; mdfr?: string | null; -} -export type customRainBdst = z.infer +}; +export type customRainBdst = z.infer; export const upHeadList: TableUpperProps[] = [ { id: "cityText", title: "시도" }, @@ -66,12 +81,10 @@ export const upHeadList: TableUpperProps[] = [ const rainRes: customRainBdst[] = []; - export const selectClass = "w-full h-full !text-xl"; export type rainFacState = { rain: { - isInit: boolean; upHeadList: TableUpperProps[]; rainRes: customRainBdst[]; rainResCount: number; @@ -80,17 +93,15 @@ export type rainFacState = { type rainFacSActions = { initRain: (code: string | number) => void; getRainData: (pageNation: number, code: string | number) => void; - rainSearch: (txt: string, pageNation: number, code: string | number) => void; + rainSearch: (txt: string, pageNation: number, code: string) => void; rainBdstReg: (data: customRainBdst, code: string | number) => void; rainBdstUpdate: (data: customRainBdst, code: string | number) => void; - }; export type rainFacType = rainFacState & rainFacSActions; export const rainFacStateExport: rainFacState = { rain: { - isInit: false, rainRes: rainRes, rainResCount: 1, upHeadList: upHeadList, @@ -98,17 +109,23 @@ export const rainFacStateExport: rainFacState = { }; const initFetch = async (code: string | number) => { - // const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/1/10/${code}`); - const rainRes = await getFetchWithCount("wr", `/reuseFc/rainyInfoList/1/${rainRegSize}/${code}`); + const rainRes = await getFetchWithCount( + fetchType.WR, + `/reuseFc/rainyInfoList/1/${rainRegSize}/${code}` + ); return rainRes; }; export const rainFacActionsExport: (set: any) => rainFacSActions = ( set: any ) => { return { + // 빗물 이용시설 조회한다. getRainData: async (pageNation: number, code: string | number) => { try { - const rainRes = await getFetchWithCount("wr", `/reuseFc/rainyInfoList/${pageNation}/${rainRegSize}/${code}`); + const rainRes = await getFetchWithCount( + fetchType.WR, + `/reuseFc/rainyInfoList/${pageNation}/${rainRegSize}/${code}` + ); // 여기서 상태 업데이트 return set((state: rainFacState) => ({ @@ -117,16 +134,13 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state.rain, rainRes: rainRes.data, rainResCount: rainRes.count, - isInit: false, }, })); - } catch (e) { - console.log(e) - + console.log(e); } }, - + // 빗물 이용시설 조회한다. initRain: async (code: string | number) => { try { // 파라이터 수정 통합관리자 =0, 시관리자=시코드, 시군구 관리자= 시군구 코드 를 세번째 파라미터로 지정 / 건축물 서치가 있을경우 4번째 파라미터로 던지기 즉 1/20/42(서울시)/영현빌딩 이런식으로) @@ -138,49 +152,47 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state.rain, rainRes: rainRes.data, rainResCount: rainRes.count, - isInit: false, }, })); } catch (error) { console.log("error", error); } }, - rainSearch: async (txt: string, pageNation: number) => { + // 빗물 이용시설 조회한다. (건축물 이름을 포함하여) + rainSearch: async (txt: string, pageNation: number, code: string) => { try { - // const rainRes = await getFetch('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:'')) - const rainRes = await getFetchWithCount('wr', `/reuseFc/rainyInfoList/${pageNation}/${rainRegSize}/41` + (txt ? `/${txt}` : '')) - console.log("rainRes", rainRes) + const rainRes = await getFetchWithCount( + fetchType.WR, + `/reuseFc/rainyInfoList/${pageNation}/${rainRegSize}/${code}` + + (txt ? `/${txt}` : "") + ); + console.log("rainRes", rainRes); set((state: rainFacState) => { return { rain: { ...state.rain, rainRes: rainRes.data, rainResCount: rainRes.count, - isInit: false, }, }; - }) - } - catch (erTxt) { - console.log("error", erTxt) + }); + } catch (erTxt) { + console.log("error", erTxt); } }, + // 빗물 이용시설을 등록한다. rainBdstReg: async (data: customRainBdst, code: string | number) => { try { - const test = await makeRstr(data); const res = await postFectch("/reuseFc/rainyInfo", test); if (res.status === 200) { if (data.chgBuilding.length > 0) { - - const chPK = res?.data?.bdstInfoSn - const makeCh = res.data.chgBuilding.map((item: chgBuilding) => - ({ + const chPK = res?.data?.bdstInfoSn; + const makeCh = res.data.chgBuilding.map((item: chgBuilding) => ({ ...item, bdstInfoSn: chPK, - }) - ); + })); const chch = await postFectch("/reuseFc/chgBuilding", makeCh); if (chch.status === 200) { @@ -201,7 +213,6 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state.rain, rainRes: rainRes.data, rainResCount: rainRes.count, - isInit: false, }, })); } catch (e) { @@ -210,25 +221,20 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( } finally { } }, + // 빗물이용시설 시설에 대한 사항을 업데이트한다 rainBdstUpdate: async (data: customRainBdst, code: string | number) => { try { const chData = await makeMdfr(data); const res = await putFectch("/reuseFc/rainyInfo", chData); - console.log("res", res) - console.log("data", data) if (res.status === 200) { if (data.chgBuilding.length > 0) { const chPK = data?.bdstInfoSn; - console.log("chPK", chPK) - const makeCh = data.chgBuilding.map((item: chgBuilding) => - ({ + console.log("chPK", chPK); + const makeCh = data.chgBuilding.map((item: chgBuilding) => ({ ...item, bdstInfoSn: chPK, - }) - ); - console.log("makeCh", makeCh) + })); const chch = await postFectch("/reuseFc/chgBuilding", makeCh); - console.log("chch", chch) if (chch.status === 200) { toast.success("건축물 수정이 완료되었습니다."); @@ -242,10 +248,6 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( toast.error("건축물 수정이 완료되었습니다."); } - // } - // toast.success("수정이 완료되었습니다."); - - // } const rainRes = await initFetch(code); set((state: rainFacState) => ({ ...state, @@ -253,7 +255,6 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( ...state.rain, rainRes: rainRes.data, rainResCount: rainRes.count, - isInit: false, }, })); } catch (e) { @@ -261,7 +262,6 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = ( toast.error("수정시 오류가 발생하였습니다."); } finally { } - } - } -} - + }, + }; +}; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx index 42e771292..7fa3595fc 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx @@ -8,18 +8,21 @@ import { makeMdfr, makeRstr } from "../bdstReg"; import { baseReuseBuildingSchema, chgBuildingSchema, validationMessages } from "../rainReg/type"; + + +/** + * 중수도시설 등록 (스토어) + * 재이용시설 등록 - 중수도시설 등록 + * 중수도시설에서 사용하는 api 및 타입 등을 관리한다. + * */ export const rswtRegSize =15; const rswtrObjSchema = z.object({ bdstRuseFcltSn: z.number().nullish(), - //wtrUsqty: z.number({ required_error: validationMessages.required("물사용량(m³)") }).positive({ message: validationMessages.required("물사용량(m³)") }), - //oblgTrgtWtrUsqty: z.number().nullish().default(0), orgwtKndCd: z.string({ required_error: validationMessages.requiredSelect("원수 종류") }).min(1, { message: validationMessages.requiredSelect("원수 종류") }), filtrTrtmfctCpct: z.number().nullish(), filtrTrtmfctProcs: z.string({ required_error: validationMessages.required("주요처리공정") }).min(1, { message: validationMessages.required("주요처리공정") }), filtrTrtmfctUsgCd: z.string().default("").nullish(), rswtrUsqty: z.number().default(0), - //altUswtrUtztnYn: z.enum(["Y", "N"]).nullish(), //안쓰는값 -// altUswtrKndCd: z.string().default("").nullish(), //안쓰는값 altUswtrUtztnQnt: z.number().default(0), //안쓰는값 altUswtrIdntyMthdCd: z.string().default("").nullish(), //안쓰는값 rgtr: z.string().nullish().default(null), @@ -56,7 +59,6 @@ const rswtRes: customRswtBdst[] = []; export type rswtFacState = { rswt: { - isInit: boolean; upHeadList: TableUpperProps[]; rswtRes: customRswtBdst[]; rswtResCount: number; @@ -78,7 +80,6 @@ export type rswtFacType = rswtFacState & rswtFacSActions; export const rswtFacStateExport: rswtFacState = { rswt: { - isInit: false, upHeadList: upHeadList, rswtRes: rswtRes, rswtResCount: 1, @@ -93,6 +94,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( set: any ) => { return { + // 중수도 시설을 조회한다 (시설이름 포함) rswtBdstSearch: async ( txt: string, pageNation: number, @@ -111,7 +113,6 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state.rswt, rswtRes: rswtRes.data, rswtResCount: rswtRes.count, - isInit: false, }, }; }); @@ -119,6 +120,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( console.log("error", erTxt); } }, + // 중수도 시설을 조회한다 getRswtBdstData: async (pageNation: number, code: string | number) => { try { const rswtRes = await getFetchWithCount( @@ -133,13 +135,13 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state.rswt, rswtRes: rswtRes.data, rswtResCount: rswtRes.count, - isInit: false, }, })); } catch (e) { console.log(e); } }, + // 중수도 시설을 조회한다 initRswt: async (code: string | number) => { try { const rswtRes = await initFetch(code); @@ -149,13 +151,13 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state.rswt, rswtRes: rswtRes.data, rswtResCount: rswtRes.count, - isInit: false, }, })); } catch (error) { console.log(error); } }, + // 중수도 시설에 대한 사항을 업데이트한다 rswtBdstUpdate: async (data: customRswtBdst, code: string | number) => { try { const chData = await makeMdfr(data); @@ -189,7 +191,6 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state.rswt, rswtRes: rswtRes.data, rswtResCount: rswtRes.count, - isInit: false, }, })); @@ -199,6 +200,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( } finally { } }, + // 중수도 시설을 등록한다. rswtBdstReg: async (data: customRswtBdst, code: string | number) => { try { const chData = await makeRstr(data); @@ -235,7 +237,6 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = ( ...state.rswt, rswtRes: rswtRes.data, rswtResCount: rswtRes.count, - isInit: false, }, })); } catch (e) { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx index 60b726e2b..a1d1193b2 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx @@ -461,7 +461,7 @@ export const ruseGuranteeHeadListExport: TableUpperProps[] = [ { id: "crmty", title: "색도(도)", visible: true }, { id: "tn", title: "총질소(mg/L)", visible: true }, { id: "tph", title: "총인(mg/L)", visible: true }, - { id: "ph", title: "수소이온농도(ph)", visible: true }, + { id: "ph", title: "수소이온농도(pH)", visible: true }, { id: "clIonQnt", title: "염화물(mg/L)", visible: true }, { id: "cdtnv", title: "전기전도도(μs/cm)​", visible: true }, ]; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index f14101626..28743ab26 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -1,4 +1,7 @@ -import type { CommonTableProps, TableUpperProps } from "@/app/store/common/type/header"; +import type { + CommonTableProps, + TableUpperProps, +} from "@/app/store/common/type/header"; import type { FcPrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import type { ReturnType } from "@common/business_components/ui"; @@ -8,9 +11,23 @@ import type { customPbnst, pubHasuType } from "../../fcltReg/pbnstReg/type"; import { controlHeadView } from "../rainSttn"; import type { sttnHeadListType } from "../rainSttn/headList"; import { excelPbnstSttnParsing } from "./excel"; -import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList"; +import { + pbnSttHeadListExport, + pbnstSttNodeListExport, + ruseDmdHeadListExport, + ruseFcltHeadListExport, + ruseFcltNodeListExport, + ruseGuranteeHeadListExport, + rusePplHeadListExport, + ruseSplyHeadListExport, +} from "./headList"; import type { WaterReuseFacility } from "./type"; +/** + * 하수재이용시설 현황 (스토어) + * 하수재이용시설 등록 - 하수재이용시설 현황 + * 빗물이용시설에서 사용하는 api 및 타입 등을 관리한다. + * */ const pbnstSttHeadList = pbnSttHeadListExport; const pbnstSttNodeList = pbnstSttNodeListExport; @@ -21,15 +38,15 @@ export type pbnstSttnState = { pbnstSttHeadList: CommonTableProps[]; pbnstSttNodeList: CommonTableProps[]; pbnstDetail: customPbnst; - ruseFcltNodeList: TableUpperProps[] - ruseSplyHeadList: TableUpperProps[] - rusePplHeadList: TableUpperProps[] - ruseGuranteeHeadList: TableUpperProps[] - ruseDmdHeadList: TableUpperProps[] - ruseFcltHeadList: TableUpperProps[] + ruseFcltNodeList: TableUpperProps[]; + ruseSplyHeadList: TableUpperProps[]; + rusePplHeadList: TableUpperProps[]; + ruseGuranteeHeadList: TableUpperProps[]; + ruseDmdHeadList: TableUpperProps[]; + ruseFcltHeadList: TableUpperProps[]; pbnstSttnResCount: number; excelList: []; - fclts: string[] + fclts: string[]; isInit: boolean; }; }; @@ -97,49 +114,65 @@ export const hasuListFetch = async ( ) => { let url = ``; let filteredFclt = flcts; - const filterData = reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue + const filterData = + reurnValue.sigunValue !== "0" + ? reurnValue.sigunValue + : reurnValue.sidoValue; - - if(filterData !== '0') - filteredFclt= flcts.filter((fclt: string) => { - return filterData.length==2 ?fclt.slice(0, 2) === filterData:fclt.slice(0, 5) === filterData - }) + if (filterData !== "0") + filteredFclt = flcts.filter((fclt: string) => { + return filterData.length == 2 + ? fclt.slice(0, 2) === filterData + : fclt.slice(0, 5) === filterData; + }); if (reurnValue.partValue === "A") { url += `${reurnValue.partValue}/${ // reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue - reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue - }/0/1/SW` - - if(filterData !== '0') - filteredFclt= flcts.filter((fclt: string) => { - return filterData.length==2 ?fclt.slice(0, 2) === filterData:fclt.slice(0, 5) === filterData - }) + reurnValue.sigunValue !== "0" + ? reurnValue.sigunValue + : reurnValue.sidoValue + }/0/1/SW`; + + if (filterData !== "0") + filteredFclt = flcts.filter((fclt: string) => { + return filterData.length == 2 + ? fclt.slice(0, 2) === filterData + : fclt.slice(0, 5) === filterData; + }); } else if (reurnValue.partValue === "R") { - url += `${reurnValue.partValue}/${reurnValue.regionValue - ? reurnValue.regionValue - : reurnValue.unitWaterShedValue - ? reurnValue.unitWaterShedValue - : reurnValue.middleRegionValue - }/0/1/SW` - } else if (reurnValue.partValue === 'G') { - url += `${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW` - if(filterData !== '0') - filteredFclt= flcts.filter((fclt: string) => { - return filterData.length==2 ?fclt.slice(0, 2) === filterData:fclt.slice(0, 5) === filterData - }) - + url += `${reurnValue.partValue}/${ + reurnValue.regionValue + ? reurnValue.regionValue + : reurnValue.unitWaterShedValue + ? reurnValue.unitWaterShedValue + : reurnValue.middleRegionValue + }/0/1/SW`; + } else if (reurnValue.partValue === "G") { + url += `${reurnValue.envPartValue}/${reurnValue.sigunValue !== "0" ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW`; + if (filterData !== "0") + filteredFclt = flcts.filter((fclt: string) => { + return filterData.length == 2 + ? fclt.slice(0, 2) === filterData + : fclt.slice(0, 5) === filterData; + }); } else { - url += `A/0/0/1/SW` + url += `A/0/0/1/SW`; } if (searchNm && searchNm?.length > 0) { - url += "/" + searchNm + url += "/" + searchNm; } - const pbnList = await postFectch( `/prcsFclt/ruseInfo/1/${filteredFclt.length}/`+url, filteredFclt, fetchType.COMMON); + const pbnList = await postFectch( + `/prcsFclt/ruseInfo/1/${filteredFclt.length}/` + url, + filteredFclt, + fetchType.COMMON + ); - - const checkRuseFcltList = searchNm && searchNm?.length > 0?pbnList.data.map((item)=> item.bscFctCd ):filteredFclt + const checkRuseFcltList = + searchNm && searchNm?.length > 0 + ? pbnList.data.map((item) => item.bscFctCd) + : filteredFclt; const getRuseList = await postFectch( `/reuseFc/pubDetailList/${year}/${filterData}/${page}/${total}`, checkRuseFcltList, @@ -147,9 +180,8 @@ export const hasuListFetch = async ( ); const checkWrRegListRes = getRuseList.data; - - const data: WaterReuseFacility[] = checkWrRegListRes.map( - (item: FcPrfType) => { + const data: WaterReuseFacility[] = checkWrRegListRes + .map((item: FcPrfType) => { const findData = pbnList.data.find( (fclt: pubHasuType) => fclt.bscFctCd === item.pbnstRuseFcltId.substring(0, 11) @@ -182,57 +214,54 @@ export const hasuListFetch = async ( { total: 0, inUsage: 0, outUsage: 0 } ); return { - rvbsn: findData?.rvbsn || '-', - lgbsn: findData?.lgbsn || '-', - mdmbsn: findData?.mdmbsn || '-', - rgnNm: findData?.rgnNm || '-', - sido: findData?.sido || '-', - gugun: findData?.gugun || '-', - bscFctNm: findData?.bscFctNm || '-', - efflWqltStndrdNm: findData?.efflWqltStndrdNm || '-', + rvbsn: findData?.rvbsn || "-", + lgbsn: findData?.lgbsn || "-", + mdmbsn: findData?.mdmbsn || "-", + rgnNm: findData?.rgnNm || "-", + sido: findData?.sido || "-", + gugun: findData?.gugun || "-", + bscFctNm: findData?.bscFctNm || "-", + efflWqltStndrdNm: findData?.efflWqltStndrdNm || "-", fctCpc: Number(findData?.fctCpc) || 0, tel: findData?.tel ?? "-", - ruseUtztnFcltNm: item?.ruseUtztnFcltNm || '-', - fcltCpct: item?.fcltCpct || '-', - splyExtraCpct: item?.splyExtraCpct || '-', - ruseCpct: item?.ruseCpct || '-', - pbnstRuseFcltId: item.pbnstRuseFcltId || '-', + ruseUtztnFcltNm: item?.ruseUtztnFcltNm || "-", + fcltCpct: item?.fcltCpct || "-", + splyExtraCpct: item?.splyExtraCpct || "-", + ruseCpct: item?.ruseCpct || "-", + pbnstRuseFcltId: item.pbnstRuseFcltId || "-", usageTotal: usage?.total, inUsage: usage?.inUsage, outUsage: usage?.outUsage, - operMthd: item.operList[0]?.operMthd || '-', + operMthd: item.operList[0]?.operMthd || "-", rprtvBzenty: item.operList[0]?.rprtvBzenty, bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "", endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "", - searchNm: findData?.bscFctNm || '-', - searchPk: findData?.bscFctCd || '-', - prfList: item?.prfList ?? [] + searchNm: findData?.bscFctNm || "-", + searchPk: findData?.bscFctCd || "-", + prfList: item?.prfList ?? [], }; } + }) + .filter(Boolean); - } - ).filter(Boolean); - - - - - return {data:data, count:getRuseList.count}; + return { data: data, count: getRuseList.count }; }; export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( set: any ) => { return { + //등록된 하수재이용시설을 조회한다. getFlcts: async () => { - const fclts = await getFetch(fetchType.WR, '/reuseFc/pubFc') - + const fclts = await getFetch(fetchType.WR, "/reuseFc/pubFc"); return set((state: pbnstSttnState) => ({ pbnstSttn: { ...state.pbnstSttn, - fclts: fclts + fclts: fclts, }, })); }, + //테이블 헤드를 조정한다. pbnstChSttnHead: async ( headList: z.infer ): Promise => { @@ -246,6 +275,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }, })); }, + //하수처리시설을 조회하여 하수재이용시설을 확인한다. pbnstSttnSearch: async ( isExcel: boolean, page: string, @@ -256,14 +286,13 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( fclts: string[] ) => { try { - const pbnstSttnRes = await hasuListFetch( page, total, reurnValue, searchNm, year, - fclts, + fclts ); // if (Number(total) > 9000) { @@ -279,14 +308,13 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }; }); } else { - set((state: pbnstSttnState) => { return { ...state, pbnstSttn: { ...state.pbnstSttn, pbnstSttnRes: pbnstSttnRes.data, - pbnstSttnResCount: pbnstSttnRes.count + pbnstSttnResCount: pbnstSttnRes.count, // isInit: false, }, }; @@ -296,6 +324,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log("error", erTxt); } }, + //하수처리시설을 조회하여 하수재이용시설을 조회한다. pbnSttnInit: async ( page: string, total: string, @@ -313,7 +342,6 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( fclts ); - set((state: pbnstSttnState) => { return { ...state, @@ -322,7 +350,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( pbnstSttnRes: pbnstSttnRes.data, pbnstSttnResCount: pbnstSttnRes.count, isInit: false, - pbnstDetail: {} as customPbnst + pbnstDetail: {} as customPbnst, }, }; }); @@ -330,22 +358,29 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log("error", erTxt); } }, + // 팝업에 있는 데이터를 초기화한다. resetPbnstDetail: async () => { set((state: pbnstSttnState) => { return { ...state, pbnstSttn: { ...state.pbnstSttn, - pbnstDetail: {} as customPbnst + pbnstDetail: {} as customPbnst, }, }; - }) + }); }, + //하수처리시설을 조회하여 하수재이용시설을 조회한다. getPbnStnDetail: async (pbnstRuseFcltId: string) => { try { - let pbnstDetail = await getFetch("wr", `/reuseFc/pubFc/${pbnstRuseFcltId}`); + let pbnstDetail = await getFetch( + "wr", + `/reuseFc/pubFc/${pbnstRuseFcltId}` + ); if (pbnstDetail.length >= 0) { - pbnstDetail = pbnstDetail.find((item: customPbnst) => item.pbnstRuseFcltId === pbnstRuseFcltId) + pbnstDetail = pbnstDetail.find( + (item: customPbnst) => item.pbnstRuseFcltId === pbnstRuseFcltId + ); } set((state: pbnstSttnState) => { return { @@ -360,6 +395,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log(errorHasu); } }, + //하수재이용시설 실적 현황 에서 사용하는 조회 pbnNmSearch: async ( page: string, total: string, @@ -369,7 +405,6 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( flcts: string[] ) => { try { - const pbnstSttnRes = await hasuListFetch( page, total, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx index 65f02e26b..989a73071 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/excel.tsx @@ -1,22 +1,18 @@ import type { SelectDataType } from "@common/business_components/ui"; import type { customRainBdst } from "../../fcltReg/rainReg"; -import { bdstUsgCd } from "@/app/store/common/code/basicCode"; -//TODO: 공통코드시 삭제되니 수정 해야됨 export const excelRainSttnParsing = ( excel: { data: customRainBdst[] }, - sidoCode: SelectDataType[], - sggCode: SelectDataType[] + code: Record ): string[][] => { const excelExportData: string[][] = []; excel.data.forEach((item) => { - console.log("item", item) excelExportData.push([ - sidoCode.find((sido) => sido.val === item.ctpvCd?.toString())?.text ?? "", - sggCode.find((sgg) => sgg.val === item.sggCd?.toString())?.text ?? "", + code?.cityCd?.find((sido) => sido.val === item.ctpvCd?.toString())?.text ?? "", + code?.sggCd?.find((sgg) => sgg.val === item.sggCd?.toString())?.text ?? "", item.bdstNm ?? "", item.daddr ?? "", - bdstUsgCd.find((cd) => cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 + code?.bdstUsgCd?.find((cd) => cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 String(item.frstArchPrmsnDt ?? ""), String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]), String(item.chgBuilding.length > 0 ? "Y" : "N"), diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx index e78183cc5..9ed008ac5 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx @@ -126,7 +126,7 @@ export const rainSttHeadListExport: z.infer = [ visible: true, }, { - id: "grntchBdstCertGrd", + id: "grntchBdstCertGrdText", title: "녹색건축물인증등급", visible: true, }, @@ -405,7 +405,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "grntchBdstCertGrd", + id: "grntchBdstCertGrdText", title: "인증등급", upName: "grntchBdstCert", visible: true, @@ -445,7 +445,7 @@ export const rainSttnDetailNodeListExport:CommonTableProps[] = [ rowSpan: 1, colSpan: 4 }, - { id: "ph", title: "PH", + { id: "ph", title: "pH", visible: true, row: 2, rowSpan: 1, @@ -524,7 +524,7 @@ export const rainSttnDetailHeadListExport:CommonTableProps[] = [ colSpan: 1 }, - { id: "ph", title: "PH", + { id: "ph", title: "pH", visible: true, row: 1, rowSpan: 1, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx index 34629f259..e57603fe3 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx @@ -102,12 +102,8 @@ export type rainSttnState = { }; }; type rainSttnActions = { - rainSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void - rainSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + rainSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record ) => void + rainSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record) => void; rainChSttnHead: ( headList: z.infer, ) => void; @@ -134,9 +130,7 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( set: any ) => { return { - rainSttnInit: async (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { + rainSttnInit: async (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record) => { try { const rainSttnRes = await getFetchWithCount( @@ -148,7 +142,7 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rainExcel = excelRainSttnParsing(rainSttnRes, sidoCode, sggCode); + const rainExcel = excelRainSttnParsing(rainSttnRes, code); set((state: rainSttnState) => { return { ...state, @@ -174,9 +168,7 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( console.log(e) } }, - rainSttnSearch: async (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { + rainSttnSearch: async (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record) => { try { const rainSttnRes = await getFetchWithCount( fetchType.WR, @@ -187,7 +179,7 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rainExcel = excelRainSttnParsing(rainSttnRes, sidoCode, sggCode); + const rainExcel = excelRainSttnParsing(rainSttnRes,code); set((state: rainSttnState) => { return { ...state, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx index b3d3835c2..46a2f0e61 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/excel.tsx @@ -1,21 +1,20 @@ -import { bdstUsgCd } from "@/app/store/common/code/basicCode"; import type { SelectDataType } from "@common/business_components/ui"; import type { customRswtBdst } from "../../fcltReg/rswtReg"; + export const excelRSwtSttnParsing = ( excel: { data: customRswtBdst[] }, - sidoCode: SelectDataType[], - sggCode: SelectDataType[] + code: Record ): string[][] => { + const excelExportData: string[][] = []; excel.data.forEach((item) => { - console.log("item", item) excelExportData.push([ - sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", - sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", + code.cityCd?.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "", + code.sggCd?.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "", item.bdstNm ?? "", item.daddr ?? "", - bdstUsgCd.find((cd)=> cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 + code?.bdstUsgCd?.find((cd)=> cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도 String(item.frstArchPrmsnDt ?? ""), String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]), // String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량 diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx index e4bcce08a..ec772610d 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx @@ -119,7 +119,7 @@ export const rswtSttHeadListExport: z.infer = [ visible: true, }, { - id: "grntchBdstCertGrd", + id: "grntchBdstCertGrdText", title: "녹색건축물인증등급", visible: true, }, @@ -379,7 +379,7 @@ export const rswtSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "grntchBdstCertGrd", + id: "grntchBdstCertGrdText", title: "인증등급", upName: "grntchBdstCert", visible: true, diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index 1d4617442..47444ce32 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -30,12 +30,8 @@ export type rswtSttnState = { }; type rswtSttnActions = { - rswtSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; - rswtSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => void; + rswtSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record) => void; + rswtSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record) => void; rswtChSttnHead: ( headList: z.infer, ) => void; @@ -60,9 +56,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( set: any ) => { return { - rswtSttnInit: async (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { + rswtSttnInit: async (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record) => { try { const rswtSttnRes = await getFetchWithCount( fetchType.WR, @@ -73,17 +67,17 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); - set((state: rswtSttnState) => { - return { - ...state, - rswtSttn: { - ...state.rswtSttn, - excelList: rswtExcel, - }, - }; - }); - } else + const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, code); + set((state: rswtSttnState) => { + return { + ...state, + rswtSttn: { + ...state.rswtSttn, + excelList: rswtExcel, + }, + }; + }); + } set((state: rswtSttnState) => { return { @@ -100,9 +94,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( console.log(e) } }, - rswtSttnSearch: async (isExcel: boolean, page: number, total: number, con: string, txt: string, - sidoCode: SelectDataType[], - sggCode: SelectDataType[]) => { + rswtSttnSearch: async (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record) => { try { const rswtSttnRes = await getFetchWithCount( fetchType.WR, @@ -113,7 +105,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = ( (txt ? `/${txt}` : "") ); if (isExcel) { - const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode); + const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, code); set((state: rswtSttnState) => { return { ...state, diff --git a/apps/wr/app/store/stats/rswtStat/excel.tsx b/apps/wr/app/store/stats/rswtStat/excel.tsx index 00935b8fb..4bd698ad0 100644 --- a/apps/wr/app/store/stats/rswtStat/excel.tsx +++ b/apps/wr/app/store/stats/rswtStat/excel.tsx @@ -1,7 +1,10 @@ -import type { RswtStatProps } from "."; -import { bdstUsgCd } from "../../common/code/basicCode"; +import type { SelectDataType } from "@common/business_components/ui"; +import type { RswtStatProps } from "."; -export const excelRswtStat = (excelList:RswtStatProps[]) : (string | number)[][] => { +export const excelRswtStat = (excelList: RswtStatProps[], rswtBdstType : SelectDataType[] ) : (string | number)[][] => { + + + console.log('bdstUsgCd ', rswtBdstType) const excelData: (string | number)[][] = []; excelList.forEach((item) => { excelData.push([ @@ -15,7 +18,7 @@ export const excelRswtStat = (excelList:RswtStatProps[]) : (string | number)[][] String(item.bdstNm) ?? "", //건축물용도코드(빈칸) //String(item.bdstUsgCd) ?? "", - bdstUsgCd.find((cd)=> cd.val === item.bdstUsgCd.toString())?.text ?? "", //건축물용도 + rswtBdstType?.find((cd)=> cd.val === item.bdstUsgCd.toString())?.text ?? "", //건축물용도 //주소 String(item.daddr) ?? "", //법적의무대상여부 diff --git a/apps/wr/app/store/stats/rswtStat/index.tsx b/apps/wr/app/store/stats/rswtStat/index.tsx index 89c4089c0..bd9a9c8e0 100644 --- a/apps/wr/app/store/stats/rswtStat/index.tsx +++ b/apps/wr/app/store/stats/rswtStat/index.tsx @@ -2,6 +2,7 @@ import { fetchType, getFetch } from "@/components/lib/api"; import type { TableUpperProps } from "../../common/type/header"; import { rswtStatHeadListExport } from "./headList"; import { excelRswtStat } from "./excel"; +import type { SelectDataType } from "@common/business_components/ui"; export type RswtStatProps = { cityText: string //시도명 @@ -38,7 +39,7 @@ export type GuideStatProps = { } type rswtStatActions = { - searchRswtStatList: (year: string, city: { val: string; text: string }[]) => void; + searchRswtStatList: (year: string, city: SelectDataType[],bdstUsgCd: SelectDataType[] ) => void; } export type ExcelType = { @@ -72,7 +73,7 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = ( set: any ) => { return { - searchRswtStatList: async (year: string, city: { val: string; text: string }[]) => { + searchRswtStatList: async (year: string, city: SelectDataType[] , rswtBdstType:SelectDataType[]) => { const res = await getFetch(fetchType.WR, `/reuseChk/reuseWater/stat/${year}`) const data = res.filter(item => { const code = item.ctpvCd.trim(); @@ -198,7 +199,7 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = ( utztnUsgCd: utztnUsgArray.join(', '), }) }); - const excelDetailData = excelRswtStat(rswtDetailList); + const excelDetailData = excelRswtStat(rswtDetailList,rswtBdstType); set((state: rswtStatState) => ({ rswtStat: { ...state.rswtStat, diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index e19ec2216..fbb3434d9 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -3,6 +3,7 @@ import { codeActionExport, comCodeStateExport, getCityCd, + getCommonUpCd, getEnvPartCd, getMiddleRegionCd, getRegionCd, @@ -334,13 +335,14 @@ export const StoreZus = ( ...dmMapState, } ) => { - return createStore()((set) => { + return createStore()((set ,get) => { getSggCd(set); getCityCd(set); getRegionCd(set); getMiddleRegionCd(set); getUnitWaterShedCd(set); getEnvPartCd(set); + getCommonUpCd(set) return { ...initState, ...comFcltSearchAction(set), @@ -349,7 +351,7 @@ export const StoreZus = ( ...rswtFacActionsExport(set), ...matDmdActionsExport(set), ...htdflFacActionsExport(set), - ...codeActionExport(set), + ...codeActionExport(set,get), ...bdstActionsExport(set), ...rainChkgdnActionsExport(set), ...rswtChkgdnActionsExport(set), @@ -369,7 +371,7 @@ export const StoreZus = ( ...ruseCaseActionsExport(set), ...rainStatActionsExport(set), ...rswtStatActionsExport(set), - ...authActionsExport(set), + ...authActionsExport(set,get), ...commonMapActionsExport(set), ...pbnMapActionsExport(set), ...rainMapActionsExport(set), diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index bee5e093d..1a66802f5 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -10,6 +10,7 @@ import { } from "@common/components/ui"; import moment from "moment"; import { + codeToText, formatCommaNumber, formatYyyymmdd, handleCommaNumberChange @@ -73,23 +74,23 @@ export const rswtChkTableData = (chkData: rswtChkZodType[]) => { let flatRswtChk = {}; const findGuide = root.guideDetails.find( (guide) => guide.utztnUsgCd === detail.utztnUsgCd - ); + ) const findPoluttion = root.rswtrPollutions.find( (polution) => polution.utztnUsgCd === detail.utztnUsgCd ); - const operMngCd = root?.reuseBuilding.operMngCd; flatRswtChk = { ...root, ...detail, ...findGuide, ...findPoluttion, ...flatRswtChk, - operMngCd: operMngCd, + utztnUsgCdText: codeToText(detail.utztnUsgCd, 'dmdUszCd'), }; makeRswtData.push(flatRswtChk); }); }); } + return makeRswtData; }; diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index 042e74aa6..a99dd8db8 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -1,4 +1,4 @@ -import type { comCodeState } from "@/app/store/common/code"; +import { lwCds, type comCodeState } from "@/app/store/common/code"; import { filePickedBlob, filePickedBlobArray, @@ -33,12 +33,15 @@ export const getCity = (val: string, sggCd: SelectDataType[]) => { // cd text 넣기 export const tableData = (data: any, code: comCodeState) => { const chCode = code.code; - return data?.map( (item: { sggCd: string; ctpvCd: string; - reuseBuilding: { lawTrgtYn: any; bdstUsgCd: any }[]; + reuseBuilding: { + lawTrgtYn: string; + bdstUsgCd: string; + grntchBdstCertGrd: string; + }[]; }) => { let returnData = {}; const sggText = chCode.sggCd.find( @@ -48,16 +51,23 @@ export const tableData = (data: any, code: comCodeState) => { (cd) => cd.val === String(item.ctpvCd).trim() )?.text; if (item?.reuseBuilding?.length > 0) { - const bdsgUsgText = chCode.bdstUsgCd.find( - (cd) => Number(cd.val) === item?.reuseBuilding[0]?.bdstUsgCd + const bdsgUsgText = chCode?.bdstTotalUsgType?.find( + (cd) => cd.val === item?.reuseBuilding[0]?.bdstUsgCd )?.text; + const lawTrgtYn = item?.reuseBuilding[0]?.lawTrgtYn; + + const grntchBdstCertGrdText = chCode?.bdstGrntchClass?.find( + (cd) => cd.val === item?.reuseBuilding[0]?.grntchBdstCertGrd + )?.text; + returnData = { ...item, sggText: sggText ?? "없음", cityText: cityText ?? "없음", bdsgUsgText: bdsgUsgText, lawTrgtYn: lawTrgtYn, + grntchBdstCertGrdText: grntchBdstCertGrdText, }; } else { returnData = { @@ -152,13 +162,13 @@ export const formatCommaNumber = ( }; //내가 쓰는 값이 숫자이냐 아니냐 -export const isNumeric =(value: string) => { - if(value&&value.length>0){ +export const isNumeric = (value: string) => { + if (value && value.length > 0) { return value?.trim() !== "" && !isNaN(Number(value)); - }else{ - return false + } else { + return false; } -} +}; export const getCityOrSgg = (ref: RefObject) => { let con; @@ -211,11 +221,15 @@ export const formatPhoneNumber = (tel: string) => { } }; -export const confirmToast = (content: string, saveFunc: () => void, contentClass?:string) => { +export const confirmToast = ( + content: string, + saveFunc: () => void, + contentClass?: string +) => { toast( (t) => ( -
{content}
+
{content}
) : ( @@ -256,7 +279,8 @@ export default function ChkgdModal({ type, obj, setIsModal, readonly }: { type:

{type === "RNB" - ? `시설명 : (${obj.bdstNm})` : `시설명 : (${obj.building.bdstNm})`} + ? `시설명 : (${obj.bdstNm})` + : `시설명 : (${obj.building.bdstNm})`}

@@ -269,7 +293,11 @@ export default function ChkgdModal({ type, obj, setIsModal, readonly }: { type: { setChGuidData(data); @@ -284,7 +312,11 @@ export default function ChkgdModal({ type, obj, setIsModal, readonly }: { type: { setChGuidData(data); diff --git a/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx b/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx index 427323c1e..8f2446099 100644 --- a/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx +++ b/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx @@ -162,7 +162,7 @@ export default function PbnPrfExcelModal({ setFiles={(files: File[] | null) => { if (files) setFiles(files); }} - fileTypes="xlsx" + fileTypes=".xlsx" maxFiles={1} diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index a692553af..fb2754050 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -18,6 +18,7 @@ import { } from "@common/business_components"; import { Button, Input, Label } from "@common/components"; import { useEffect, useState } from "react"; +import toast from "react-hot-toast"; export type objSearchType = { sgg: string | number; @@ -43,11 +44,11 @@ export function BdstReg({ setIsModal, isModal, }: BdstRegProps) { - const { code, bdst, findBdst } = useWrStore((state) => { + const { code, bdst, auth, findBdst } = useWrStore((state) => { return state; }); - const { userSiSggCd } = code; + const { laeSeCd } = auth; const [bdstTable, setBdstTable] = useState(); const [bdstForm, setBdstForm] = useState( @@ -68,7 +69,12 @@ export function BdstReg({ data = objSearch.sgg; } //RNB(빗물), RST(중수도), HTB(온배수) - findBdst(String(data), searchTxt || "", moType); + if(data){ + + findBdst(String(data), searchTxt || "", moType); + }else{ + toast.error("시도 또는 시군구를 선택하여 주십시오."); + } }; useEffect(() => { @@ -88,29 +94,40 @@ export function BdstReg({ }, [bdst]); useEffect(() => { - if (userSiSggCd.length === 2 && code.cityCd.length > 0) { - const city = code.cityCd.filter((item) => item.val === userSiSggCd); - const sgg = code.sggCd.filter( - (item) => item.val.slice(0, 2) === userSiSggCd - ); - sgg.unshift({ text: "전체", val: "0" }); + let city = [] as SelectDataType[]; + if (laeSeCd.length === 2 && code.cityCd.length > 0) { + city = code.cityCd.filter((item) => item.val === laeSeCd); setUserCityCd(city); // Fix: Ensure city is of type SelectDataType[] - setObjSearch({ ...objSearch, city: String(city[0]?.val) }); - setUserSggCd(sgg); } else if ( - userSiSggCd.length === 5 && + laeSeCd.length === 5 && code.cityCd.length > 0 && code.sggCd.length > 0 ) { - const city = code.cityCd.filter( - (item) => item.val === userSiSggCd.slice(0, 2) - ); + city = code.cityCd.filter((item) => item.val === laeSeCd.slice(0, 2)); setUserCityCd(city); - const sgg = code.sggCd.filter((item) => item.val === userSiSggCd); - setUserSggCd(sgg); - setObjSearch({ city: String(city[0]?.val), sgg: String(sgg[0]?.val) }); + } else if ( + laeSeCd === "0" && + code.cityCd.length > 0 && + code.sggCd.length > 0 + ) { + setUserCityCd(code.cityCd); } - }, [userSiSggCd, code.cityCd, code.sggCd]); + if (city.length > 0) + setObjSearch({ ...objSearch, city: Number(city[0]?.val) ?? "0" }); + }, [laeSeCd, code.cityCd, code.sggCd]); + + useEffect(() => { + const city = String(objSearch.city); + if (city === "0") { + setUserSggCd([{ text: "전체", val: "0" }]); + setObjSearch({ ...objSearch, sgg: "0" }); + } else if (city.length === 2) { + const sgg = code.sggCd.filter((item) => item.val.slice(0, 2) === city); + //sgg.unshift({ text: "전체", val: "0" }); + setUserSggCd(sgg); + setObjSearch({ ...objSearch, sgg: Number(sgg[0]?.val) }); + } + }, [objSearch.city]); const tableClick: (val: number | undefined, headId: string) => void = ( val @@ -133,21 +150,23 @@ export function BdstReg({ className="col-span-3 h-full" label={"시도"} selectClass={selectClass} + key={`city-${String(objSearch.city)}`} selectArray={useCityCd} onSelectValue={(val) => { - setObjSearch({ ...objSearch, city: String(val) }); + setObjSearch({ ...objSearch, city: Number(val) }); }} - value={objSearch.city || useCityCd[0]?.val} + value={objSearch.city ?? useCityCd[0]?.val} > { - if (val) setObjSearch({ ...objSearch, sgg: String(val) }); + if (val) setObjSearch({ ...objSearch, sgg: Number(val) }); }} - value={objSearch.sgg || useSggCd[0]?.val} + value={objSearch.sgg ?? useSggCd[0]?.val} > {" "} @@ -197,35 +216,35 @@ export function BdstReg({
-
- {moType === "RNB" ? ( - - ) : moType === "RST" ? ( - { - if (setIsModal && open) { - setIsModal(open); - } - }} - > - ) : ( - { - if (setIsModal && open) { - setIsModal(open); - } - }} - > - )} -
+
+ {moType === "RNB" ? ( + + ) : moType === "RST" ? ( + { + if (setIsModal && open) { + setIsModal(open); + } + }} + > + ) : ( + { + if (setIsModal && open) { + setIsModal(open); + } + }} + > + )} +
diff --git a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx index 6fc2c0632..8727f037e 100644 --- a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx @@ -4,12 +4,11 @@ import { useWrStore } from "@/app/store"; import type { TableUpperProps } from "@/app/store/common/type/header"; import { rainPageSize, type rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import { tableData } from "@/components/lib/func/commom"; +import { codeToText, tableData } from "@/components/lib/func/commom"; import { chRowspanTable, rainChkTableData } from "@/components/lib/func/TableData"; -import LoadingOverlay from "@common/business_components/ui/loadingBar"; import UiPageNations from "@common/business_components/ui/table/uiPageNations"; import { Table, @@ -89,15 +88,18 @@ export default function RainChkgdTable({ } ) }) + return { ...item, ...bud[0], + utztnUsgCdText: codeToText(item.guideDetails[0].utztnUsgCd, 'dmdUszCd'), + oilqMeasMthdText:codeToText(item.oilqMeasMthd, 'rainFcltFlowRate'), + operMngCdText:codeToText(item.operMngCd.trim(), 'rainRswtMng'), rainyDetails:rainyDetails, rowspan: item.rainyDetails?.length, }; }); - console.log('rainChg ', rainChg) setMakeTableData(rainChkTableData(rainChg)); } else { setMakeTableData([]); @@ -153,7 +155,7 @@ export default function RainChkgdTable({ setUpRaintDetail(updateTableData as rainChkZodType[]); - } + } else setUpRaintDetail(selectedData); }, [makeTableData, selectedIds]); useEffect(() => { @@ -188,7 +190,6 @@ export default function RainChkgdTable({ return ( <> - {headMakeprfmnc( diff --git a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx index aa74ad2c2..e931cf706 100644 --- a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx @@ -13,7 +13,6 @@ import { chRowspanTable, rswtChkTableData, } from "@/components/lib/func/TableData"; -import LoadingOverlay from "@common/business_components/ui/loadingBar"; import UiPageNations from "@common/business_components/ui/table/uiPageNations"; import { Table, TableBody, TableHeader } from "@common/components/ui"; import { useCallback, useEffect, useState } from "react"; @@ -138,7 +137,6 @@ export default function RswtChkgdTable({ return ( <> -
{headMakeprfmnc(headList?.headList, headList?.upHeadList)} diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx index 0f919a603..fb243010e 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm.tsx @@ -39,6 +39,21 @@ type RuseMngTableProps = { readonly?: boolean; }; + +/** + * 재이용시설 등록 - 하수재이용 시설등록 + * 재이용시설 등록 - 하수재이용 시설현황 + * - layout.tsx에 의해 공통 레이아웃이 적용됨 + * - with-layout 적용 + * - 하수처리시설에 하수재이용 시설 시설 정보를 등록한다. + * - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다 + * indexMng: 시설정보 + * indexBiz: 차수별 정보 + * 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다. + * + * 시설정보및 차수별정보의 테이블 데이터를 만들고 생성한다. + * */ + const RuseMngTableForm = React.forwardRef( ( { diff --git a/apps/wr/public/sample_rswtSttn.xlsx b/apps/wr/public/sample_rswtSttn.xlsx index cec85971d..1085c6cfc 100644 Binary files a/apps/wr/public/sample_rswtSttn.xlsx and b/apps/wr/public/sample_rswtSttn.xlsx differ diff --git a/apps/wr/wr_doc/공사비산정 방법 정리_20241119_1.xlsx b/apps/wr/wr_doc/공사비산정 방법 정리_20241119_1.xlsx new file mode 100644 index 000000000..23149c67a Binary files /dev/null and b/apps/wr/wr_doc/공사비산정 방법 정리_20241119_1.xlsx differ diff --git a/packages/common/business_components/src/ui/chart/LineBarChart.tsx b/packages/common/business_components/src/ui/chart/LineBarChart.tsx index f26cb976c..271629e6a 100644 --- a/packages/common/business_components/src/ui/chart/LineBarChart.tsx +++ b/packages/common/business_components/src/ui/chart/LineBarChart.tsx @@ -210,8 +210,8 @@ export default function LineBarchart({ > {setXAxisYearTick? - value.slice(0,7)} fontSize="8px" fontWeight="bold"/> : - + value.slice(0,7)} className="text-[12px] font-bold" /> : + } {/* 왼쪽 Y축: lineVal */} {yFieldText && value.slice(0,7)} /> : } diff --git a/packages/common/business_components/src/ui/excel/index.tsx b/packages/common/business_components/src/ui/excel/index.tsx index cbe77293b..aedb32256 100644 --- a/packages/common/business_components/src/ui/excel/index.tsx +++ b/packages/common/business_components/src/ui/excel/index.tsx @@ -6,6 +6,10 @@ type ExcelDownloadProps = { fileName: string; sheetNameArray: string[]; headerRange?: string; + decimalArray0? : number[]; + decimalArray1? : number[]; + decimalArray2? : number[]; + decimalArray3? : number[]; } export const downloadExcel = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3'}: ExcelDownloadProps) => { @@ -15,6 +19,45 @@ export const downloadExcel = ({ data, fileName = new Date().getTime().toString() excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName); }; +export const downloadExcelFormat = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3', decimalArray0=[], decimalArray1=[], decimalArray2=[], decimalArray3=[]}: ExcelDownloadProps) => { + const worksheet = XLSX.utils.json_to_sheet(Array.isArray(data) ? data : [data]); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]); + console.log('decimalArray0 : ', decimalArray0); + const headerEnd = XLSX.utils.decode_range(headerRange).e.r; // 0-based index + const startRow = headerEnd + 1; + + // 🔹 전체 범위 + const range = XLSX.utils.decode_range(worksheet["!ref"] as string); + + const chaneValue = (array: number[], decimal: number) => { + for (let row = startRow; row <= range.e.r; row++) { + if(array.length>0){ + for(let idx=0; idx 0 && files.map((file:File, i:number) => ( - + - {file.name} + {file.name} ))} diff --git a/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx b/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx index 60bfdacfd..42662ab1d 100644 --- a/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx +++ b/packages/common/business_components/src/ui/file-upload/lib/file_upload.tsx @@ -79,10 +79,49 @@ export const FileUploader = forwardRef< const [isFileTooBig, setIsFileTooBig] = useState(false); const [isLOF, setIsLOF] = useState(false); const [activeIndex, setActiveIndex] = useState(-1); + + // MIME 타입 매핑 함수 추가 + const getAcceptObject = (fileTypes?: string): Record => { + if (!fileTypes) { + return { "image/*": [".jpg", ".jpeg", ".png", ".gif"] }; + } + + // 파일 확장자 별 MIME 타입 매핑 + const extensionToMimeType: Record = { + ".pdf": "application/pdf", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".doc": "application/msword", + ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".xls": "application/vnd.ms-excel", + ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".txt": "text/plain", + }; + + // fileTypes 문자열을 개별 확장자로 분리 + const extensions = fileTypes.split(",").map(ext => ext.trim()); + const acceptObj: Record = {}; + + extensions.forEach(ext => { + // 확장자 앞에 점(.)이 없으면 추가 + const normalizedExt = ext.startsWith(".") ? ext : `.${ext}`; + // 매핑된 MIME 타입 찾기, 없으면 기본값 사용 + const mimeType = extensionToMimeType[normalizedExt] || "application/octet-stream"; + + if (!acceptObj[mimeType]) { + acceptObj[mimeType] = []; + } + + acceptObj[mimeType].push(normalizedExt); + }); + + return acceptObj; + }; + const { - accept = { - "image/*": acceptName?acceptName.split(",").map(extend=>("."+extend)):[".jpg", ".jpeg", ".png", ".gif"], - }, + accept = getAcceptObject(acceptName), maxFiles = 1, maxSize = 4 * 1024 * 1024, multiple = true, @@ -208,7 +247,7 @@ export const FileUploader = forwardRef< }, [value, maxFiles]); const opts = dropzoneOptions - ? dropzoneOptions + ? { ...dropzoneOptions, accept: getAcceptObject(acceptName) } : { accept, maxFiles, maxSize, multiple }; const dropzoneState = useDropzone({ diff --git a/packages/common/business_components/src/ui/map/searchBar/searchBar.tsx b/packages/common/business_components/src/ui/map/searchBar/searchBar.tsx index a1201d23a..40f28e867 100644 --- a/packages/common/business_components/src/ui/map/searchBar/searchBar.tsx +++ b/packages/common/business_components/src/ui/map/searchBar/searchBar.tsx @@ -166,7 +166,10 @@ export const SearchBar = ({ let list: SelectDataType[] = []; if (type === "tb_il_swage_prcs_fclt") { - const cqlFilter = `ctpv_nm='${sidoNm}' and sgg_nm='${sggNm}' and swtrmt_fclt_nm like '%${fcltyNm}%'`; + // 하수처리시설 + let cqlFilter = `swtrmt_fclt_nm like '%${fcltyNm}%'`; + if (sggNm !== "시군구" && sggNm) cqlFilter = `sgg_nm='${sggNm}' and ` + cqlFilter; + if (sidoNm !== "시도" && sidoNm) cqlFilter = `ctpv_nm='${sidoNm}' and ` + cqlFilter; url += encodeURIComponent(cqlFilter); const res = await fetch(url); const json = await res.json(); diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index d4e4b7a2e..21e1a27bb 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -68,6 +68,7 @@ interface SdmRegFormProps { setIsDuplicate: (value: boolean) => void; updateList?: DemandCompType; readOnly?: boolean; + openNetwork?: boolean; } type FieldComponent = ( @@ -84,6 +85,7 @@ export function SdmRegForm({ setIsDuplicate, updateList, readOnly, + openNetwork, }: SdmRegFormProps) { const [sidoValue, setSidoValue] = useState(""); const [sigunValue, setSigunValue] = useState(""); @@ -403,22 +405,24 @@ export function SdmRegForm({ { name: "daddr", label: "사업자주소", - component: (field) => ( - // - { - field.onChange(rtnData.roadAddrPart1); - }} - /> - ), + component: (field) => + openNetwork ? ( + { + field.onChange(rtnData.roadAddrPart1); + }} + /> + ) : ( + + ), }, { name: "telno", diff --git a/packages/common/business_components/src/ui/sdmInsertForm/index.tsx b/packages/common/business_components/src/ui/sdmInsertForm/index.tsx index 051bdbdce..6dbefef4f 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/index.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/index.tsx @@ -16,8 +16,9 @@ type thisProps = { rtnValue: (searchText: string, pageCnt: number) => void; rtnInputData: (data: DemandCompType) => void; bodyClassNm?: string; - updateList?:DemandCompType - readOnly?:boolean + updateList?:DemandCompType; + readOnly?:boolean; + openNetwork:boolean } const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean ,updateList?:DemandCompType) => z.object({ @@ -88,7 +89,7 @@ const defaultValues: FormSchema = { * @returns */ -export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm, updateList,readOnly}: thisProps) { +export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm, updateList,readOnly,openNetwork}: thisProps) { const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(false); const [isDuplicate, setIsDuplicate] = useState(false); @@ -165,6 +166,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList setIsDuplicate={setIsDuplicate} updateList={updateList} readOnly={readOnly} + openNetwork={openNetwork} />
{readOnly==true?<> diff --git a/packages/common/business_components/src/ui/table/HeadMakeColSpan.tsx b/packages/common/business_components/src/ui/table/HeadMakeColSpan.tsx index c0ec33233..b3d3fdc40 100644 --- a/packages/common/business_components/src/ui/table/HeadMakeColSpan.tsx +++ b/packages/common/business_components/src/ui/table/HeadMakeColSpan.tsx @@ -8,7 +8,8 @@ interface TableUpperProps { row? : number; rowSpan?: number; colSpan?: number; - visible?:boolean; + visible?:boolean; + widthPercent?: number; } const HeadMakeColSpan = ({ upHeadList }: { upHeadList: TableUpperProps[] }) => { @@ -52,7 +53,7 @@ const HeadMakeColSpan = ({ upHeadList }: { upHeadList: TableUpperProps[] }) => { colSpan={head.colSpan || 1} rowSpan={head.rowSpan || 1} style={{ whiteSpace: 'pre-line' }} - className="bg-gray-50" + className="bg-gray-50" > {head.title} diff --git a/packages/common/business_components/src/ui/table/index.tsx b/packages/common/business_components/src/ui/table/index.tsx index 6d5b24c70..dc763d00b 100644 --- a/packages/common/business_components/src/ui/table/index.tsx +++ b/packages/common/business_components/src/ui/table/index.tsx @@ -32,6 +32,7 @@ type UiTableProps = { index?: number; curPage?: number; headButton?: React.ReactNode | undefined; + widthFixed?: boolean; }; type UiHeadProps = { @@ -39,6 +40,9 @@ type UiHeadProps = { title: string; align?: string; visible?: boolean; + row?: number; + widthPercent?: number; + rowSpan?: number; }; export function UiTable({ @@ -57,6 +61,7 @@ export function UiTable({ index = -1, curPage = 1, headButton = undefined, + widthFixed = false }: UiTableProps) { const [cur, setCur] = useState(curPage); const [idx, setIdx] = useState(index); @@ -104,6 +109,15 @@ export function UiTable({ } }; + const getLeafCols = (list: UiHeadProps[]) => { + const maxRow = list?.reduce((max, head) => Math.max(max, head.row || 0), 0); + return list + .filter(h => h.visible !== false) + .filter(h => ((h.row ?? 0) + (h.rowSpan ?? 1) - 1) >= maxRow) + ; + }; + + const leafCols = getLeafCols(headlist); return ( <> @@ -122,7 +136,13 @@ export function UiTable({ <> )}
-
+
+ {widthFixed? + + {leafCols.map(col => ( + + ))} + :""} {children ? children : }