From 2009c54a00bfd349ccf96b6d1fb0ad7001ea370d Mon Sep 17 00:00:00 2001 From: rsone001 Date: Mon, 29 Dec 2025 11:49:07 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20footer(=ED=95=A9=EA=B3=84)=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/fo/.env.mindone | 1 + apps/fo/app/auth/login/route.ts | 2 +- apps/fo/app/page.tsx | 31 +- .../pages/(with-layout)/dashboard/page.tsx | 98 +-- apps/fo/app/store/planSewage/index.tsx | 346 ++++++--- apps/fo/app/store/processFacility/index.tsx | 732 +++++++++--------- apps/fo/app/store/sewageOccur/index.tsx | 391 +++++----- apps/fo/src/entities/auth/index.ts | 2 +- .../fo/src/entities/auth/lib/auth-wrapper.tsx | 13 +- apps/sn/.env.local | 1 + apps/sn/.env.mindone | 1 + apps/sn/.env.production | 2 +- .../map/components/common/codeMapper.ts | 7 + .../map/components/common/table.ts | 4 +- .../map/components/popupComponent/Ssc.tsx | 17 +- .../popupComponent/featureClickEventPopup.tsx | 11 + .../map/components/popupComponent/smh.tsx | 3 +- .../(map-layout)/map/searchModal/basicTab.tsx | 2 +- .../map/searchModal/operationTab.tsx | 2 +- .../map/searchModal/reportFilesModal.tsx | 8 +- .../map/searchModal/reportTab.tsx | 14 +- .../map/searchModal/searchModal.tsx | 14 +- .../(with-base-layout)/ii/rdiiResult/page.tsx | 8 +- .../app/(with-base-layout)/ii/result/page.tsx | 8 +- .../(with-base-layout)/oper/floodPre/page.tsx | 1 + .../oper/floodPre/tableModal.tsx | 7 +- .../(with-base-layout)/oper/oldPp/page.tsx | 1 + .../oper/oldPp/tableModal.tsx | 552 ++++++------- apps/sn/app/auth/login/route.ts | 2 +- apps/sn/next.config.ts | 14 + apps/st/src/components/module/DataGrid.tsx | 70 +- .../management/SeweragePenetrationRateMng.tsx | 27 +- apps/st/src/components/type/DataGrid.type.ts | 26 + .../src/components/util/grid/footerSummary.ts | 22 + apps/wr/app/auth/login/route-bak.ts | 2 +- .../common/components/src/api/attachment.ts | 2 +- packages/common/components/src/api/banner.ts | 2 +- packages/common/components/src/api/site.ts | 4 +- 38 files changed, 1367 insertions(+), 1083 deletions(-) create mode 100644 apps/st/src/components/util/grid/footerSummary.ts diff --git a/apps/fo/.env.mindone b/apps/fo/.env.mindone index d2258aaf3..2003db503 100644 --- a/apps/fo/.env.mindone +++ b/apps/fo/.env.mindone @@ -5,6 +5,7 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11300 +NEXT_PUBLIC_SUB_DOMAIN = http://con.mind-one.co.kr:11300 NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login #NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082 NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11083/operation-service diff --git a/apps/fo/app/auth/login/route.ts b/apps/fo/app/auth/login/route.ts index d954cbaa1..65bbce15e 100644 --- a/apps/fo/app/auth/login/route.ts +++ b/apps/fo/app/auth/login/route.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const hostname = request.nextUrl.hostname; - const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://portal.hasuon.or.kr"; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 diff --git a/apps/fo/app/page.tsx b/apps/fo/app/page.tsx index 26f528d0e..143dfdc90 100644 --- a/apps/fo/app/page.tsx +++ b/apps/fo/app/page.tsx @@ -11,25 +11,20 @@ export default function Home() { const checkToken = getCookie(AUTH_USER_ID); useEffect(() => { + const hostname = window.location.hostname; - if (!checkToken) { - // 외부 URL로 이동해야 할 경우 location.replace를 사용합니다. - if (window.location.hostname.includes("hasuon.or.kr")) { - location.replace(process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL||'/pages/dashboard'); - return; // 페이지 이동 후에는 더 이상 로직을 실행하지 않습니다. - } - - async function doLogin() { - try { - await LoginApi.login({ userId: "CLEANWATER", password: "gktneh12!@" }); - router.push("/pages/dashboard"); // location.href 대신 router.push 사용 - } catch (err) { - console.error("로그인 실패", err); + if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { + if (!checkToken) { + async function doLogin() { + try { + await LoginApi.login({ userId: "CLEANWATER", password: "gktneh12!@" }); + window.location.href = "/pages/dashboard"; + } catch (err) { + console.error("로그인 실패", err); + } } - } - doLogin(); - } else { - router.push("/pages/dashboard"); - } + doLogin(); + } else router.push("/pages/dashboard"); + } else router.push("/pages/dashboard"); }, []); } \ No newline at end of file diff --git a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx index a6cf99008..8d431cf75 100644 --- a/apps/fo/app/pages/(with-layout)/dashboard/page.tsx +++ b/apps/fo/app/pages/(with-layout)/dashboard/page.tsx @@ -19,7 +19,7 @@ import { roundNumber } from "@/app/components/common/DataForm"; const tabList = [ { value: 'facilityInfo', label: '시설정보 및 운영현황' }, - { value: 'mainGraph', label: '주요그래프' }, + { value: 'mainGraph', label: '주요그래프' }, { value: 'rainManage', label: '강우일 운영현황' }, //{ value: 'drainageEquipment', label: '배수설비 정비현황' } ]; @@ -42,7 +42,7 @@ export const generateYearDates = (searchYear: string) => { export default function DashBoard() { // 입력값 상태 관리 - const { Common, initializeCommonData,searchMainGraph, searchRainManage, searchOperationStatus, OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); + const { Common, initializeCommonData, searchMainGraph, searchRainManage, searchOperationStatus, OperationStatus, RainManage, MainGraph, PlanFclty } = useFoStore((state) => state); const [activeTab, setActiveTab] = useState('facilityInfo'); const [filteredSigunData, setFilteredSigunData] = useState([{ text: "전체", val: '0' }]); @@ -55,7 +55,7 @@ export default function DashBoard() { selectSidoData, selectSigunData, } = Common; - + const { planFcltyList } = PlanFclty; @@ -82,7 +82,7 @@ export default function DashBoard() { // 연도 const [searchYear, setSearchYear] = useState(selectSearchYear[0]?.val || '0'); // 시설명 - const [fcltyList, setFcltyList] = useState<{bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | ''}>({ + const [fcltyList, setFcltyList] = useState<{ bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }>({ bscFctCd: '11000SW001R', bscFctNm: '난지', fcltyCpc: 860000, @@ -90,7 +90,7 @@ export default function DashBoard() { efflWqltStndrdNm: '500톤 이상(Ⅲ지역)' }); - const [searchFcltyList, setSearchFcltyList] = useState<{bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | ''}>({ + const [searchFcltyList, setSearchFcltyList] = useState<{ bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string | '', efflWqltStndrdNm: string | '' }>({ bscFctCd: '', bscFctNm: '', fcltyCpc: '', @@ -116,7 +116,7 @@ export default function DashBoard() { }; const onSelectValue = (val: string, type: string) => { - switch(type) { + switch (type) { case 'sido': setSidoValue(val); initializeSigunData(val); @@ -145,11 +145,11 @@ export default function DashBoard() { const excelDownload = () => { if (!fcltyList.bscFctCd) return; - + switch (activeTab) { - case 'facilityInfo': - searchOperationStatus(false, searchYear, fcltyList.bscFctCd).then(() => {setTimeout(() => {makeExcelData();}, 200);}); - + case 'facilityInfo': // 시설정보 및 운영현황 + searchOperationStatus(false, searchYear, fcltyList.bscFctCd).then(() => { setTimeout(() => { makeExcelData(); }, 200); }); + const makeExcelData = async () => { fetch(`/mainDashBoard.xlsx`, {}).then(async (response) => { if (!response.ok) { @@ -161,7 +161,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.provisionalApproval ? Number(item.provisionalApproval.toString().replaceAll(',', '')) ? Number(item.provisionalApproval.toString().replaceAll(',', '')) : item.provisionalApproval : '', item.now, item.stepOne, item.stepTwo, @@ -172,25 +172,25 @@ export default function DashBoard() { // operationalStatusList를 2차원 배열로 변환 const excelData2 = operationalStatusList.map((item, index) => { - console.log(item.yearAvg+' '+item.yearMax+' '+item.yearMin); + console.log(item.yearAvg + ' ' + item.yearMax + ' ' + item.yearMin); const baseData = [ - Number(item.yearAvg?.toString().replaceAll(',','')), - Number(item.yearMax?.toString().replaceAll(',','')), - Number(item.yearMin?.toString().replaceAll(',','')), - Number(item.summerAll?.toString().replaceAll(',','')), - Number(item.summerThree?.toString().replaceAll(',','')), - Number(item.summerRain?.toString().replaceAll(',','')), - Number(item.winterAll?.toString().replaceAll(',','')), - Number(item.winterSunnyAvg?.toString().replaceAll(',','')), - Number(item.winterSunnyMax?.toString().replaceAll(',','')), - Number(item.winterSunnyMin?.toString().replaceAll(',','')), - Number(item.groundWaterAvg?.toString().replaceAll(',','').replaceAll('%','')), - Number(item.groundWaterSummer?.toString().replaceAll(',','').replaceAll('%','')), - Number(item.groundWaterWinter?.toString().replaceAll(',','').replaceAll('%','')) + Number(item.yearAvg?.toString().replaceAll(',', '')), + Number(item.yearMax?.toString().replaceAll(',', '')), + Number(item.yearMin?.toString().replaceAll(',', '')), + Number(item.summerAll?.toString().replaceAll(',', '')), + Number(item.summerThree?.toString().replaceAll(',', '')), + Number(item.summerRain?.toString().replaceAll(',', '')), + Number(item.winterAll?.toString().replaceAll(',', '')), + Number(item.winterSunnyAvg?.toString().replaceAll(',', '')), + Number(item.winterSunnyMax?.toString().replaceAll(',', '')), + Number(item.winterSunnyMin?.toString().replaceAll(',', '')), + Number(item.groundWaterAvg?.toString().replaceAll(',', '').replaceAll('%', '')), + Number(item.groundWaterSummer?.toString().replaceAll(',', '').replaceAll('%', '')), + Number(item.groundWaterWinter?.toString().replaceAll(',', '').replaceAll('%', '')) ]; - + // index가 0일 때만 rdi와 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; + 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 = [ @@ -215,32 +215,32 @@ export default function DashBoard() { }; break; - case 'mainGraph': + case 'mainGraph': // 주요그래프 searchMainGraph(searchYear, fcltyList.bscFctCd); const yearData = generateYearDates(searchYear); - const yearValueData : any = []; + const yearValueData: any = []; - for (const i in yearData){ + for (const i in yearData) { const rowArray: string[] = []; rowArray.push(yearData[i] ?? ""); //강수량 - rowArray.push(roundNumber(chart_inflowRain.filter(item=>{return yearData[i] === item.label})[0]?.barVal0?.toString(), 1) || ''); + rowArray.push(roundNumber(chart_inflowRain.filter(item => { return yearData[i] === item.label })[0]?.barVal0?.toString(), 1) || ''); //유입하수량 - rowArray.push(roundNumber(chart_inflowRain.filter(item=>{return yearData[i] === item.label})[0]?.lineVal1?.toString(), 0) || ''); + rowArray.push(roundNumber(chart_inflowRain.filter(item => { return yearData[i] === item.label })[0]?.lineVal1?.toString(), 0) || ''); //시설용량 - rowArray.push(roundNumber(chart_inflowRain.filter(item=>{return yearData[i] === item.label})[0]?.lineVal0?.toString(), 0) || ''); + rowArray.push(roundNumber(chart_inflowRain.filter(item => { return yearData[i] === item.label })[0]?.lineVal0?.toString(), 0) || ''); //유입BOD - rowArray.push(roundNumber(chart_bodRain.filter(item=>{return yearData[i] === item.label})[0]?.lineVal0?.toString(), 1) || ''); + rowArray.push(roundNumber(chart_bodRain.filter(item => { return yearData[i] === item.label })[0]?.lineVal0?.toString(), 1) || ''); //유입T-P - rowArray.push(roundNumber(chart_inflTp.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_inflTp.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //총인유입T-P - rowArray.push(roundNumber(chart_chongInTp.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_chongInTp.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //방류T-P - rowArray.push(roundNumber(chart_efflTp.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_efflTp.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //유입T-N - rowArray.push(roundNumber(chart_inflTn.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_inflTn.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); //방류T-N - rowArray.push(roundNumber(chart_efflTn.filter(item=>{return yearData[i] === item.label})[0]?.val?.toString(), 3) || ''); + rowArray.push(roundNumber(chart_efflTn.filter(item => { return yearData[i] === item.label })[0]?.val?.toString(), 3) || ''); yearValueData.push( rowArray @@ -250,7 +250,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: '주요그래프' @@ -314,7 +314,7 @@ export default function DashBoard() { downloadMultipleExcel('주요그래프', sheetParameter); break; - case 'rainManage': + case 'rainManage': // 강우일 운영현황 searchRainManage(searchYear, fcltyList.bscFctCd, true); if (excelList && excelList.length > 0) { downloadExcel({ data: excelList as unknown as JSON[], fileName: '강우일 운영현황', sheetNameArray: ['강우일 운영현황'], headerRange: 'A1:T1' }); @@ -351,7 +351,7 @@ export default function DashBoard() { const searchVal = () => { setSearchFcltyList(fcltyList); - if(searchFcltyList.bscFctCd) { + if (searchFcltyList.bscFctCd) { searchOperationStatus(false, searchYear, fcltyList.bscFctCd); } } @@ -361,11 +361,11 @@ export default function DashBoard() {
- setSearchYear(val.toString()) } value={searchYear} selectClass={undefined}/> - onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={undefined}/> - onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={undefined}/> + setSearchYear(val.toString())} value={searchYear} selectClass={undefined} /> + onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={undefined} /> + onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={undefined} />
- +
@@ -385,13 +385,13 @@ export default function DashBoard() { - + - + - + diff --git a/apps/fo/app/store/planSewage/index.tsx b/apps/fo/app/store/planSewage/index.tsx index 44ab12440..2fd9b531c 100644 --- a/apps/fo/app/store/planSewage/index.tsx +++ b/apps/fo/app/store/planSewage/index.tsx @@ -1,37 +1,33 @@ import DataForm from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; -import { getFetch } from "@/app/components/api"; -import { type ApiResponse, type FlowDataItem } from "../underWaterInput"; -import CalcRainEffect from "@/app/components/common/CalcRainEffect"; +import { getFetch, postFetch } from "@/app/components/api"; +import { type ApiResponse } from "../underWaterInput"; +// import CalcRainEffect from "@/app/components/common/CalcRainEffect"; import { roundUp } from "../common"; export type { TableUpperProps }; -/**==================================== - * Store - 타입 - ====================================*/ - /** - * (1) 메인페이지 + * 처리시설 연간 운영현황 > 계획하수량 산정지표 현황 */ // 시설별 강수현황 type PlanSewageProps = { - bscFctCd : string, - sido : string, - gugun : string, - bscFctNm : string, - daddr : string, - fctCpc : number, - spareCapacity : number, - variableLoadPercent : number, - classifiedSewerPercent : number, - rgnNm : string, - rvbsn : string, - lgbsn : string, - mdmbsn : string, - sprtProcZoneAr : number, - procZoneSm : number, - avgInflAmnt : number, - avgInflAmntSunny : number, - maxInflAmntSunny : number, + bscFctCd: string, + sido: string, + gugun: string, + bscFctNm: string, + daddr: string, + fctCpc: number, + spareCapacity: number, + variableLoadPercent: number, + classifiedSewerPercent: number, + rgnNm: string, + rvbsn: string, + lgbsn: string, + mdmbsn: string, + sprtProcZoneAr: number, + procZoneSm: number, + avgInflAmnt: number, + avgInflAmntSunny: number, + maxInflAmntSunny: number, } /**==================================== @@ -40,90 +36,135 @@ type PlanSewageProps = { /** * (1) 메인페이지 - */ + */ // 검색단 -const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; +const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", upSequnce:1, row:0, colSpan: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', 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 upHeadList1: TableUpperProps[] = [ + { id: "A", title: "행정구역", upSequnce: 1, row: 0, colSpan: 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', 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, 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', 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, 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', 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, 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, 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', 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, 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, 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', 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[] = [ +const planSewageList: PlanSewageProps[] = [ ] /**==================================== * Store - api ====================================*/ - 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 : '') : ''; + +/** +* 계획시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) +* @param pageNo : 페이지 번호 +* @param pageSize : 페이지 크기 +* @param searchYear : 검색년도 +* @param partCd : 구분코드 +* @param nameCd : 행정코드(시도명, 시군구명, 단위유역) +* @param fcltCpct : 시설용량 +* @param oprtngSttsCd : 운영 상태 코드 +* @param facilityName : 시설명 +*/ +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; const res = await getFetch('fo', url); return { data: res.data, count: res.count } - } +} +// 분류식화율 구하기 위한 api 호출 +const fetchPlanZoneList = async (searchYear: string, fcltCdList: string[]) => { + try { + const res = await postFetch('fo', '/prcsFclt/info/planZone/' + searchYear, fcltCdList); + return res; + } catch (error) { + console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error); + return null; + } +} + +// 시설들 유량 정보 조회 +// export const fetchFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { +// try { +// const params = new URLSearchParams(); +// fcltCdList.forEach(cd => params.append('fcltCds', cd)); +// const res = await getFetch('fo', '/fclt/flow/' + searchYear + '?' + params.toString()); +// return res; +// } catch (error) { +// console.error('시설정보 유량 데이터를 가져오는데 실패했습니다:', error); +// return null; +// } +// }; +// 시설들 유량 정보 조회 +export const fetchFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { + try { + const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList); + return res; + } catch (error) { + console.error('시설정보 유량 데이터를 가져오는데 실패했습니다:', error); + return null; + } +}; /**==================================== * Store - expaort ====================================*/ export type ExcelType = { 시설코드: string; - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', 시도: string; 시군구: string; 시설이름: string; 주소: string; "시설용량(m³/일)": number; "여유용량(m³/일)": number; - "변동부하율(%)" : number; - "분류식화율(%)" : number; + "변동부하율(%)": number; + "분류식화율(%)": number; } -const dataFormSetting=(item : PlanSewageProps)=> { +const dataFormSetting = (item: PlanSewageProps) => { DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); - DataForm({ type: 'float0', column: 'spareCapacity', item: item as unknown as Record}); - DataForm({ type: 'float2', column: 'variableLoadPercent', item: item as unknown as Record}); - DataForm({ type: 'float1', column: 'classifiedSewerPercent', item: item as unknown as Record}); + DataForm({ type: 'float0', column: 'spareCapacity', item: item as unknown as Record }); + DataForm({ type: 'float2', column: 'variableLoadPercent', item: item as unknown as Record }); + DataForm({ type: 'float1', column: 'classifiedSewerPercent', item: item as unknown as Record }); }; export type PlanSewageActions = { @@ -133,10 +174,10 @@ export type PlanSewageActions = { export type PlanSewageType = { PlanSewageSearch: { isInit: boolean; - labelArray:string[]; + labelArray: string[]; }, - PlanSewage : { + PlanSewage: { isInit: boolean; upHeadList1: TableUpperProps[]; upHeadList2: TableUpperProps[]; @@ -154,21 +195,21 @@ export const planSewageInitState: PlanSewageType = { labelArray: LabelArray, }, - PlanSewage : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - planSewageList : planSewageList, - planSewageCount : 0, - excelList : [], - isLoading : true, + PlanSewage: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + planSewageList: planSewageList, + planSewageCount: 0, + excelList: [], + isLoading: true, }, } export type PlanSewageStore = PlanSewageType & PlanSewageActions; -export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageType) => void)=>PlanSewageActions=(set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => { +export const planSewageReducer: (set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => PlanSewageActions = (set: (fn: (state: PlanSewageType) => PlanSewageType) => void) => { return { searchPlanSewageList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { set((state: PlanSewageType) => ({ @@ -179,48 +220,121 @@ export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageTy }, })); const res = await fetchPlanSewageList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm); - const excelDownList: ExcelType[] = []; - const data = res.data - const processedData = await Promise.all(data.map(async (item:PlanSewageProps) => { - const res2 = await getFetch('fo', '/fclt/flow/' + item.bscFctCd + '/' + searchYear) as ApiResponse; - const calData = CalcRainEffect(res2.data, 'SUNNY'); + const fcltylist = res.data; // 시설목록 + const fcltCdList: string[] = []; // 시설코드목록 + const planSewageList: PlanSewageProps[] = []; // 오수발생량시설목록 + fcltylist.forEach(item => { + fcltCdList.push(item.bscFctCd); + planSewageList.push({ + bscFctCd: item.bscFctCd, + sido: item.sido, + gugun: item.gugun, + bscFctNm: item.bscFctNm, + daddr: item.daddr, + fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')), + spareCapacity: 0, + variableLoadPercent: 0, + classifiedSewerPercent: 0, + rgnNm: item.rgnNm, //환경청 + rvbsn: item.rvbsn, //단위유역 + lgbsn: item.lgbsn, //권역 + mdmbsn: item.mdmbsn, //중권역 + sprtProcZoneAr: 0, // 분류식지역 면적(㎢) + procZoneSm: 0, // 처리구역 면적합계(㎢) + avgInflAmnt: 0, + avgInflAmntSunny: 0, + maxInflAmntSunny: 0, + }); + }); + + const excelDownList: ExcelType[] = []; + // const data = res.data + + const planZoneRes: any = await fetchPlanZoneList(searchYear, fcltCdList); + const planZoneList = planZoneRes?.data; + planZoneList?.forEach(item => { + const planSewageItem = planSewageList.find(item2 => item2.bscFctCd == item.bscFctCd); + if (planSewageItem) { + planSewageItem.sprtProcZoneAr = item.sprtProcZoneAr; + planSewageItem.procZoneSm = item.procZoneSm; + } + }); + + const detailRes: any = await fetchFlow(searchYear, fcltCdList); + for (const item of planSewageList) { + const detailList = detailRes?.data[item.bscFctCd]; + + let avgInflAmnt = 0; let sumInflAmntSunny = 0; let avgInflAmntSunny = 0; let maxInflAmntSunny = 0; - calData.forEach((flowItem:FlowDataItem) => { - sumInflAmntSunny += Number(flowItem.inflAmnt); + let cntSunny = 0; + let rainEffectDay = 0; + detailList?.forEach(item2 => { - if(Number(flowItem.inflAmnt) > maxInflAmntSunny){ - maxInflAmntSunny = Number(flowItem.inflAmnt); + if (item2.infoRnDay == null || item2.infoRnDay == 'x') item2.infoRnDay = 0; + if (item2.infoRnDay >= 3) { // 강우량이 3이상이면 그 후 2일이 강후영향일임. + rainEffectDay = 2; + } else { + rainEffectDay--; } - }); + if (rainEffectDay < 0) { //청천시 + sumInflAmntSunny += Number(item2.inflAmnt); + cntSunny++; - avgInflAmntSunny = sumInflAmntSunny / calData.length; + if (Number(item2.inflAmnt) > maxInflAmntSunny) { + maxInflAmntSunny = Number(item2.inflAmnt); + } + } + avgInflAmnt += Number(item2.inflAmnt); + }); + avgInflAmntSunny = sumInflAmntSunny / cntSunny; + item.avgInflAmnt = roundUp(avgInflAmnt, 0); item.avgInflAmntSunny = roundUp(avgInflAmntSunny, 0); item.maxInflAmntSunny = roundUp(maxInflAmntSunny, 0); - return item; - })); - + } + + // const processedData = await Promise.all(data.map(async (item: PlanSewageProps) => { + // const res2 = await getFetch('fo', '/fclt/flow/' + item.bscFctCd + '/' + searchYear) as ApiResponse; + // const calData = CalcRainEffect(res2.data, 'SUNNY'); + + // let sumInflAmntSunny = 0; // 청천시 유입량 합계 + // let avgInflAmntSunny = 0; // 청천시 유입량 평균 + // let maxInflAmntSunny = 0; // 청천시 유입량 최대값 + // calData.forEach((flowItem: FlowDataItem) => { + // sumInflAmntSunny += Number(flowItem.inflAmnt); + + // if (Number(flowItem.inflAmnt) > maxInflAmntSunny) { + // maxInflAmntSunny = Number(flowItem.inflAmnt); + // } + // }); + + // avgInflAmntSunny = sumInflAmntSunny / calData.length; + // item.avgInflAmntSunny = roundUp(avgInflAmntSunny, 0); + // item.maxInflAmntSunny = roundUp(maxInflAmntSunny, 0); + // return item; + // })); + /** * 결과데이터 계산 * (1) 여유용량 = 시설용량 - 건기시 평균유량 * (2) 변동부하율 = 건기시 일최대 유량/일평균유량(기준 최근 3개년) * (3) 분류식화율 = 분류식지역 면적(㎢)/처리구역 면적합계(㎢) ×100 */ - const resultData = processedData.map((item:PlanSewageProps) => { + const resultData = planSewageList.map((item: PlanSewageProps) => { item.spareCapacity = Number(item.fctCpc) - Number(item.avgInflAmntSunny); - item.variableLoadPercent = item.maxInflAmntSunny && item.maxInflAmntSunny!==0 ? Number(item.maxInflAmntSunny) / Number(item.avgInflAmntSunny) : 0; - item.classifiedSewerPercent = item.sprtProcZoneAr && item.sprtProcZoneAr!==0 ? Number(item.sprtProcZoneAr) / Number(item.procZoneSm) * 100 : 0; + item.variableLoadPercent = item.maxInflAmntSunny && item.maxInflAmntSunny !== 0 ? Number(item.maxInflAmntSunny) / Number(item.avgInflAmntSunny) : 0; + item.classifiedSewerPercent = item.sprtProcZoneAr && item.sprtProcZoneAr !== 0 ? Number(item.sprtProcZoneAr) / Number(item.procZoneSm) * 100 : 0; // 분류식화율 return item; }); - resultData.forEach((item:PlanSewageProps) => { + resultData.forEach((item: PlanSewageProps) => { dataFormSetting(item) }) - if(pageSize>5000){ - resultData.forEach((item:PlanSewageProps) => { + if (pageSize > 5000) { + resultData.forEach((item: PlanSewageProps) => { excelDownList.push({ 시설코드: item.bscFctCd, 권역: item.lgbsn, @@ -238,18 +352,18 @@ export const planSewageReducer:(set:(fn: (state: PlanSewageType) => PlanSewageTy }) }) } - - set((state:PlanSewageType) => ({ + + set((state: PlanSewageType) => ({ ...state, - PlanSewage: pageSize<5000?{ + PlanSewage: pageSize < 5000 ? { ...state.PlanSewage, planSewageList: resultData, planSewageCount: res.count, - isLoading : false, - }:{ + isLoading: false, + } : { ...state.PlanSewage, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })) } diff --git a/apps/fo/app/store/processFacility/index.tsx b/apps/fo/app/store/processFacility/index.tsx index f4184865d..8fa38e5bc 100644 --- a/apps/fo/app/store/processFacility/index.tsx +++ b/apps/fo/app/store/processFacility/index.tsx @@ -2,152 +2,147 @@ import { getFetch } from "@/app/components/api"; import DataForm, { roundNumber } from "@/app/components/common/DataForm"; import type { TableUpperProps } from "../dashboard"; export type { TableUpperProps }; - -/**==================================== - * Store - 타입 - ====================================*/ - /** - * (1) 메인페이지 + * 처리시설 현황 > 처리시설 시설정보 */ // 처리시설 리스트 export type facilityListProps = { - bscFctCd : string, - bscFctNm : string, - bscFctClsNm : string, - sido : string, - gugun : string, - daddr : string, - fctCpc : number | string | '', - plInflWqltBod : number | string | '', - dsInflWqltBod : number | string | '', - trtFrfNm : string, - rnDt : string, - cmplDt : string, - trstOprEtpNm : string, - rvbsn : string, - mdmbsn : string, - lgbsn : string, - rgnNm : string, - mnstr : string, - efflWtrrgn : string, - efflWqltStndrdNm : string + bscFctCd: string, + bscFctNm: string, + bscFctClsNm: string, + sido: string, + gugun: string, + daddr: string, + fctCpc: number | string | '', + plInflWqltBod: number | string | '', + dsInflWqltBod: number | string | '', + trtFrfNm: string, + rnDt: string, + cmplDt: string, + trstOprEtpNm: string, + rvbsn: string, + mdmbsn: string, + lgbsn: string, + rgnNm: string, + mnstr: string, + efflWtrrgn: string, + efflWqltStndrdNm: string } export interface ExcelType { - 시설코드: string, - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', - 시도: string, - 시군구: string, - 시설이름: string, - 주소: string, - "시설용량(m³/일)": number | '', - "계획유입수질(mg/L)": number | '', - "설계유입수질(mg/L)": number | '', - 공법: string, - 가동개시일: string, - 준공일: string, - 관리대행업자: string, + 시설코드: string, + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', + 시도: string, + 시군구: string, + 시설이름: string, + 주소: string, + "시설용량(m³/일)": number | '', + "계획유입수질(mg/L)": number | '', + "설계유입수질(mg/L)": number | '', + 공법: string, + 가동개시일: string, + 준공일: string, + 관리대행업자: string, } // (2) 처리시설 팝업 // 시설 기본정보 export type BasicInfoProps = { - bscFctNm : string, - fctCpc : number | '', - sido : string, - gugun : string, - startDay : string, - addr : string, - cmplDt : string, - trtFrfNm : string, - trstOprEtpNm : string, + bscFctNm: string, + fctCpc: number | '', + sido: string, + gugun: string, + startDay: string, + addr: string, + cmplDt: string, + trtFrfNm: string, + trstOprEtpNm: string, } // 시설 계획정보 export type PlanInfoProps = { - plInflWqltBod? : string, - plInflWqltToc? : string, - plInflWqltCod? : string, - plInflWqltSs? : string, - plInflWqltTn? : string, - plInflWqltTp? : string, - dsInflWqltBod? : string, - dsInflWqltToc? : string, - dsInflWqltCod? : string, - dsInflWqltSs? : string, - dsInflWqltTn? : string, - dsInflWqltTp? : string, - sitArea? : string | number, - trtDstrArea? : string | number, - swrTrtPopl? : string | number + plInflWqltBod?: string, + plInflWqltToc?: string, + plInflWqltCod?: string, + plInflWqltSs?: string, + plInflWqltTn?: string, + plInflWqltTp?: string, + dsInflWqltBod?: string, + dsInflWqltToc?: string, + dsInflWqltCod?: string, + dsInflWqltSs?: string, + dsInflWqltTn?: string, + dsInflWqltTp?: string, + sitArea?: string | number, + trtDstrArea?: string | number, + swrTrtPopl?: string | number } // 시설 계획정보 export type LegalWaterQltyProps = { - totClfgrpcnt : number, - bod : number, - cod : number, - ss : number, - tn : number, - tp : number + totClfgrpcnt: number, + bod: number, + cod: number, + ss: number, + tn: number, + tp: number } // 시설 수역 및 구역정보 export type fcltyAreaInfoProps = { - rvbsn : string, - efflWtrrgn : string, - lgbsn : string, - efflWqltStndrdNm : string, - rgnNm : string, + rvbsn: string, + efflWtrrgn: string, + lgbsn: string, + efflWqltStndrdNm: string, + rgnNm: string, } // 시설 이력관리 export type fcltyHistInfoProps = { - extnsSeqno : string, - extnsNm : string, - bzStrtYrMnth : string, - bzEdYrMnth : string, - eqpPrmsDt : string, - cmplDt : string, - trlrnCmplDt : string, - rnDt : string, - sitArea : number, - trtDstrArea : number, - swrTrtPopl : number, - fctCpc : number | '' + extnsSeqno: string, + extnsNm: string, + bzStrtYrMnth: string, + bzEdYrMnth: string, + eqpPrmsDt: string, + cmplDt: string, + trlrnCmplDt: string, + rnDt: string, + sitArea: number, + trtDstrArea: number, + swrTrtPopl: number, + fctCpc: number | '' } // 시설 수질정보 export type fcltyWaterQltyInfoProps = { - extnsSeqno : string, - plInflWqltBod : string, - plInflWqltToc : string, - plInflWqltCod : string, - plInflWqltSs : string, - plInflWqltTn : string, - plInflWqltTp : string, - dsInflWqltBod : string, - dsInflWqltToc : string, - dsInflWqltCod : string, - dsInflWqltSs : string, - dsInflWqltTn : string, - dsInflWqltTp : string, - plEfflWqltBod : string, - plEfflWqltToc : string, - plEfflWqltCod : string, - plEfflWqltSs : string, - plEfflWqltTn : string, - plEfflWqltTp : string, - bod : number, - cod : number, - ss : number, - tn : number, - tp : number, - totClfgrpcnt : number, + extnsSeqno: string, + plInflWqltBod: string, + plInflWqltToc: string, + plInflWqltCod: string, + plInflWqltSs: string, + plInflWqltTn: string, + plInflWqltTp: string, + dsInflWqltBod: string, + dsInflWqltToc: string, + dsInflWqltCod: string, + dsInflWqltSs: string, + dsInflWqltTn: string, + dsInflWqltTp: string, + plEfflWqltBod: string, + plEfflWqltToc: string, + plEfflWqltCod: string, + plEfflWqltSs: string, + plEfflWqltTn: string, + plEfflWqltTp: string, + bod: number, + cod: number, + ss: number, + tn: number, + tp: number, + totClfgrpcnt: number, } /**==================================== @@ -156,48 +151,48 @@ export type fcltyWaterQltyInfoProps = { /** * (1) 메인페이지 - */ + */ // 검색단 -const ProcessFacilityLabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '시설상태', '시설구분', '권역', '단위유역', '중권역', '환경청별']; +const ProcessFacilityLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '시설상태', '시설구분', '권역', '단위유역', '중권역', '환경청별']; // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ +const upHeadList1: TableUpperProps[] = [ { 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: "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: "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} + { id: "trstOprEtpNm", title: '관리대행업자', row: 0, rowSpan: 2, widthPercent: 14 } ]; // 처리시설 리스트 (유역) -const upHeadList2:TableUpperProps[] = [ +const upHeadList2: TableUpperProps[] = [ { 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 } + { 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[] = [ +const upHeadList3: TableUpperProps[] = [ { id: "A", title: "유역", colSpan: 3, row: 0, widthPercent: 12 }, { id: "rvbsn", title: "권역", row: 1, widthPercent: 4 }, - { id: "lgbsn", 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 }, @@ -206,178 +201,178 @@ const upHeadList3:TableUpperProps[] = [ { 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: "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[] = [ +const processFacilityList: facilityListProps[] = [ ] /** * 처리시설 상세팝업 - */ + */ // 시설 기본정보 (헤더) -const upHeadListBasicInfo:TableUpperProps[] = [ +const upHeadListBasicInfo: TableUpperProps[] = [ { id: "bscFctNm", title: "시설명" }, - { id: "fctCpc", title: "시설용량n(m³/일)", align: 'right'}, - { id: "sido", title: "시도"}, - { id: "gugun", title: "시군구"}, - { id: "rnDt", title: "가동개시일"}, - { id: "daddr", title: "주소"}, - { id: "cmplDt", title: "준공일"}, - { id: "trtFrfNm", title: "공법"}, - { id: "trstOprEtpNm", title: "관리대행업자"}, + { id: "fctCpc", title: "시설용량n(m³/일)", align: 'right' }, + { id: "sido", title: "시도" }, + { id: "gugun", title: "시군구" }, + { id: "rnDt", title: "가동개시일" }, + { id: "daddr", title: "주소" }, + { id: "cmplDt", title: "준공일" }, + { id: "trtFrfNm", title: "공법" }, + { id: "trstOprEtpNm", title: "관리대행업자" }, ]; // 시설 기본정보 (리스트) -const gridListBasicInfo:BasicInfoProps[] = [ +const gridListBasicInfo: BasicInfoProps[] = [ { - bscFctNm : "난지", - fctCpc : 860000, - sido : "서울특별시", - gugun : "", - startDay : "1987-06-30", - addr : "경기도 고양시 덕양구 대덕로 426 (현천동)", - cmplDt : "2013-04-30", - trtFrfNm : "MLE, A2O", - trstOprEtpNm : "자체", + bscFctNm: "난지", + fctCpc: 860000, + sido: "서울특별시", + gugun: "", + startDay: "1987-06-30", + addr: "경기도 고양시 덕양구 대덕로 426 (현천동)", + cmplDt: "2013-04-30", + trtFrfNm: "MLE, A2O", + trstOprEtpNm: "자체", } ]; // 시설 법적방류수질 (헤더) -const upHeadListLegalWaterQlty:TableUpperProps[] = [ - { id: "bod", title: "BOD(mg/L)", align: 'right'}, - { id: "cod", title: "TOC(COD)(mg/L)", align: 'right'}, - { id: "ss", title: "SS(mg/L)", align: 'right'}, - { id: "tn", title: "T-N(mg/L)", align: 'right'}, - { id: "tp", title: "T-P(mg/L) ", align: 'right'}, - { id: "totClfgrpcnt", title: "대장균군(개/100ml)"}, +const upHeadListLegalWaterQlty: TableUpperProps[] = [ + { id: "bod", title: "BOD(mg/L)", align: 'right' }, + { id: "cod", title: "TOC(COD)(mg/L)", align: 'right' }, + { id: "ss", title: "SS(mg/L)", align: 'right' }, + { id: "tn", title: "T-N(mg/L)", align: 'right' }, + { id: "tp", title: "T-P(mg/L) ", align: 'right' }, + { id: "totClfgrpcnt", title: "대장균군(개/100ml)" }, ] // 시설 법적방류수질 (리스트) -let gridListLegalWaterQlty:LegalWaterQltyProps[] = [ +let gridListLegalWaterQlty: LegalWaterQltyProps[] = [ ] // 시설 계획정보 (헤더) -const upHeadListPlanInfo:TableUpperProps[] = [ - { id: "plInflWqltBod", title: "BOD", upName:"upChangeRe1", upSequnce:1, align: 'right' }, - { id: "plInflWqltToc", title: "TOC", upName:"upChangeRe1", upSequnce:2, align: 'right' }, - { id: "plInflWqltCod", title: "COD", upName:"upChangeRe1", upSequnce:3, align: 'right' }, - { id: "plInflWqltSs", title: "SS", upName:"upChangeRe1", upSequnce:4, align: 'right' }, - { id: "plInflWqltTn", title: "T-N", upName:"upChangeRe1", upSequnce:5, align: 'right' }, - { id: "plInflWqltTp", title: "T-P", upName:"upChangeRe1", upSequnce:6, align: 'right' }, - { id: "dsInflWqltBod", title: "BOD", upName:"upChangeRe2", upSequnce:1, align: 'right' }, - { id: "dsInflWqltToc", title: "TOC", upName:"upChangeRe2", upSequnce:2, align: 'right' }, - { id: "dsInflWqltCod", title: "COD", upName:"upChangeRe2", upSequnce:3, align: 'right' }, - { id: "dsInflWqltSs", title: "SS", upName:"upChangeRe2", upSequnce:4, align: 'right' }, - { id: "dsInflWqltTn", title: "T-N", upName:"upChangeRe2", upSequnce:5, align: 'right' }, - { id: "dsInflWqltTp", title: "T-P", upName:"upChangeRe2", upSequnce:6, align: 'right' }, - { id: "sitArea", title: "부지면적\n(m²)", align: 'right'}, - { id: "trtDstrArea", title: "처리구역면적\n(ha)", align: 'right'}, - { id: "swrTrtPopl", title: "하수처리인구\n(인)", align: 'right'}, +const upHeadListPlanInfo: TableUpperProps[] = [ + { id: "plInflWqltBod", title: "BOD", upName: "upChangeRe1", upSequnce: 1, align: 'right' }, + { id: "plInflWqltToc", title: "TOC", upName: "upChangeRe1", upSequnce: 2, align: 'right' }, + { id: "plInflWqltCod", title: "COD", upName: "upChangeRe1", upSequnce: 3, align: 'right' }, + { id: "plInflWqltSs", title: "SS", upName: "upChangeRe1", upSequnce: 4, align: 'right' }, + { id: "plInflWqltTn", title: "T-N", upName: "upChangeRe1", upSequnce: 5, align: 'right' }, + { id: "plInflWqltTp", title: "T-P", upName: "upChangeRe1", upSequnce: 6, align: 'right' }, + { id: "dsInflWqltBod", title: "BOD", upName: "upChangeRe2", upSequnce: 1, align: 'right' }, + { id: "dsInflWqltToc", title: "TOC", upName: "upChangeRe2", upSequnce: 2, align: 'right' }, + { id: "dsInflWqltCod", title: "COD", upName: "upChangeRe2", upSequnce: 3, align: 'right' }, + { id: "dsInflWqltSs", title: "SS", upName: "upChangeRe2", upSequnce: 4, align: 'right' }, + { id: "dsInflWqltTn", title: "T-N", upName: "upChangeRe2", upSequnce: 5, align: 'right' }, + { id: "dsInflWqltTp", title: "T-P", upName: "upChangeRe2", upSequnce: 6, align: 'right' }, + { id: "sitArea", title: "부지면적\n(m²)", align: 'right' }, + { id: "trtDstrArea", title: "처리구역면적\n(ha)", align: 'right' }, + { id: "swrTrtPopl", title: "하수처리인구\n(인)", align: 'right' }, ]; // 시설 계획정보 (리스트) -const gridListPlanInfo:PlanInfoProps[] = [ +const gridListPlanInfo: PlanInfoProps[] = [ { - plInflWqltBod : "179.0", - plInflWqltToc : "90.0", - plInflWqltCod : "0.0", - plInflWqltSs : "132.0", - plInflWqltTn : "38.000", - plInflWqltTp : "4.300", - dsInflWqltBod : "178.0", - dsInflWqltToc : "91.0", - dsInflWqltCod : "0.0", - dsInflWqltSs : "131.0", - dsInflWqltTn : "40.200", - dsInflWqltTp : "4.500", - sitArea : "928,574", - trtDstrArea : "7,994.0", - swrTrtPopl : "1,573,277", + plInflWqltBod: "179.0", + plInflWqltToc: "90.0", + plInflWqltCod: "0.0", + plInflWqltSs: "132.0", + plInflWqltTn: "38.000", + plInflWqltTp: "4.300", + dsInflWqltBod: "178.0", + dsInflWqltToc: "91.0", + dsInflWqltCod: "0.0", + dsInflWqltSs: "131.0", + dsInflWqltTn: "40.200", + dsInflWqltTp: "4.500", + sitArea: "928,574", + trtDstrArea: "7,994.0", + swrTrtPopl: "1,573,277", } ]; // 시설 수역 및 구역정보 (헤더) -const upHeadListFcltyAreaInfo:TableUpperProps[] = [ +const upHeadListFcltyAreaInfo: TableUpperProps[] = [ { id: "rvbsn", title: "하천명" }, - { id: "efflWtrrgn", title: "방류수역"}, - { id: "lgbsn", title: "단위유역"}, - { id: "efflWqltStndrdNm", title: "지역구분"}, - { id: "rgnNm", title: "관할 유역(지방) 환경청"} + { id: "efflWtrrgn", title: "방류수역" }, + { id: "lgbsn", title: "단위유역" }, + { id: "efflWqltStndrdNm", title: "지역구분" }, + { id: "rgnNm", title: "관할 유역(지방) 환경청" } ]; // 시설 수역 및 구역정보 (리스트) -const gridListFcltyAreaInfo:fcltyAreaInfoProps[] = [ +const gridListFcltyAreaInfo: fcltyAreaInfoProps[] = [ { - rvbsn : "한강", - efflWtrrgn : "한강수계", - lgbsn : "한강본류", - efflWqltStndrdNm : "500톤 이상\n(Ⅲ지역)", - rgnNm : "한강유역환경청" + rvbsn: "한강", + efflWtrrgn: "한강수계", + lgbsn: "한강본류", + efflWqltStndrdNm: "500톤 이상\n(Ⅲ지역)", + rgnNm: "한강유역환경청" } ]; // 시설 이력관리 (헤더) -const upHeadListFcltyHistInfo:TableUpperProps[] = [ +const upHeadListFcltyHistInfo: TableUpperProps[] = [ { id: "extnsSeqno", title: "차수", align: 'center' }, - { id: "extnsNm", title: "구분"}, - { id: "bzStrtYrMnth", title: "사업기간", upName:"upChangeRe1", upSequnce:1}, - { id: "bzEdYrMnth", title: "사업기간", upName:"upChangeRe1", upSequnce:2}, - { id: "eqpPrmsDt", title: "설치인가일"}, - { id: "cmplDt", title: "준공일"}, - { id: "trlrnCmplDt", title: "시운전완료일"}, - { id: "rnDt", title: "가동개시일"}, + { id: "extnsNm", title: "구분" }, + { id: "bzStrtYrMnth", title: "사업기간", upName: "upChangeRe1", upSequnce: 1 }, + { id: "bzEdYrMnth", title: "사업기간", upName: "upChangeRe1", upSequnce: 2 }, + { id: "eqpPrmsDt", title: "설치인가일" }, + { id: "cmplDt", title: "준공일" }, + { id: "trlrnCmplDt", title: "시운전완료일" }, + { id: "rnDt", title: "가동개시일" }, { id: "fctCpc", title: "시설용량(m³/일)", align: 'right' }, ]; // 시설 이력관리 (리스트) -const gridListFcltyHistInfo:fcltyHistInfoProps[] = [ +const gridListFcltyHistInfo: fcltyHistInfoProps[] = [ { - extnsSeqno : "최초", - extnsNm : "최초", - bzStrtYrMnth : "1984.12.01", - bzEdYrMnth : "1987.06.01", - eqpPrmsDt : "1985.09.13", - cmplDt : "1987.06.30", - trlrnCmplDt : "1987.06.30", - rnDt : "1987.06.30", - sitArea : 0, - trtDstrArea : 0, - swrTrtPopl : 0, - fctCpc : 860000 + extnsSeqno: "최초", + extnsNm: "최초", + bzStrtYrMnth: "1984.12.01", + bzEdYrMnth: "1987.06.01", + eqpPrmsDt: "1985.09.13", + cmplDt: "1987.06.30", + trlrnCmplDt: "1987.06.30", + rnDt: "1987.06.30", + sitArea: 0, + trtDstrArea: 0, + swrTrtPopl: 0, + fctCpc: 860000 } ]; // 시설 수질정보 (헤더) -const upHeadListFcltyWaterQltyInfo:TableUpperProps[] = [ +const upHeadListFcltyWaterQltyInfo: TableUpperProps[] = [ { id: "extnsSeqno", title: "차수" }, - { id: "plInflWqltBod", title: "BOD", upName:"upChangeRe1", upSequnce:1, align: 'right' }, - { id: "plInflWqltToc", title: "TOC", upName:"upChangeRe1", upSequnce:2, align: 'right' }, - { id: "plInflWqltCod", title: "COD", upName:"upChangeRe1", upSequnce:3, align: 'right' }, - { id: "plInflWqltSs", title: "SS", upName:"upChangeRe1", upSequnce:4, align: 'right' }, - { id: "plInflWqltTn", title: "T-N", upName:"upChangeRe1", upSequnce:5, align: 'right' }, - { id: "plInflWqltTp", title: "T-P", upName:"upChangeRe1", upSequnce:6, align: 'right' }, - { id: "dsInflWqltBod", title: "BOD", upName:"upChangeRe2", upSequnce:1, align: 'right' }, - { id: "dsInflWqltToc", title: "TOC", upName:"upChangeRe2", upSequnce:2, align: 'right' }, - { id: "dsInflWqltCod", title: "COD", upName:"upChangeRe2", upSequnce:3, align: 'right' }, - { id: "dsInflWqltSs", title: "SS", upName:"upChangeRe2", upSequnce:4, align: 'right' }, - { id: "dsInflWqltTn", title: "T-N", upName:"upChangeRe2", upSequnce:5, align: 'right' }, - { id: "dsInflWqltTp", title: "T-P", upName:"upChangeRe2", upSequnce:6, align: 'right' }, - { id: "plEfflWqltBod", title: "BOD", upName:"upChangeRe3", upSequnce:1, align: 'right' }, - { id: "plEfflWqltToc", title: "TOC", upName:"upChangeRe3", upSequnce:2, align: 'right' }, - { id: "plEfflWqltCod", title: "COD", upName:"upChangeRe3", upSequnce:3, align: 'right' }, - { id: "plEfflWqltSs", title: "SS", upName:"upChangeRe3", upSequnce:4, align: 'right' }, - { id: "plEfflWqltTn", title: "T-N", upName:"upChangeRe3", upSequnce:5, align: 'right' }, - { id: "plEfflWqltTp", title: "T-P", upName:"upChangeRe3", upSequnce:6, align: 'right' }, + { id: "plInflWqltBod", title: "BOD", upName: "upChangeRe1", upSequnce: 1, align: 'right' }, + { id: "plInflWqltToc", title: "TOC", upName: "upChangeRe1", upSequnce: 2, align: 'right' }, + { id: "plInflWqltCod", title: "COD", upName: "upChangeRe1", upSequnce: 3, align: 'right' }, + { id: "plInflWqltSs", title: "SS", upName: "upChangeRe1", upSequnce: 4, align: 'right' }, + { id: "plInflWqltTn", title: "T-N", upName: "upChangeRe1", upSequnce: 5, align: 'right' }, + { id: "plInflWqltTp", title: "T-P", upName: "upChangeRe1", upSequnce: 6, align: 'right' }, + { id: "dsInflWqltBod", title: "BOD", upName: "upChangeRe2", upSequnce: 1, align: 'right' }, + { id: "dsInflWqltToc", title: "TOC", upName: "upChangeRe2", upSequnce: 2, align: 'right' }, + { id: "dsInflWqltCod", title: "COD", upName: "upChangeRe2", upSequnce: 3, align: 'right' }, + { id: "dsInflWqltSs", title: "SS", upName: "upChangeRe2", upSequnce: 4, align: 'right' }, + { id: "dsInflWqltTn", title: "T-N", upName: "upChangeRe2", upSequnce: 5, align: 'right' }, + { id: "dsInflWqltTp", title: "T-P", upName: "upChangeRe2", upSequnce: 6, align: 'right' }, + { id: "plEfflWqltBod", title: "BOD", upName: "upChangeRe3", upSequnce: 1, align: 'right' }, + { id: "plEfflWqltToc", title: "TOC", upName: "upChangeRe3", upSequnce: 2, align: 'right' }, + { id: "plEfflWqltCod", title: "COD", upName: "upChangeRe3", upSequnce: 3, align: 'right' }, + { id: "plEfflWqltSs", title: "SS", upName: "upChangeRe3", upSequnce: 4, align: 'right' }, + { id: "plEfflWqltTn", title: "T-N", upName: "upChangeRe3", upSequnce: 5, align: 'right' }, + { id: "plEfflWqltTp", title: "T-P", upName: "upChangeRe3", upSequnce: 6, align: 'right' }, ]; // 시설 수질정보 (리스트) -const gridListFcltyWaterQltyInfo:fcltyWaterQltyInfoProps[] = [ +const gridListFcltyWaterQltyInfo: fcltyWaterQltyInfoProps[] = [ { extnsSeqno: "최초", plInflWqltBod: "111.0", @@ -411,11 +406,20 @@ const gridListFcltyWaterQltyInfo:fcltyWaterQltyInfoProps[] = [ * Store - api (데이터 호출) ====================================*/ -// 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) -export const fetchFacilityListInit = async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string ): Promise<{data:facilityListProps[], count:number}> => { +/** + * 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우) + * @param pageNo : 페이지 번호 + * @param pageSize : 페이지 크기 + * @param partValue : 구분값(행정명, 대유역, 환경청) + * @param nameCd : 행정코드(시도명, 시군구명, 단위유역) + * @param fcltCpct : 시설용량 + * @param oprtngSttsCd : 운영 상태 코드 + * @param facilityName : 시설명 + */ +export const fetchFacilityListInit = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => { try { - const tailStr = partValue ? '/'+ (partValue==='G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; - const url = '/prcsFclt/info/'+pageNo+'/'+pageSize+tailStr; + const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; + const url = '/prcsFclt/info/' + pageNo + '/' + pageSize + tailStr; const res = await getFetch('fo', url); res.data.forEach((item: Record) => { item.daddr = item.addr ? item.addr : ''; @@ -427,42 +431,42 @@ export const fetchFacilityListInit = async (pageNo:number, pageSize:number, part return res; } catch (error) { console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data: [], count: 0}; + return { data: [], count: 0 }; } }; -const fetchFacilityList = async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string ): Promise<{data:facilityListProps[], count:number}> => { +const fetchFacilityList = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => { try { - const tailStr = partValue ? '/'+ (partValue==='G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; - const url = '/prcsFclt/info/history/'+pageNo+'/'+pageSize+tailStr; + const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; + const url = '/prcsFclt/info/history/' + pageNo + '/' + pageSize + tailStr; //const res = await getFetch('fo', '/prcsFclt/info/'+pageNo+'/'+pageSize+tailUrl); const res = await getFetch('fo', url); return res; } catch (error) { console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data: [], count: 0}; + return { data: [], count: 0 }; } }; // 시설정보 리스트 데이터 호출 (대시보드용) -const fetchFacilityListSearching = async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string ): Promise<{data:facilityListProps[], count:number}> => { +const fetchFacilityListSearching = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => { try { - const tailStr = partValue ? '/'+ (partValue==='G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; - const url = '/prcsFclt/searching/'+pageNo+'/'+pageSize+tailStr; + const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : ''; + const url = '/prcsFclt/searching/' + pageNo + '/' + pageSize + tailStr; //const res = await getFetch('fo', '/prcsFclt/info/'+pageNo+'/'+pageSize+tailUrl); const res = await getFetch('fo', url); return res; } catch (error) { console.error('시설정보 데이터를 가져오는데 실패했습니다:', error); - return {data: [], count: 0}; + return { data: [], count: 0 }; } }; // 모달 // 시설정보 이력정보 데이터 호출 -const fetchFacilityHistInfo = async (facilityCd:string ): Promise => { +const fetchFacilityHistInfo = async (facilityCd: string): Promise => { try { - const res = await getFetch('fo', '/prcsFclt/hist/'+facilityCd); + const res = await getFetch('fo', '/prcsFclt/hist/' + facilityCd); const data = res.data; DataForm({ type: 'date', column: 'trlrnCmplDt', item: data as unknown as Record }); DataForm({ type: 'date', column: 'eqpPrmsDt', item: data as unknown as Record }); @@ -471,7 +475,7 @@ const fetchFacilityHistInfo = async (facilityCd:string ): Promise }); DataForm({ type: 'number', column: 'trtDstrArea', item: data as unknown as Record }); DataForm({ type: 'number', column: 'swrTrtPopl', item: data as unknown as Record }); - return data; + return data; } catch (error) { console.error('시설정보 이력정보 데이터를 가져오는데 실패했습니다:', error); return []; @@ -479,9 +483,9 @@ const fetchFacilityHistInfo = async (facilityCd:string ): Promise => { +export const fetchFacilityWaterQltyInfo = async (facilityCd: string): Promise => { try { - const res = await getFetch('fo', '/prcsFclt/info/history/'+facilityCd); + const res = await getFetch('fo', '/prcsFclt/info/history/' + facilityCd); const data = res.data; return data; } catch (error) { @@ -504,97 +508,97 @@ export type ProcessFacilityActions = { * @param oprtngSttsCd : 운영 상태 코드 * @param facilityName : 시설명 */ - searchProcessFacility : (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => void; + searchProcessFacility: (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => void; /** * 시설정보 이력정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityHist : (facilityCd:string) => void; + searchProcessFacilityHist: (facilityCd: string) => void; /** * 시설정보 수질정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityWaterQlty : (facilityCd:string) => void; + searchProcessFacilityWaterQlty: (facilityCd: string) => void; /** * 시설정보 리스트 데이터 호출 (대시보드용) * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessFacilitySearching : (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => void; + searchProcessFacilitySearching: (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => void; } export type ProcessFacilityType = { ProcessFacility: { isInit: boolean; - processFacilityLabelArray:string[]; + processFacilityLabelArray: string[]; }, - ProcessFacilityList : { + ProcessFacilityList: { isInit: boolean; - upHeadList1:TableUpperProps[]; - upHeadList2:TableUpperProps[]; - upHeadList3:TableUpperProps[]; - processFacilityList:facilityListProps[]; - processFacilityCount:number; - excelList : ExcelType[]; + upHeadList1: TableUpperProps[]; + upHeadList2: TableUpperProps[]; + upHeadList3: TableUpperProps[]; + processFacilityList: facilityListProps[]; + processFacilityCount: number; + excelList: ExcelType[]; isLoading: boolean; }, - ProcessFacilityDetail : { - isInit : boolean; - upHeadListBasicInfo : TableUpperProps[]; - gridListBasicInfo : BasicInfoProps[]; - upHeadListPlanInfo : TableUpperProps[]; - gridListPlanInfo : PlanInfoProps[]; - upHeadListFcltyAreaInfo : TableUpperProps[]; - gridListFcltyAreaInfo : fcltyAreaInfoProps[]; - - upHeadListFcltyHistInfo : TableUpperProps[]; - gridListFcltyHistInfo : fcltyHistInfoProps[]; - upHeadListFcltyWaterQltyInfo : TableUpperProps[]; - gridListFcltyWaterQltyInfo : fcltyWaterQltyInfoProps[]; + ProcessFacilityDetail: { + isInit: boolean; + upHeadListBasicInfo: TableUpperProps[]; + gridListBasicInfo: BasicInfoProps[]; + upHeadListPlanInfo: TableUpperProps[]; + gridListPlanInfo: PlanInfoProps[]; + upHeadListFcltyAreaInfo: TableUpperProps[]; + gridListFcltyAreaInfo: fcltyAreaInfoProps[]; - upHeadListLegalWaterQlty : TableUpperProps[]; - gridListLegalWaterQlty : LegalWaterQltyProps[]; + upHeadListFcltyHistInfo: TableUpperProps[]; + gridListFcltyHistInfo: fcltyHistInfoProps[]; + upHeadListFcltyWaterQltyInfo: TableUpperProps[]; + gridListFcltyWaterQltyInfo: fcltyWaterQltyInfoProps[]; + + upHeadListLegalWaterQlty: TableUpperProps[]; + gridListLegalWaterQlty: LegalWaterQltyProps[]; }, } -export const processFacilityInitState:ProcessFacilityType = { +export const processFacilityInitState: ProcessFacilityType = { ProcessFacility: { isInit: false, processFacilityLabelArray: ProcessFacilityLabelArray, }, - ProcessFacilityList : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - processFacilityList : processFacilityList, - processFacilityCount:1, - excelList : [], - isLoading : true, + ProcessFacilityList: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + processFacilityList: processFacilityList, + processFacilityCount: 1, + excelList: [], + isLoading: true, }, - ProcessFacilityDetail : { - isInit : false, - upHeadListBasicInfo : upHeadListBasicInfo, - gridListBasicInfo : gridListBasicInfo, - upHeadListPlanInfo : upHeadListPlanInfo, - gridListPlanInfo : gridListPlanInfo, - upHeadListFcltyAreaInfo : upHeadListFcltyAreaInfo, - gridListFcltyAreaInfo : gridListFcltyAreaInfo, + ProcessFacilityDetail: { + isInit: false, + upHeadListBasicInfo: upHeadListBasicInfo, + gridListBasicInfo: gridListBasicInfo, + upHeadListPlanInfo: upHeadListPlanInfo, + gridListPlanInfo: gridListPlanInfo, + upHeadListFcltyAreaInfo: upHeadListFcltyAreaInfo, + gridListFcltyAreaInfo: gridListFcltyAreaInfo, - upHeadListFcltyHistInfo : upHeadListFcltyHistInfo, - gridListFcltyHistInfo : gridListFcltyHistInfo, - upHeadListFcltyWaterQltyInfo : upHeadListFcltyWaterQltyInfo, - gridListFcltyWaterQltyInfo : gridListFcltyWaterQltyInfo, + upHeadListFcltyHistInfo: upHeadListFcltyHistInfo, + gridListFcltyHistInfo: gridListFcltyHistInfo, + upHeadListFcltyWaterQltyInfo: upHeadListFcltyWaterQltyInfo, + gridListFcltyWaterQltyInfo: gridListFcltyWaterQltyInfo, - upHeadListLegalWaterQlty : upHeadListLegalWaterQlty, - gridListLegalWaterQlty : gridListLegalWaterQlty, + upHeadListLegalWaterQlty: upHeadListLegalWaterQlty, + gridListLegalWaterQlty: gridListLegalWaterQlty, } } @@ -603,8 +607,8 @@ type SetStateFunction = (state: ProcessFacilityType | ((state: ProcessFacilityTy export type ProcessFacilityStore = ProcessFacilityType & ProcessFacilityActions; -export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActions=(set: SetStateFunction) => { - return{ +export const processFacilityReducer: (set: SetStateFunction) => ProcessFacilityActions = (set: SetStateFunction) => { + return { // 메인페이지 /** @@ -612,7 +616,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessFacility: async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => { + searchProcessFacility: async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => { set((state: ProcessFacilityType) => ({ ...state, ProcessFacilityList: { @@ -621,12 +625,12 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }, })); const res = await fetchFacilityList(pageNo, pageSize, partValue, nameCd, fcltCpct, oprtngSttsCd, facilityPartValue, facilityName); - res.data.forEach((item:facilityListProps) => { - DataForm({ type: 'date', column: 'cmplDt', item:item as unknown as Record}); - DataForm({ type: 'date', column: 'rnDt', item:item as unknown as Record}); - DataForm({ type: 'float0', column: 'fctCpc', item:item as unknown as Record}); + res.data.forEach((item: facilityListProps) => { + DataForm({ type: 'date', column: 'cmplDt', item: item as unknown as Record }); + DataForm({ type: 'date', column: 'rnDt', item: item as unknown as Record }); + DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record }); }) - + res.data.forEach(item => { item.plInflWqltBod = item.plInflWqltBod ? Number(item.plInflWqltBod).toFixed(1) : ''; item.dsInflWqltBod = item.dsInflWqltBod ? Number(item.dsInflWqltBod).toFixed(1) : ''; @@ -634,7 +638,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio const excelDownList: ExcelType[] = []; - if(pageSize>5000){ + if (pageSize > 5000) { res.data.forEach(item => { excelDownList.push({ 시설코드: item.bscFctCd, @@ -646,7 +650,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio 시군구: item.gugun, 시설이름: item.bscFctNm, 주소: item.daddr, - "시설용량(m³/일)": item.fctCpc ? Number(item.fctCpc.toString().replaceAll(',','')) : '', + "시설용량(m³/일)": item.fctCpc ? Number(item.fctCpc.toString().replaceAll(',', '')) : '', "계획유입수질(mg/L)": item.plInflWqltBod ? Number(item.plInflWqltBod) : '', "설계유입수질(mg/L)": item.dsInflWqltBod ? Number(item.dsInflWqltBod) : '', 공법: item.trtFrfNm, @@ -656,27 +660,27 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }) }) } - set((state:ProcessFacilityType) => ({ - ...state, - ProcessFacilityList: pageSize<5000?{ - ...state.ProcessFacilityList, - processFacilityList: res.data, - processFacilityCount: res.count, - isLoading: false, - }:{ - ...state.ProcessFacilityList, - excelList: excelDownList, - isLoading: false, - }, + set((state: ProcessFacilityType) => ({ + ...state, + ProcessFacilityList: pageSize < 5000 ? { + ...state.ProcessFacilityList, + processFacilityList: res.data, + processFacilityCount: res.count, + isLoading: false, + } : { + ...state.ProcessFacilityList, + excelList: excelDownList, + isLoading: false, + }, })) }, - + /** * 시설정보 리스트 데이터 호출 * @param pageNo : 페이지 번호 * @param pageSize : 페이지 크기 */ - searchProcessFacilitySearching: async (pageNo:number, pageSize:number, partValue?:string, nameCd?:string, fcltCpct?:string, oprtngSttsCd?:string, facilityPartValue?:string, facilityName?:string) => { + searchProcessFacilitySearching: async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string) => { set((state: ProcessFacilityType) => ({ ...state, ProcessFacilityList: { @@ -694,24 +698,24 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio item.plInflWqltBod = item.plInflWqltBod ? Number(item.plInflWqltBod).toFixed(1) : ''; item.dsInflWqltBod = item.dsInflWqltBod ? Number(item.dsInflWqltBod).toFixed(1) : ''; }) */ - set((state:ProcessFacilityType) => ({ - ...state, - ProcessFacilityList: { - ...state.ProcessFacilityList, - processFacilityList: res.data, - processFacilityCount: res.count, - isLoading: false, - }, + set((state: ProcessFacilityType) => ({ + ...state, + ProcessFacilityList: { + ...state.ProcessFacilityList, + processFacilityList: res.data, + processFacilityCount: res.count, + isLoading: false, + }, })) }, - + // 모달 이력정보 /** * 시설정보 이력정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityHist: async (facilityCd:string) => { + searchProcessFacilityHist: async (facilityCd: string) => { const promiseSet = await Promise.all([fetchFacilityHistInfo(facilityCd)]); const [facilityHistInfo] = promiseSet; // extnsSeqno를 기준으로 오름차순 정렬 @@ -727,7 +731,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }); sortedHistInfo.forEach(item => { - if(item.extnsSeqno == '0'){ + if (item.extnsSeqno == '0') { item.extnsSeqno = '최초'; item.extnsNm = '신설'; } @@ -735,10 +739,10 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio // yyyy-MM-dd로 변환 sortedHistInfo.forEach(item => { - item.eqpPrmsDt = item.eqpPrmsDt ? item.eqpPrmsDt.substring(0,4) + '-' + item.eqpPrmsDt.substring(4,6) + '-' + item.eqpPrmsDt.substring(6,8) : ''; - item.trlrnCmplDt = item.trlrnCmplDt ? item.trlrnCmplDt.substring(0,4) + '-' + item.trlrnCmplDt.substring(4,6) + '-' + item.trlrnCmplDt.substring(6,8) : ''; - item.cmplDt = item.cmplDt ? item.cmplDt.substring(0,4) + '-' + item.cmplDt.substring(4,6) + '-' + item.cmplDt.substring(6,8) : ''; - item.rnDt = item.rnDt ? item.rnDt.substring(0,4) + '-' + item.rnDt.substring(4,6) + '-' + item.rnDt.substring(6,8) : ''; + item.eqpPrmsDt = item.eqpPrmsDt ? item.eqpPrmsDt.substring(0, 4) + '-' + item.eqpPrmsDt.substring(4, 6) + '-' + item.eqpPrmsDt.substring(6, 8) : ''; + item.trlrnCmplDt = item.trlrnCmplDt ? item.trlrnCmplDt.substring(0, 4) + '-' + item.trlrnCmplDt.substring(4, 6) + '-' + item.trlrnCmplDt.substring(6, 8) : ''; + item.cmplDt = item.cmplDt ? item.cmplDt.substring(0, 4) + '-' + item.cmplDt.substring(4, 6) + '-' + item.cmplDt.substring(6, 8) : ''; + item.rnDt = item.rnDt ? item.rnDt.substring(0, 4) + '-' + item.rnDt.substring(4, 6) + '-' + item.rnDt.substring(6, 8) : ''; }); // 마지막 이력 데이터의 값을 gridListPlanInfo에 업데이트 @@ -779,7 +783,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio * 시설정보 수질정보 데이터 호출 * @param facilityCd : 시설코드 */ - searchProcessFacilityWaterQlty: async (facilityCd:string) => { + searchProcessFacilityWaterQlty: async (facilityCd: string) => { const promiseSet = await Promise.all([fetchFacilityWaterQltyInfo(facilityCd)]); const [facilityWaterQltyInfo] = promiseSet; // extnsSeqno를 기준으로 오름차순 정렬 @@ -795,7 +799,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio }); sortedWaterQltyInfo.forEach(item => { - if(item.extnsSeqno == '0'){ + if (item.extnsSeqno == '0') { item.extnsSeqno = '최초'; } }); @@ -814,7 +818,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio DataForm({ type: 'float1', column: 'dsInflWqltSs', item: item as unknown as Record }); DataForm({ type: 'float3', column: 'dsInflWqltTn', item: item as unknown as Record }); DataForm({ type: 'float3', column: 'dsInflWqltTp', item: item as unknown as Record }); - + DataForm({ type: 'float1', column: 'plEfflWqltBod', item: item as unknown as Record }); DataForm({ type: 'float1', column: 'plEfflWqltToc', item: item as unknown as Record }); DataForm({ type: 'float1', column: 'plEfflWqltCod', item: item as unknown as Record }); @@ -829,10 +833,10 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio gridListLegalWaterQlty.push({ bod: facilityWaterQltyInfo[0]?.bod ?? 0, cod: Number(facilityWaterQltyInfo[0]?.cod ?? 0), - ss: Number(facilityWaterQltyInfo[0]?.ss ?? 0), + ss: Number(facilityWaterQltyInfo[0]?.ss ?? 0), tn: Number(facilityWaterQltyInfo[0]?.tn ?? 0), tp: Number(facilityWaterQltyInfo[0]?.tp ?? 0), - totClfgrpcnt : Number(facilityWaterQltyInfo[0]?.totClfgrpcnt ?? 0), + totClfgrpcnt: Number(facilityWaterQltyInfo[0]?.totClfgrpcnt ?? 0), }); gridListLegalWaterQlty.forEach(item => { @@ -851,7 +855,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio ProcessFacilityDetail: { ...state.ProcessFacilityDetail, gridListFcltyWaterQltyInfo: sortedWaterQltyInfo, - gridListLegalWaterQlty: gridListLegalWaterQlty, + gridListLegalWaterQlty: gridListLegalWaterQlty, gridListPlanInfo: [{ ...state.ProcessFacilityDetail.gridListPlanInfo[0], dsInflWqltBod: lastWaterQltyInfo?.dsInflWqltBod === 'NULL' || lastWaterQltyInfo?.dsInflWqltBod === undefined ? '' : lastWaterQltyInfo.dsInflWqltBod, @@ -875,7 +879,7 @@ export const processFacilityReducer:(set:SetStateFunction)=>ProcessFacilityActio ProcessFacilityDetail: { ...state.ProcessFacilityDetail, gridListFcltyWaterQltyInfo: sortedWaterQltyInfo, - gridListLegalWaterQlty: gridListLegalWaterQlty, + gridListLegalWaterQlty: gridListLegalWaterQlty, gridListPlanInfo: [{ ...state.ProcessFacilityDetail.gridListPlanInfo[0], dsInflWqltBod: '', diff --git a/apps/fo/app/store/sewageOccur/index.tsx b/apps/fo/app/store/sewageOccur/index.tsx index 69d2a4f50..e9857af71 100644 --- a/apps/fo/app/store/sewageOccur/index.tsx +++ b/apps/fo/app/store/sewageOccur/index.tsx @@ -5,58 +5,55 @@ import { OSU_PERCENT } from "../common"; import type { TableUpperProps } from "../dashboard"; import { fetchFacilityListInit } from "../processFacility"; export type { TableUpperProps }; -/**==================================== - * Store - 타입 - ====================================*/ /** - * (1) 메인페이지 + * 운영실태 >오수발생량 추정 */ // 시설별 강수현황 export type SewageOccurProps = { - bscFctCd : string, - sidoNm : string, - sggNm : string, - lclgvrnmntNm : string, - bscFctNm : string, - daddr : string, - fctCpc : number, - waterUsage : number, - swageChangePercent : number, - estimationSewage : number, - sewageInputYear : number, - sewageInputChungchun : number, - rgnNm : string, - rvbsn : string, - lgbsn : string, - mdmbsn : string, - msrDt : string, + bscFctCd: string, + sidoNm: string, + sggNm: string, + lclgvrnmntNm: string, + bscFctNm: string, + daddr: string, + fctCpc: number, + waterUsage: number, + swageChangePercent: number, + estimationSewage: number, + sewageInputYear: number, + sewageInputChungchun: number, + rgnNm: string, + rvbsn: string, + lgbsn: string, + mdmbsn: string, + msrDt: string, } -export type modalTableType = { msrDt: string,waterUsage: number,swageChangePercent: number,estimationSewage: number}; +export type modalTableType = { msrDt: string, waterUsage: number, swageChangePercent: number, estimationSewage: number }; export type SewageOccurDetailProps = { -cnt : number, - sum : number, - yr:string, - usage:number, // 일평균 유입량 - cntWtrUsg : number, // 물사용량 일자수 - sumWtrUsg : number, // 물사용량 합 - avgWtrUsg:number, // 일평균 물사용량 - monWtrUsg:number, // 월 물사용량 + cnt: number, + sum: number, + yr: string, + usage: number, // 일평균 유입량 + cntWtrUsg: number, // 물사용량 일자수 + sumWtrUsg: number, // 물사용량 합 + avgWtrUsg: number, // 일평균 물사용량 + monWtrUsg: number, // 월 물사용량 } export type WtrUsgYmProps = { - bscFctCd : string, // 처리구역시설코드 - levyYm : string, // 부과년월 - wtrUsg : number, // 월별 물사용량(m³/월) + bscFctCd: string, // 처리구역시설코드 + levyYm: string, // 부과년월 + wtrUsg: number, // 월별 물사용량(m³/월) } // 검색단 -const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; +const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별']; export interface ExcelType { 시설코드: string, - 권역:string|'', - 단위유역:string|'', - 중권역:string|'', - 환경청:string|'', + 권역: string | '', + 단위유역: string | '', + 중권역: string | '', + 환경청: string | '', 시도: string, 시군구: string, 시설명: string, @@ -70,64 +67,64 @@ export interface ExcelType { } // 리스트 헤더 -const upHeadList1:TableUpperProps[] = [ - { id: "A", title: "행정구역", row:0, colSpan: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, 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 upHeadList1: TableUpperProps[] = [ + { id: "A", title: "행정구역", row: 0, colSpan: 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, 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: "권역", 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, 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 upHeadList2: TableUpperProps[] = [ + { id: "A", title: "유역", row: 0, colSpan: 3 }, + { 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, 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: "권역", 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: "시도", 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, 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 upHeadList3: TableUpperProps[] = [ + { id: "A", title: "유역", row: 0, colSpan: 3 }, + { 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: "시도", 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, 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[] = [ +const upHeadListSewageOccurDetail: TableUpperProps[] = [ { id: "msrDt", title: "년월" }, - { id: "waterUsage", title: "물사용량(m³/일)", align:"right" }, - { id: "swageChangePercent", title: "오수전환율(%)", align:"right" }, - { id: "estimationSewage", title: "오수발생량 추정(m³/일)", row:0, rowSpan:2, align:"right" }, + { id: "waterUsage", title: "물사용량(m³/일)", align: "right" }, + { id: "swageChangePercent", title: "오수전환율(%)", align: "right" }, + { id: "estimationSewage", title: "오수발생량 추정(m³/일)", row: 0, rowSpan: 2, align: "right" }, ]; -const sewageOccurList:SewageOccurProps[] = [] +const sewageOccurList: SewageOccurProps[] = [] -const tempSewageOccurList:modalTableType[] = [] +const tempSewageOccurList: modalTableType[] = [] /** * yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환 @@ -135,20 +132,20 @@ const tempSewageOccurList:modalTableType[] = [] * @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31) */ function getDaysInMonth(yyyymm) { - if (typeof yyyymm !== 'string' || yyyymm.length !== 6) { - throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'"); - } + if (typeof yyyymm !== 'string' || yyyymm.length !== 6) { + throw new Error("입력은 'yyyymm' 형식의 문자열이어야 합니다. 예: '202502'"); + } - const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025 - const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2 + const year = parseInt(yyyymm.slice(0, 4), 10); // "2025" -> 2025 + const month = parseInt(yyyymm.slice(4, 6), 10); // "02" -> 2 - if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { - throw new Error("유효한 년/월이 아닙니다."); - } + if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { + throw new Error("유효한 년/월이 아닙니다."); + } - // Date(year, month, 0) -> 전달의 마지막 날 - // month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨 - return new Date(year, month, 0).getDate(); + // Date(year, month, 0) -> 전달의 마지막 날 + // month에 '다음달'을 넣고, 일(day)에 0을 주면 해당 월의 마지막 날짜가 됨 + return new Date(year, month, 0).getDate(); } /**==================================== * Store - API @@ -174,9 +171,9 @@ function getDaysInMonth(yyyymm) { // } // 시설들 유량 정보 조회 -export const fetchSweageOccurListFlow = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +export const fetchSweageOccurListFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설정보 오수발생량 상세 데이터를 가져오는데 실패했습니다:', error); @@ -184,9 +181,9 @@ export const fetchSweageOccurListFlow = async (searchYear: string|undefined, fcl } }; // 시설별 물사용량 정보 조회 -export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise => { +export const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise => { try { - const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/'+searchYear, fcltCdList); + const res = await postFetch('fo', '/fclt/flow/wtrUsgYm/' + searchYear, fcltCdList); return res; } catch (error) { console.error('시설들 월별 물사용량 데이터를 가져오는데 실패했습니다:', error); @@ -205,10 +202,10 @@ export type SewageOccurActions = { export type SewageOccurType = { SewageOccurSearch: { isInit: boolean; - labelArray:string[]; + labelArray: string[]; }, - SewageOccur : { + SewageOccur: { isInit: boolean; upHeadList1: TableUpperProps[]; upHeadList2: TableUpperProps[]; @@ -219,7 +216,7 @@ export type SewageOccurType = { isLoading: boolean; }, - SewageOccurDetail : { + SewageOccurDetail: { isInit: boolean; upHeadListSewageOccurDetail: TableUpperProps[]; gridListSewageOccurDetail: modalTableType[]; @@ -232,18 +229,18 @@ export const sewageOccurInitState: SewageOccurType = { labelArray: LabelArray, }, - SewageOccur : { - isInit : false, - upHeadList1 : upHeadList1, - upHeadList2 : upHeadList2, - upHeadList3 : upHeadList3, - sewageOccurList : sewageOccurList, - sewageOccurCount : 2, - excelList : [], - isLoading : true, + SewageOccur: { + isInit: false, + upHeadList1: upHeadList1, + upHeadList2: upHeadList2, + upHeadList3: upHeadList3, + sewageOccurList: sewageOccurList, + sewageOccurCount: 2, + excelList: [], + isLoading: true, }, - SewageOccurDetail : { + SewageOccurDetail: { isInit: false, upHeadListSewageOccurDetail: upHeadListSewageOccurDetail, gridListSewageOccurDetail: tempSewageOccurList, @@ -277,69 +274,69 @@ export type FlowResponse = { count: number; } -export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { +export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) => { return { searchSewageOccurList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => { const facilityInitData = await fetchFacilityListInit(pageNo, pageSize, part, nameCd, fcltCpct, operationValue, fcltyNm); - if(pageSize < 5000){ + if (pageSize < 5000) { set((state: SewageOccurType) => ({ ...state, SewageOccur: { ...state.SewageOccur, - sewageOccurList : [], - sewageOccurCount : facilityInitData.count, - excelList : [], + sewageOccurList: [], + sewageOccurCount: facilityInitData.count, + excelList: [], isLoading: true }, })); - }else{ + } else { set((state: SewageOccurType) => ({ ...state, SewageOccur: { ...state.SewageOccur, - excelList : [], + excelList: [], isLoading: true }, })); } - + const fcltylist = facilityInitData.data; // 시설목록 - const fcltCdList : string[] = []; // 시설코드목록 - const sewageOccurPropsList : SewageOccurProps[] = []; // 오수발생량시설목록 + const fcltCdList: string[] = []; // 시설코드목록 + const sewageOccurPropsList: SewageOccurProps[] = []; // 오수발생량시설목록 fcltylist.forEach(item => { fcltCdList.push(item.bscFctCd); sewageOccurPropsList.push({ - bscFctCd : item.bscFctCd, - sidoNm : item.sido, - sggNm : item.gugun, - lclgvrnmntNm : '', - bscFctNm : item.bscFctNm, - daddr : item.daddr, - fctCpc : parseFloat(item.fctCpc.toString().replace(/,/g, '')), - waterUsage : 0, - swageChangePercent : 0, - estimationSewage : 0, - sewageInputYear : 0, - sewageInputChungchun : 0, - rgnNm : item.rgnNm, - rvbsn : item.rvbsn, - lgbsn : item.lgbsn, - mdmbsn : item.mdmbsn, - msrDt : '', + bscFctCd: item.bscFctCd, + sidoNm: item.sido, + sggNm: item.gugun, + lclgvrnmntNm: '', + bscFctNm: item.bscFctNm, + daddr: item.daddr, + fctCpc: parseFloat(item.fctCpc.toString().replace(/,/g, '')), + waterUsage: 0, + swageChangePercent: 0, + estimationSewage: 0, + sewageInputYear: 0, + sewageInputChungchun: 0, + rgnNm: item.rgnNm, + rvbsn: item.rvbsn, + lgbsn: item.lgbsn, + mdmbsn: item.mdmbsn, + msrDt: '', }); }); - - const soccurDetailRes : any = await fetchSweageOccurListFlow(searchYear, fcltCdList); - const wtrUsgYmRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); + + const soccurDetailRes: any = await fetchSweageOccurListFlow(searchYear, fcltCdList); + const wtrUsgYmRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); // const wtrUsgMap : Record = {}; // wtrUsgRes.data.forEach(fclt => { // wtrUsgMap[fclt.bscFctCd] = fclt.wtrUsg; // }); for (const item of sewageOccurPropsList) { - + const detailList = soccurDetailRes?.data[item.bscFctCd]; const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd]; - + item.swageChangePercent = 90; let sumChungcunDay = 0; // 청천일수 let chungcunSumFlow = 0;// 청천시 하수유입량 @@ -348,18 +345,18 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { detailList?.forEach(item2 => { if (item2.infoRnDay == null || item2.infoRnDay == 'x') item2.infoRnDay = 0; - if(item2.infoRnDay >= 3) { + if (item2.infoRnDay >= 3) { rainEffectDay = 2; - }else{ + } else { rainEffectDay--; } - if(rainEffectDay<0){ //청천시 + if (rainEffectDay < 0) { //청천시 chungcunSumFlow += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;//Number(item2.inflAmnt); sumChungcunDay += 1; } totWaterUsage += Number(item2.inflAmnt); }); - + let wtrUsgYearTotal = 0; // 연간 물사용량 let wtrUsgYearDays = 0; // 연간 물사용 일수 wtrUsgYmList?.forEach(item3 => { @@ -372,13 +369,13 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { const count = detailList ? detailList.length : 0; const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량 item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65% - if(wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) { - item.waterUsage = wtrUsgYearDays>0? wtrUsgYearTotal / wtrUsgYearDays: 0; // 일평균 물사용량 - } + if (wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) { + item.waterUsage = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량 + } item.sewageInputYear = parseFloat(avg.toFixed(2)); // 연간 하수유입량(m³/일) - item.sewageInputChungchun = parseFloat((chungcunSumFlow===0?0:(chungcunSumFlow / sumChungcunDay)).toFixed(2)); // 청천시 하수유입량 + item.sewageInputChungchun = parseFloat((chungcunSumFlow === 0 ? 0 : (chungcunSumFlow / sumChungcunDay)).toFixed(2)); // 청천시 하수유입량 item.estimationSewage = parseFloat((item.waterUsage * OSU_PERCENT).toFixed(2)); // 오수발생량 추정(m³/일) - if ( item.bscFctCd === '11200PB001R' ) { + if (item.bscFctCd === '11200PB001R') { console.log('chungcunSumFlow:', chungcunSumFlow); console.log('sumChungcunDay:', sumChungcunDay); } @@ -388,7 +385,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { ); } - if(pageSize >= 5000){ + if (pageSize >= 5000) { const excelDownList: ExcelType[] = []; sewageOccurPropsList.forEach((item: SewageOccurProps) => { excelDownList.push({ @@ -414,16 +411,16 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { SewageOccur: { ...state.SewageOccur, excelList: excelDownList, - isLoading : false, + isLoading: false, }, })); - }else{ + } else { set((state: SewageOccurType) => ({ ...state, SewageOccur: { ...state.SewageOccur, - sewageOccurList : sewageOccurPropsList, - sewageOccurCount : facilityInitData.count, + sewageOccurList: sewageOccurPropsList, + sewageOccurCount: facilityInitData.count, isLoading: false, excelList: [], }, @@ -516,12 +513,12 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { searchSewageOccurDetailList: async (bscFctCd: string, searchYear: string, startYm?: string, endYm?: string) => { const fcltCdList = [bscFctCd]; - const wtrUsgRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList); + const wtrUsgRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList); const res = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear); const monthData: SewageOccurDetailProps[] = []; - let tot = 0, cnt= 0; + let tot = 0, cnt = 0; - if(startYm) { + if (startYm) { res.data = res.data.filter((item: FlowDataItem) => { const month = item.msrDt?.substring(0, 6); return month >= startYm; @@ -533,7 +530,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { }); } } - if(endYm) { + if (endYm) { res.data = res.data.filter((item: FlowDataItem) => { const month = item.msrDt?.substring(0, 6); return month <= endYm; @@ -555,8 +552,10 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { monthData[monthIdx].sum += Number(item.inflAmnt); monthData[monthIdx].cnt++; } else { - monthData[monthIdx] = {cnt:1, sum:Number(item.inflAmnt), yr:item.msrDt.substring(0,4) - , usage:0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0, monWtrUsg:0}; + monthData[monthIdx] = { + cnt: 1, sum: Number(item.inflAmnt), yr: item.msrDt.substring(0, 4) + , usage: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0, monWtrUsg: 0 + }; } } tot += Number(item.inflAmnt) @@ -574,29 +573,29 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { if (typeof monthData[monthIdx] === 'object') { monthData[monthIdx].sumWtrUsg += Number(item.wtrUsg); monthData[monthIdx].cntWtrUsg += getDaysInMonth(item.levyYm); - } + } } totWtrUsg += Number(item.wtrUsg); cntWtrUsg += getDaysInMonth(item.levyYm); }); } - - const tableData:modalTableType[] = [] + + const tableData: modalTableType[] = [] let maxWaterUsage = 0; let minWaterUsage = 9999999999; let avgWaterUsage = 0; monthData.forEach((item, index) => { - item.avgWtrUsg = item.sum/item.cnt *0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 + item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; tableData.push({ - msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)), - waterUsage: Math.round(item.avgWtrUsg*1) /1, - swageChangePercent: OSU_PERCENT*100,//(Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100, - estimationSewage: Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1 + msrDt: item.yr + '-' + (index + 1 >= 10 ? String(index + 1) : '0' + (index + 1)), + waterUsage: Math.round(item.avgWtrUsg * 1) / 1, + swageChangePercent: OSU_PERCENT * 100,//(Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100, + estimationSewage: Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1 }) if (item.avgWtrUsg > maxWaterUsage) { - maxWaterUsage = item.avgWtrUsg; + maxWaterUsage = item.avgWtrUsg; } if (item.avgWtrUsg < minWaterUsage) { @@ -604,29 +603,29 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => { } }); - avgWaterUsage = tot/cnt*0.65 + avgWaterUsage = tot / cnt * 0.65 if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; - const newData= [ - { - msrDt: '평균', - waterUsage: roundNumber(Math.round(avgWaterUsage*1) /1,0), - swageChangePercent: OSU_PERCENT*100, - estimationSewage: roundNumber(Math.round(avgWaterUsage*OSU_PERCENT*1) /1,0), - }, - { - msrDt: '최대', - waterUsage: roundNumber(Math.round(maxWaterUsage*100) /100,0), - swageChangePercent: OSU_PERCENT*100, - estimationSewage: roundNumber(Math.round(maxWaterUsage*OSU_PERCENT*1) /1, 0), - }, - { - msrDt: '최소', - waterUsage: roundNumber(Math.round(minWaterUsage*100) /100,0), - swageChangePercent: OSU_PERCENT*100, - estimationSewage: roundNumber(Math.round(minWaterUsage*OSU_PERCENT*1) /1,0), - }, - ...tableData + const newData = [ + { + msrDt: '평균', + waterUsage: roundNumber(Math.round(avgWaterUsage * 1) / 1, 0), + swageChangePercent: OSU_PERCENT * 100, + estimationSewage: roundNumber(Math.round(avgWaterUsage * OSU_PERCENT * 1) / 1, 0), + }, + { + msrDt: '최대', + waterUsage: roundNumber(Math.round(maxWaterUsage * 100) / 100, 0), + swageChangePercent: OSU_PERCENT * 100, + estimationSewage: roundNumber(Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, 0), + }, + { + msrDt: '최소', + waterUsage: roundNumber(Math.round(minWaterUsage * 100) / 100, 0), + swageChangePercent: OSU_PERCENT * 100, + estimationSewage: roundNumber(Math.round(minWaterUsage * OSU_PERCENT * 1) / 1, 0), + }, + ...tableData ] set((state: SewageOccurType) => ({ diff --git a/apps/fo/src/entities/auth/index.ts b/apps/fo/src/entities/auth/index.ts index 9dc9dd368..97e142225 100644 --- a/apps/fo/src/entities/auth/index.ts +++ b/apps/fo/src/entities/auth/index.ts @@ -1,2 +1,2 @@ export { LoginApi } from "./api/login-service"; -//export { AuthWrapper } from "./lib/auth-wrapper"; +export { AuthWrapper } from "./lib/auth-wrapper"; diff --git a/apps/fo/src/entities/auth/lib/auth-wrapper.tsx b/apps/fo/src/entities/auth/lib/auth-wrapper.tsx index d3ae23177..0c2d04830 100644 --- a/apps/fo/src/entities/auth/lib/auth-wrapper.tsx +++ b/apps/fo/src/entities/auth/lib/auth-wrapper.tsx @@ -1,8 +1,7 @@ "use client"; import { useEffect } from "react"; -import { useRouter } from "next/navigation"; -//import { usePathname } from "next/navigation"; +import { useRouter, usePathname } from "next/navigation"; import { client } from "@/src/shared/api"; import type { IUserInfo } from "@/src/shared/store"; import { useUserStore, getCookie } from "@/src/shared/lib"; @@ -13,7 +12,7 @@ const LOGIN_PAGE_URL = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "http://loca const AuthWrapper = ({ children }: { children: React.ReactNode }) => { const router = useRouter(); - //const pathname = usePathname(); + const pathname = usePathname(); const { userInfo, setUserInfo } = useUserStore((state) => state); async function authCheck() { @@ -42,7 +41,7 @@ const AuthWrapper = ({ children }: { children: React.ReactNode }) => { console.error("Token refresh failed:", refreshError); setUserInfo(null); - const hostname = location.hostname; + const hostname = window.location.hostname; // 개발 환경에서는 localhost 도메인 사용 if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") @@ -50,13 +49,13 @@ const AuthWrapper = ({ children }: { children: React.ReactNode }) => { // 운영 환경에서는 서브도메인을 포함한 최상위 도메인 사용 // router.push는 같은 Next.js 앱 내에서만 작동하므로 다른 앱으로 이동할 때는 window.location.href 사용 - if (hostname.includes("hasuon.or.kr")) location.href = LOGIN_PAGE_URL; // 세션 만료 시 CM 로그인 페이지로 리다이렉트 + if (hostname.includes("hasuon.or.kr")) window.location.href = LOGIN_PAGE_URL; // 세션 만료 시 CM 로그인 페이지로 리다이렉트 } } })(); - }, []); + }, [pathname]); return <>{children}; }; -export { AuthWrapper }; +export { AuthWrapper }; \ No newline at end of file diff --git a/apps/sn/.env.local b/apps/sn/.env.local index c83e4fb68..997f50518 100644 --- a/apps/sn/.env.local +++ b/apps/sn/.env.local @@ -5,6 +5,7 @@ NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PORT = 3002 NEXT_PUBLIC_PROXY_HOST = http://localhost:3002 +NEXT_PUBLIC_SUB_DOMAIN = http://localhost:13000 NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver #NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr/openapi/Gettile.do?apiKey=04trYP9_xwLAfALjwZ-B8g&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/png&layer=korean_map&style=korean&tilematrixset=EPSG:5179&TileMatrix={z}&TileCol={x}&TileRow={y} diff --git a/apps/sn/.env.mindone b/apps/sn/.env.mindone index 7010ce026..d03f5cae5 100644 --- a/apps/sn/.env.mindone +++ b/apps/sn/.env.mindone @@ -5,6 +5,7 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11302 +NEXT_PUBLIC_SUB_DOMAIN = http://con.mind-one.co.kr:11300 NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000 NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver diff --git a/apps/sn/.env.production b/apps/sn/.env.production index 004fc8701..b166d7390 100644 --- a/apps/sn/.env.production +++ b/apps/sn/.env.production @@ -6,8 +6,8 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id NEXT_PUBLIC_ACCESS_TOKEN = access-token NEXT_PUBLIC_REFRESH_TOKEN = refresh-token #NEXT_PUBLIC_PROXY_HOST = https://devlion.hasuon.or.kr +#NEXT_PUBLIC_SUB_DOMAIN = http://front-sn-feature.iipbs-web.svc.cluster.local:13000 #NEXT_PUBLIC_CM_LOGIN_PAGE_URL = https://devqueen.hasuon.or.kr/auth/login -NEXT_PUBLIC_CM_LOGIN_PAGE_URL = https://devqueen.hasuon.or.kr/auth/login NEXT_PUBLIC_SERVER_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000 NEXT_PUBLIC_GEOSERVER_URL = http://172.29.143.87:8080/geoserver NEXT_PUBLIC_LX_GEOSERVER_URL = http://172.29.143.87:8080/geoserver_swl diff --git a/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts b/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts index d1e777242..7b591b09c 100644 --- a/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts +++ b/apps/sn/app/(map-layout)/map/components/common/codeMapper.ts @@ -87,6 +87,13 @@ export const codeMapper = ({ layerName, data }: CodeMapperProps): any => { if (processedData.manage_no) { processedData.mqlt_cd = processedData.manage_no; } + if (processedData.mesure_spot_se) { + const mesureSpotSe = [{ id: '0', text: '합류식' }, { id: '1', text: '분류식' }]; + const mesureSpotSeItem = mesureSpotSe.find( + code => code.id === processedData.mesure_spot_se.trim() + ); + if (mesureSpotSeItem) processedData.mesure_spot_se = mesureSpotSeItem.text; + } break; default: diff --git a/apps/sn/app/(map-layout)/map/components/common/table.ts b/apps/sn/app/(map-layout)/map/components/common/table.ts index a16e68013..081e13d1f 100644 --- a/apps/sn/app/(map-layout)/map/components/common/table.ts +++ b/apps/sn/app/(map-layout)/map/components/common/table.ts @@ -686,7 +686,7 @@ export const untrtSwgRainCol1 = [ // 중점우수토실 측정지점 시설현황 export const untrtSwgRainCol2 = [ - { id: 'flwmtr_mesure_tp_etc', title: '구분' }, + { id: 'mesure_spot_se', title: '구분' }, // 유량계측정방식 기타 { id: 'discharge_pipe_spec', title: '방류관로 규격(m)' }, { id: 'swr_ppl_eqp_ar', title: '배수구역 면적(m²)' }, { id: 'swr_trt_popl', title: '하수처리 인구(인)' }, @@ -722,7 +722,7 @@ export const untrtSwgRainCol4 = [ export const untrtSwgRainCol5 = [ { id: 'odr', title: '회차' }, { id: 'mesureDt', title: '측정일자' }, - { id: 'mesureQy', title: '수량(m)' }, + { id: 'mesureQy', title: '수량(m³)' }, { id: 'mesureBod', title: 'BOD(mg/L)' }, { id: 'mesureToc', title: 'TOC(mg/L)' }, { id: 'mesureLoad', title: '오염부하량(kg)' } 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 3ce6b30a7..f908fe98b 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/Ssc.tsx @@ -100,15 +100,20 @@ const Ssc = ({ featureData, isMainSsc, chmbrXcnts, chmbrYdnts, onSaveClick }: { const processedDataArray: any[] = result.content.map((data: any) => { // 🎯 formatDisplayData로 기본 포맷팅 적용 const formattedItem = formatDisplayData(data); - + const flwmtrInstTp = data.flwmtrInstTp === 'R' ? '이동식' : data.flwmtrInstTp === 'S' ? '고정식' : '-'; + const flwmtrMesureTp = data.flwmtrMesureTp === 'R' ? '레이더' : data.flwmtrMesureTp === 'P' ? '플륨' + : data.flwmtrMesureTp === 'U' ? '초음파' : data.flwmtrMesureTp === 'E' ? '기타' : '-'; + const flwmtrCombined = `${flwmtrInstTp}, ${flwmtrMesureTp}`; // 🎯 추가 데이터 조합 return { ...formattedItem, - flwmtrCombined: `${data.flwmtrMesureTpEtc || '-'} / ${data.flwmtrKnd || '-'}`, - mesureBeginDt: data.mesureBeginDt ? formatNoYearNoSec(data.mesureBeginDt) : '-', - mesureEndDt: data.mesureEndDt ? formatNoYearNoSec(data.mesureEndDt) : '-', - qltwtrBeginDt: data.qltwtrBeginDt ? formatNoYearNoSec(data.qltwtrBeginDt) : '-', - qltwtrEndDt: data.qltwtrEndDt ? formatNoYearNoSec(data.qltwtrEndDt) : '-', + rainInfo: `${data.rainInfo === '0' ? '강우량계' : data.observatory || '-'}`, // 강우정보 0: 강우량계,1: 관측기관 이면 OBSERVATORY 이값사용 + mesureIntrvl: `${data.mesureIntrvlGbn === '1' ? '1분' : (data.mesureIntrvlGbn === '0' ? data.mesureIntrvl + '분' : '-')}`, // 측정간격 + flwmtrCombined: `${flwmtrCombined} / ${data.flwmtrKnd || '-'}`, // 유량계종류 및 모델명 + mesureBeginDt: data.mesureBeginDt ? formatNoYearNoSec(data.mesureBeginDt) : '-', // 수량 측정시작일 + mesureEndDt: data.mesureEndDt ? formatNoYearNoSec(data.mesureEndDt) : '-', // 수량 측정종료일 + qltwtrBeginDt: data.qltwtrBeginDt ? formatNoYearNoSec(data.qltwtrBeginDt) : '-', // 수질 측정시작일(채수시작일) + qltwtrEndDt: data.qltwtrEndDt ? formatNoYearNoSec(data.qltwtrEndDt) : '-', // 수질 측정종료일(채수종료일) }; }); setRainMeasureData(processedDataArray); 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 e0fe03a92..031c69d8a 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/featureClickEventPopup.tsx @@ -235,6 +235,17 @@ const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, ); if (materialCodeItem) data.mqlt_cd = `${materialCodeItem.text}`; } + } else { + // 중점우수토실인 경우 구분 값 + if (selectedLayerName === '중점우수토실' && data) { + if (data.mesure_spot_se) { + const mesureSpotSe = [{id:'0', text: '합류식'}, {id:'1', text: '분류식'}] + const mesureSpotSeItem = mesureSpotSe.find( + code => code.id === data.mesure_spot_se.trim() + ); + if (mesureSpotSeItem) data.mesure_spot_se = mesureSpotSeItem.text; + } + } } // 🎯 기본 데이터 포맷팅 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 f814092e7..2a0b11682 100644 --- a/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx +++ b/apps/sn/app/(map-layout)/map/components/popupComponent/smh.tsx @@ -41,7 +41,8 @@ export async function searchUpperPpls(gisMap: any, fcltMngNo: any) { } // JSON 파싱 시도 - data = JSON.parse(text); + const response = JSON.parse(text); + data = response.data; } catch (error) { console.error("JSON parsing error:", error); alert(`해당 맨홀의 상류관로를 찾을 수 없습니다.`); diff --git a/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx index 6d1507f06..c21dc8ca4 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/basicTab.tsx @@ -34,7 +34,7 @@ const BasicTab: React.FC = () => { const { basicType, setBasicType } = useSearchModalStore(); return ( -
+
{/* 구분 */}
diff --git a/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx index 692551cbb..63c18875d 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/operationTab.tsx @@ -37,7 +37,7 @@ const OperationTab: React.FC = () => { })); return ( -
+
= ({ clsfSystmSn }: ModalOpenPro onOpenChange={setIsModalOpen} headerTitle="" bodyClass={` - min-h-[50vh] h-[570px] - min-w-[35vw] w-[400px] - max-w-none max-h-none - overflow-visible + min-h-[50vh] max-h-[90dvh] + max-w-[750px] + h-auto w-auto + overflow-auto z-[5000] flex items-start `} diff --git a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx index bb6b4cd89..a90284dde 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/reportTab.tsx @@ -72,15 +72,15 @@ const ReportTab: React.FC = ({ open, isSearch = true, ctpvNm, sg } = useSearchModalStore(); const { ctpv, sgg } = useStore(); const { - isOpen: isReportFilesModalOpen, + isOpen: isReportFilesModalOpen, setIsOpen: setIsReportFilesModalOpen, dcTree: reportOriginData, fetchDcTree - } = useReportTabStore(); // 모달 상태 관리 스토어 - const { REPORT_TYPES, flattenFolders, addFileName } = useReportTab(); - - useEffect(() => { - fetchDcTree("기본계획"); // 하수정비기본계획 report + } = useReportTabStore(); // 모달 상태 관리 스토어 + const { REPORT_TYPES, flattenFolders, addFileName } = useReportTab(); + + useEffect(() => { + fetchDcTree("기본계획"); // 하수정비기본계획 report }, []); useEffect(() => { @@ -206,7 +206,7 @@ const ReportTab: React.FC = ({ open, isSearch = true, ctpvNm, sg return ( <> -
+
{isSearch && ( <>
diff --git a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx index 8da8911e5..34cdb674b 100644 --- a/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx +++ b/apps/sn/app/(map-layout)/map/searchModal/searchModal.tsx @@ -125,7 +125,7 @@ const SearchModal: React.FC = () => { {/* 📋 결과 리스트 */} {/* 기본정보 탭 */} {activeTab === 'basic' && ( -
+
{ {/* 유지관리 정보 탭 */} {activeTab === 'operation' && ( <> -
+
{ ); return ( - <> +
- +
); }; 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 c791a3f12..835584e75 100644 --- a/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx +++ b/apps/sn/app/(with-base-layout)/ii/rdiiResult/page.tsx @@ -100,7 +100,7 @@ const Result = () => { const [sggCd, setSggCd] = useState('0'); // 시군구 코드 상태 const [sggName, setSggName] = useState(''); // 시군구 이름 상태 - const {ctpv, sgg} = useStore(); + const { ctpv, sgg } = useStore(); useEffect(() => { // setCurPage(1); @@ -166,7 +166,7 @@ const Result = () => { sggNm: sggOne ? sggOne.text : item.sggCd, }; }) - .filter((item: any) => item.scsYn === 'Y'); + .filter((item: any) => item.scsYn === 'Y'); // 선택된 행 초기화 setSelectedRowData(null); @@ -304,9 +304,9 @@ const Result = () => { onDeleteFile={handleFileDelete} selectedRowData={selectedRowData} > - {[
+ {[
{/*
○ RDII 분석결과 현황
*/} -
+
{ const [ctpvCd, setCtpvCd] = useState('0'); // 시도 코드 상태 const [sggCd, setSggCd] = useState('0'); // 시군구 코드 상태 const [sggName, setSggName] = useState(''); // 시군구 이름 상태 - const {ctpv, sgg} = useStore(); + const { ctpv, sgg } = useStore(); useEffect(() => { // setCurPage(1); @@ -159,7 +159,7 @@ const Result = () => { sggNm: sggOne ? sggOne.text : item.sggCd, }; }) - .filter((item: any) => item.scsYn === 'Y'); + .filter((item: any) => item.scsYn === 'Y'); // 선택된 행 초기화 setSelectedRowData(null); @@ -296,9 +296,9 @@ const Result = () => { onDeleteFile={handleFileDelete} selectedRowData={selectedRowData} > - {[
+ {[
{/*
○ 침입수 산정결과 현황
*/} -
+
{ max-h-[100dvh] overflow-hidden z-[101] + flex flex-col gap-[10px] `} body={} useDirectRender={true} 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 ad8fcf72f..97e9d788d 100644 --- a/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx +++ b/apps/sn/app/(with-base-layout)/oper/floodPre/tableModal.tsx @@ -219,10 +219,10 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { /> {/* 관리SHEET 탭 */} {activeTab === 'management' && ( -
-
+
+
-
+
= ({ fileNm, atflId }) => { total={0} cellClick={undefined} onPageChange={() => { }} + className="whitespace-nowrap" />
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 6f26f70ec..a078a9795 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/page.tsx @@ -276,6 +276,7 @@ const Page = () => { max-h-[100dvh] overflow-hidden z-[101] + flex flex-col gap-[10px] `} body={} useDirectRender={true} 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 dece4c4f8..707f2d526 100644 --- a/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx +++ b/apps/sn/app/(with-base-layout)/oper/oldPp/tableModal.tsx @@ -3,7 +3,7 @@ * 노후 하수관로 엑셀 데이터 테이블 모달 컴포넌트 * * - 엑셀 파일 다운로드 및 특정 시트 파싱 기능 - * - 탭 기반 테이블 표시 (row data, 정밀조사, 정비사업 등) + * - 탭 기반 테이블 표시 (raw data, 정밀조사, 정비사업 등) * - 데이터 필터링 및 빈 행 제거 처리 * - 로딩 오버레이 및 에러 핸들링 지원 * - XLSX 라이브러리를 통한 엑셀 데이터 변환 @@ -21,7 +21,7 @@ import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeCo import { oldPpTable2HeadList, oldPpTable2NodeList, oldPpTable6HeadList, oldPpTable6NodeList } from './headList'; const TABS = [ - { val: "1", text: "row data" }, + { val: "1", text: "raw data" }, { val: "2", text: "1.정밀조사" }, { val: "3", text: "2.정밀조사_정비사업연계" }, { val: "4", text: " 3.정비사업" }, @@ -74,15 +74,15 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { type: blob.type || 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); - const targetSheets = ['row data', '1.정밀조사', '2.정밀조사_정비사업연계', ' 3.정비사업', '4.정비사업요약', '4.정비사업최종']; + const targetSheets = ['raw data', '1.정밀조사', '2.정밀조사_정비사업연계', ' 3.정비사업', '4.정비사업요약', '4.정비사업최종']; const jsonDataBySheet = await filePickedSelectedSheets(file, 0, targetSheets); - const header1 = jsonDataBySheet['row data']?.[1] || []; + const header1 = jsonDataBySheet['raw data']?.[1] || []; const header2 = jsonDataBySheet['1.정밀조사']?.[1] || []; const header4 = jsonDataBySheet[' 3.정비사업']?.[1] || []; const header5 = jsonDataBySheet['4.정비사업요약']?.[2] || []; - // row data + // raw data const allEntries1 = Object.entries(header1); const filteredHeader1 = [ allEntries1[0], @@ -111,8 +111,8 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { }); setTableHeader1(filteredHeader1); - const data1 = Array.isArray(jsonDataBySheet['row data']) - ? jsonDataBySheet['row data'].slice(2) + const data1 = Array.isArray(jsonDataBySheet['raw data']) + ? jsonDataBySheet['raw data'].slice(2) : []; const filteredData1 = filterEmptyRows(data1).map((item: any, index: number) => ({ ...item, @@ -177,303 +177,303 @@ const TableModal: React.FC = ({ fileNm, atflId }) => { rowNumber: index + 1 }; }); - setTableData3(filteredData3); + setTableData3(filteredData3); - // 3.정비사업 - const allEntries4 = Object.entries(header4); - const filteredHeader4 = allEntries4.filter((e): e is [string, any] => Boolean(e)) - .map(([key, value]) => ({ - id: key, - title: String(value).replace(/\r\n/g, '\n') - })); + // 3.정비사업 + const allEntries4 = Object.entries(header4); + const filteredHeader4 = allEntries4.filter((e): e is [string, any] => Boolean(e)) + .map(([key, value]) => ({ + id: key, + title: String(value).replace(/\r\n/g, '\n') + })); - filteredHeader4.splice(0, 0, { - id: "rowNumber", - title: '일련번호' - }); - setTableHeader4(filteredHeader4); + filteredHeader4.splice(0, 0, { + id: "rowNumber", + title: '일련번호' + }); + setTableHeader4(filteredHeader4); - const data4 = Array.isArray(jsonDataBySheet[' 3.정비사업']) - ? jsonDataBySheet[' 3.정비사업'].slice(2) - : []; - const filteredData4 = filterEmptyRows(data4).map((item: any, index: number) => ({ - ...item, - rowNumber: index + 1, - __EMPTY_2: item?.__EMPTY_2 || '-', - __EMPTY_11: item?.__EMPTY_11 || '-', - })); - setTableData4(filteredData4); - - // 4.정비사업요약 - const allEntries5 = Object.entries(header5); - const excludeKeys5 = [ - ": \"정비사업\"sheet에서 사업코드 ctrl+c, Ctrl+v 한 다음 중복된 데이터 제거실시", - "__EMPTY", - "__EMPTY_8", - "__EMPTY_15" - ]; - const filteredHeader5 = allEntries5 - .filter(([key]) => !excludeKeys5.includes(key)) - .filter((e): e is [string, any] => Boolean(e)) - .map(([key, value]) => ({ - id: key, - title: String(value).replace(/\r\n/g, '\n'), - })); - filteredHeader5.splice(0, 0, { - id: "rowNumber", - title: '일련번호' - }); - setTableHeader5(filteredHeader5); - - const data5 = Array.isArray(jsonDataBySheet['4.정비사업요약']) - ? jsonDataBySheet['4.정비사업요약'].slice(3) - : []; - const filteredData5 = - filterEmptyRows(data5).map((item: any, index: number) => ({ + const data4 = Array.isArray(jsonDataBySheet[' 3.정비사업']) + ? jsonDataBySheet[' 3.정비사업'].slice(2) + : []; + const filteredData4 = filterEmptyRows(data4).map((item: any, index: number) => ({ ...item, rowNumber: index + 1, + __EMPTY_2: item?.__EMPTY_2 || '-', + __EMPTY_11: item?.__EMPTY_11 || '-', })); - setTableData5(filteredData5); + setTableData4(filteredData4); - // 4.정비사업최종 (헤더는 import) - const data6 = Array.isArray(jsonDataBySheet['4.정비사업최종']) - ? jsonDataBySheet['4.정비사업최종'].slice(6) - : []; - const filteredData6 = - filterEmptyRows(data6).map((item: any, index: number) => ({ - ...item, - rowNumber: index + 1, - })); - setTableData6(filteredData6); - } catch (error) { - console.error('파일 처리 중 오류 발생:', error); - alert('파일 처리 중 오류가 발생했습니다.'); - } finally { - setIsLoading(false); + // 4.정비사업요약 + const allEntries5 = Object.entries(header5); + const excludeKeys5 = [ + ": \"정비사업\"sheet에서 사업코드 ctrl+c, Ctrl+v 한 다음 중복된 데이터 제거실시", + "__EMPTY", + "__EMPTY_8", + "__EMPTY_15" + ]; + const filteredHeader5 = allEntries5 + .filter(([key]) => !excludeKeys5.includes(key)) + .filter((e): e is [string, any] => Boolean(e)) + .map(([key, value]) => ({ + id: key, + title: String(value).replace(/\r\n/g, '\n'), + })); + filteredHeader5.splice(0, 0, { + id: "rowNumber", + title: '일련번호' + }); + setTableHeader5(filteredHeader5); + + const data5 = Array.isArray(jsonDataBySheet['4.정비사업요약']) + ? jsonDataBySheet['4.정비사업요약'].slice(3) + : []; + const filteredData5 = + filterEmptyRows(data5).map((item: any, index: number) => ({ + ...item, + rowNumber: index + 1, + })); + setTableData5(filteredData5); + + // 4.정비사업최종 (헤더는 import) + const data6 = Array.isArray(jsonDataBySheet['4.정비사업최종']) + ? jsonDataBySheet['4.정비사업최종'].slice(6) + : []; + const filteredData6 = + filterEmptyRows(data6).map((item: any, index: number) => ({ + ...item, + rowNumber: index + 1, + })); + setTableData6(filteredData6); + } catch (error) { + console.error('파일 처리 중 오류 발생:', error); + alert('파일 처리 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } } -} -function filterEmptyRows(data: any[]) { - return data - .filter(row => { - return Object.entries(row).some(([key, value]) => { - const match = key.match(/^__EMPTY_(\d+)$/); - if (!match || parseInt(match[1] ?? '', 10) < 2) return false; + function filterEmptyRows(data: any[]) { + return data + .filter(row => { + return Object.entries(row).some(([key, value]) => { + const match = key.match(/^__EMPTY_(\d+)$/); + if (!match || parseInt(match[1] ?? '', 10) < 2) return false; - return value !== undefined && - value !== null && - String(value).trim() !== '' && - String(value).trim() !== '-' && - String(value).trim() !== ''; - }); - }) - .map((row) => { - const processedRow = { ...row }; - const keys = Object.keys(processedRow); + return value !== undefined && + value !== null && + String(value).trim() !== '' && + String(value).trim() !== '-' && + String(value).trim() !== ''; + }); + }) + .map((row) => { + const processedRow = { ...row }; + const keys = Object.keys(processedRow); - keys.forEach((key, keyIndex) => { - // 마지막 속성(사업 근거)이 아닌 경우에만 빈 값을 '-'으로 변경 - if (keyIndex !== keys.length - 1) { - const value = processedRow[key]; - if (value === undefined || - value === null || - value === '' || - String(value).trim() === '') { - processedRow[key] = '-'; + keys.forEach((key, keyIndex) => { + // 마지막 속성(사업 근거)이 아닌 경우에만 빈 값을 '-'으로 변경 + if (keyIndex !== keys.length - 1) { + const value = processedRow[key]; + if (value === undefined || + value === null || + value === '' || + String(value).trim() === '') { + processedRow[key] = '-'; + } } - } - }); + }); - return processedRow; + return processedRow; + }); + }; + + // 특정 시트만 선택적으로 JSON으로 변환하는 함수 + function filePickedSelectedSheets(file: File, headerNum: number = 0, sheetNames: string[]): Promise> { + const reader = new FileReader(); + + return new Promise((resolve, reject) => { + reader.onload = function (e) { + const data = e.target?.result; + if (!data) { + console.error("Failed to read file: e.target.result is null"); + reject(new Error("Failed to read file")); + return; + } + + // Excel 파일 읽기 + const wb = XLSX.read(data, { type: 'binary', cellDates: true }); + const result: Record = {}; + + // 지정된 시트 이름만 찾아서 처리 + sheetNames.forEach(targetSheetName => { + // 대소문자 구분 없이 시트 이름 찾기 + const sheetName = wb.SheetNames.find(name => + name.toLowerCase() === targetSheetName.toLowerCase() + ); + + if (sheetName) { + const sheet = wb.Sheets[sheetName]; + if (sheet) { + const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false }); + result[targetSheetName] = jsonData; + } + } else { + console.warn(`Sheet "${targetSheetName}" not found in workbook`); + result[targetSheetName] = []; + } + }); + + resolve(result); + }; + + reader.onerror = function () { + console.error("Error reading file"); + reject(new Error("Error reading file")); + }; + + // 파일 읽기 시작 + reader.readAsBinaryString(file); }); -}; - -// 특정 시트만 선택적으로 JSON으로 변환하는 함수 -function filePickedSelectedSheets(file: File, headerNum: number = 0, sheetNames: string[]): Promise> { - const reader = new FileReader(); - - return new Promise((resolve, reject) => { - reader.onload = function (e) { - const data = e.target?.result; - if (!data) { - console.error("Failed to read file: e.target.result is null"); - reject(new Error("Failed to read file")); - return; - } - - // Excel 파일 읽기 - const wb = XLSX.read(data, { type: 'binary', cellDates: true }); - const result: Record = {}; - - // 지정된 시트 이름만 찾아서 처리 - sheetNames.forEach(targetSheetName => { - // 대소문자 구분 없이 시트 이름 찾기 - const sheetName = wb.SheetNames.find(name => - name.toLowerCase() === targetSheetName.toLowerCase() - ); - - if (sheetName) { - const sheet = wb.Sheets[sheetName]; - if (sheet) { - const jsonData = XLSX.utils.sheet_to_json(sheet, { range: headerNum, raw: false }); - result[targetSheetName] = jsonData; - } - } else { - console.warn(`Sheet "${targetSheetName}" not found in workbook`); - result[targetSheetName] = []; - } - }); - - resolve(result); - }; - - reader.onerror = function () { - console.error("Error reading file"); - reject(new Error("Error reading file")); - }; - - // 파일 읽기 시작 - reader.readAsBinaryString(file); - }); -}; + }; -return ( - <> - {/* 탭 영역 */} - ({ - value: tab.val, - label: tab.text - }))} - onValueChange={(value: string) => setActiveTab(value)} - /> - {/* row data 탭 */} - {activeTab === '1' && ( -
-
- -
- { }} - /> + return ( + <> + {/* 탭 영역 */} + ({ + value: tab.val, + label: tab.text + }))} + onValueChange={(value: string) => setActiveTab(value)} + /> + {/* row data 탭 */} + {activeTab === '1' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 1.정밀조사 탭 */} - {activeTab === '2' && ( -
-
- -
- { }} - /> + )} + {/* 1.정밀조사 탭 */} + {activeTab === '2' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 2.정밀조사_정비사업연계 탭 */} - {activeTab === '3' && ( -
-
- -
- { }} - > - - + )} + {/* 2.정밀조사_정비사업연계 탭 */} + {activeTab === '3' && ( +
+
+ +
+ { }} + > + + +
-
- )} - {/* 3.정비사업 탭 */} - {activeTab === '4' && ( -
-
- -
- { }} - /> + )} + {/* 3.정비사업 탭 */} + {activeTab === '4' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 4.정비사업요약 탭 */} - {activeTab === '5' && ( -
-
- -
- { }} - /> + )} + {/* 4.정비사업요약 탭 */} + {activeTab === '5' && ( +
+
+ +
+ { }} + /> +
-
- )} - {/* 4.정비사업최종 탭 */} - {activeTab === '6' && ( -
-
- -
- { }} - > - - + )} + {/* 4.정비사업최종 탭 */} + {activeTab === '6' && ( +
+
+ +
+ { }} + > + + +
-
- )} - -) + )} + + ) }; export default TableModal; \ No newline at end of file diff --git a/apps/sn/app/auth/login/route.ts b/apps/sn/app/auth/login/route.ts index d954cbaa1..65bbce15e 100644 --- a/apps/sn/app/auth/login/route.ts +++ b/apps/sn/app/auth/login/route.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const hostname = request.nextUrl.hostname; - const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://portal.hasuon.or.kr"; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 diff --git a/apps/sn/next.config.ts b/apps/sn/next.config.ts index bbfa649d5..66724c419 100644 --- a/apps/sn/next.config.ts +++ b/apps/sn/next.config.ts @@ -1,5 +1,8 @@ import type { NextConfig } from "next"; +const subDomain = + process.env.NEXT_PUBLIC_SUB_DOMAIN || "http://localhost:13000"; + const nextConfig: NextConfig = { output: "standalone", experimental: { @@ -11,6 +14,17 @@ const nextConfig: NextConfig = { eslint: { ignoreDuringBuilds: true, }, + async rewrites() { + return { + afterFiles: [ + { + source: "/cms/:path*", + destination: `${subDomain}/cms/:path*`, + }, + ], + fallback: [], + }; + }, }; export default nextConfig; diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 0c3cb1cc7..2365d3add 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -10,6 +10,16 @@ import { useAlertStore } from "@/shared/lib"; import { Button } from "@common/components"; import { useTabStore } from "@/store/tab-store" +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + }): void; + } +} + // Window 인터페이스 확장 declare global { interface Window { @@ -32,7 +42,28 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); - const [rowData, setRowData] = useState[]>([]); + const [rowData, setRowData] = useState[]>([]); + + // footer가 있는 컬럼의 데이터를 숫자로 변환 + const convertNumericData = (data: Record[]): Record[] => { + const footerColumns = columns.filter(col => col.footer); + const footerFieldNames = new Set(footerColumns.map(col => col.fieldName)); + + return data.map(row => { + const convertedRow: Record = { ...row }; + footerFieldNames.forEach(fieldName => { + const value = row[fieldName]; + if (value !== undefined && value !== null && value !== '') { + // 쉼표 제거 후 숫자로 변환 + const numericValue = Number(String(value).replace(/,/g, '')); + if (!isNaN(numericValue)) { + convertedRow[fieldName] = numericValue; + } + } + }); + return convertedRow; + }); + }; const exportExcel = () => { if (rowData.length === 0) { @@ -152,7 +183,8 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi } } - setRowData(dataRows); + const convertedDataRows = convertNumericData(dataRows); + setRowData(convertedDataRows); } catch (error) { console.error('엑셀 파일 파싱 오류:', error); alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); @@ -187,8 +219,11 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; - if (rows.length > 0) { - setRowData(rows); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; } // 고정 컬럼 설정 @@ -197,7 +232,27 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi colCount: fixedColumns, }); } - }, [rows, columns, columnLayout, fixedColumns]); + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + if (rows.length > 0) { + const convertedRows = convertNumericData(rows); + setRowData(convertedRows); + } + + }, [rows, columns, columnLayout, fixedColumns, rowData]); return (
@@ -233,6 +288,11 @@ const DataGrid = ({ columnInfo, rows = [], rowStartNum, isExcelImport = true, fi name={column.name} fieldName={column.fieldName} header={column.header} + footer={column.footer ? { + text: column.footer.text, + expression: column.footer.expression, + numberFormat: column.footer.numberFormat, + } : undefined} // autoFilter={true} /> ))} diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index c9f1e6fbc..789df3ecd 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -5,17 +5,38 @@ import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; +import type { GridView, DataColumn, ColumnFooter } from "@/components/type/DataGrid.type"; +import { getFooterSummary } from "@/components/util/grid/footerSummary"; + const SeweragePenetrationRateMng = () => { const columns = [ { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '구군', header: { text: '구군' } }, + { + name: 'sgg', + fieldName: '구군', + header: { text: '구군' }, + footer: { + text: '합계' + }, + }, { name: 'rvbsn', fieldName: '수계', header: { text: '수계' } }, { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { + name: 'total_popl', + fieldName: '총인구', + header: { text: '총인구' }, + footer: { + expression: 'sum' as const, + numberFormat: '#,##0', + valueCallback: (grid: GridView, column: DataColumn) => { + return getFooterSummary(grid, column); + }, + }, + }, { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, @@ -131,7 +152,7 @@ const SeweragePenetrationRateMng = () => {
- + ); }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index f168631de..81a65fd3d 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -1,7 +1,33 @@ +// RealGrid 타입 정의 +export type GridView = { + getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; + getDataSource(): { + getRowCount(): number; + getValue(rowIndex: number, field: string): number; + }; +}; + +export type DataColumn = { + name: string; + fieldName: string; +}; + +export type ColumnFooter = { + text?: string; + expression?: string; + numberFormat?: string; +}; + export type ColumnConfig = { name: string; fieldName: string; header: { text: string }; + footer?: { + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }, }; export type ColumnLayoutItem = string | { diff --git a/apps/st/src/components/util/grid/footerSummary.ts b/apps/st/src/components/util/grid/footerSummary.ts new file mode 100644 index 000000000..740a3fc7d --- /dev/null +++ b/apps/st/src/components/util/grid/footerSummary.ts @@ -0,0 +1,22 @@ +import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; + +export const getFooterSummary = (grid: GridView, column: DataColumn) => { + // 데이터 소스에서 직접 합계 계산 + const dataSource = grid.getDataSource(); + const rowCount = dataSource.getRowCount(); + let sum = 0; + + for (let i = 0; i < rowCount; i++) { + const cellValue = dataSource.getValue(i, column.fieldName); + // 문자열인 경우 숫자로 변환 + const numericValue = typeof cellValue === 'string' + ? Number(String(cellValue).replace(/,/g, '')) + : Number(cellValue); + + if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) { + sum += numericValue; + } + } + + return sum; +}; \ No newline at end of file diff --git a/apps/wr/app/auth/login/route-bak.ts b/apps/wr/app/auth/login/route-bak.ts index d954cbaa1..65bbce15e 100644 --- a/apps/wr/app/auth/login/route-bak.ts +++ b/apps/wr/app/auth/login/route-bak.ts @@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from "next/server"; export async function GET(request: NextRequest) { const hostname = request.nextUrl.hostname; - const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://queen.hasuon.or.kr"; + const redirectUrl = process.env.NEXT_PUBLIC_CM_LOGIN_PAGE_URL || "https://portal.hasuon.or.kr"; if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "con.mind-one.co.kr") { return NextResponse.redirect(new URL("/", request.url)); // 로컬 및 개발 환경 diff --git a/packages/common/components/src/api/attachment.ts b/packages/common/components/src/api/attachment.ts index f1645013e..0634f93c3 100644 --- a/packages/common/components/src/api/attachment.ts +++ b/packages/common/components/src/api/attachment.ts @@ -7,7 +7,7 @@ const BASE_URL = `${PROXY_HOST}/server`; export const getImageUrlByAtflCd = async (atflCd: string): Promise => { if (!atflCd) return ""; const response = await fetch( - `${BASE_URL}/${ENDPOINT.ATTACH_SERVICE.IMAGES}/atflCd/${atflCd}`, + `${BASE_URL}${ENDPOINT.ATTACH_SERVICE.IMAGES}/atflCd/${atflCd}`, ); const blob = await response.blob(); return URL.createObjectURL(blob); diff --git a/packages/common/components/src/api/banner.ts b/packages/common/components/src/api/banner.ts index b002755be..8d9962529 100644 --- a/packages/common/components/src/api/banner.ts +++ b/packages/common/components/src/api/banner.ts @@ -23,7 +23,7 @@ const client = getApiClient(); export const getBannerList = async (siteId: string) => { const response = await client.get( - `${BASE_URL}/${ENDPOINT.CMS_SERVICE.BANNERS}/${siteId}`, + `${BASE_URL}${ENDPOINT.CMS_SERVICE.BANNERS}/${siteId}`, { method: "GET", headers: { diff --git a/packages/common/components/src/api/site.ts b/packages/common/components/src/api/site.ts index 04eb40455..bfe0f3275 100644 --- a/packages/common/components/src/api/site.ts +++ b/packages/common/components/src/api/site.ts @@ -59,7 +59,7 @@ const BASE_URL = `${PROXY_HOST}/server`; export const getSiteInfo = async (siteId: string) => { const response = await fetch( - `${BASE_URL}/${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, + `${BASE_URL}${ENDPOINT.CMS_SERVICE.SITES}/${siteId}`, { method: "GET", headers: { @@ -74,7 +74,7 @@ const client = getApiClient(); export const getSiteList = async () => { const response = await client.get( - `${BASE_URL}/${ENDPOINT.CMS_SERVICE.SITE_LIST}`, + `${BASE_URL}${ENDPOINT.CMS_SERVICE.SITE_LIST}`, { method: "GET", headers: {