This commit is contained in:
2026-01-21 16:28:08 +09:00
65 changed files with 3361 additions and 3007 deletions
+6 -7
View File
@@ -4,20 +4,19 @@ NEXT_PUBLIC_AUTH_USER_ID = token-id
NEXT_PUBLIC_ACCESS_TOKEN = access-token
NEXT_PUBLIC_REFRESH_TOKEN = refresh-token
NEXT_PUBLIC_PORT = 3005
#NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11035
NEXT_PUBLIC_PROXY_HOST = http://localhost:3005
NEXT_PUBLIC_DM_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1
NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_FO_SERVER_API_URL = http://con.mind-one.co.kr:11083/operation-service/api/v1
# NEXT_PUBLIC_FO_SERVER_API_URL = http://192.168.1.222:8883/operation-service/api/v1
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_DM_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1
# NEXT_PUBLIC_FO_SERVER_API_URL = http://192.168.1.222:8883/operation-service/api/v1
NEXT_PUBLIC_FO_SERVER_API_URL = http://con.mind-one.co.kr:11083/operation-service/api/v1
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver
NEXT_PUBLIC_CS_TUS_UPLOAD = /attach-service/api/v1/tus/upload
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/api/v1
NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr
NEXT_PUBLIC_NGII_PARAM = 04trYP9_xwLAfALjwZ-B8g&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={x}&tilerow={y}
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service # 개발 서버 API
NEXT_PUBLIC_GATEWAY_URL=http://con.mind-one.co.kr:11083 # 개발 서버 API
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정
NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login
+1
View File
@@ -14,6 +14,7 @@ NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11083/reuse-service/ap
NEXT_PUBLIC_NGII_URL = https://map.ngii.go.kr
NEXT_PUBLIC_NGII_PARAM = 04trYP9_xwLAfALjwZ-B8g&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={x}&tilerow={y}
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service # 개발 서버 API
NEXT_PUBLIC_GATEWAY_URL=http://con.mind-one.co.kr:11083 # 개발 서버 API
# NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정
NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login
+1
View File
@@ -15,6 +15,7 @@ NEXT_PUBLIC_GEOSERVER_URL = http://172.29.143.87:8080/geoserver
NEXT_PUBLIC_LX_GEOSERVER_URL = http://172.29.143.87:8080/geoserver_swl
NEXT_PUBLIC_WR_SERVER_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000/reuse-service/api/v1
NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000/sewerage-service
NEXT_PUBLIC_GATEWAY_URL = http://apigateway.iipbs-was.svc.cluster.local:8000
NEXT_PUBLIC_NGII_URL = http://172.29.143.87/poiact
NEXT_PUBLIC_NGII_PARAM = BDE2BEF39DAFEC293AB6730150F222AC&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={y}&tilerow={x}
@@ -87,9 +87,9 @@ export default function ModalSimilarPage({ sply = 0, usageCd = '', money = 0 }:
}, [getSimilarCaseList, money, searchUseType, sply, usageCd]);
return (
<div className="align-top w-[1360px] overflow-x-auto">
<div className="align-top w-[1360px] h-full">
<Title title="유사사례 조회" />
<div className="overflow-x-auto h-[450px] w-full mt-8" tabIndex={0} aria-label="유사사례 테이블 영역">
<div className="overflow-x-auto h-[480px] w-full mt-8" tabIndex={0} aria-label="유사사례 테이블 영역">
<div className="w-[150%]">
<div className="card-header justify-self-start">
<h3 className="text-2xl font-medium text-label">유사사례</h3>
@@ -148,7 +148,7 @@ export default function ModalSimilarPage({ sply = 0, usageCd = '', money = 0 }:
</div>
</div>
</div>
<div className="overflow-x-auto h-[270px] w-full mt-8">
<div className="overflow-x-auto h-[270px] w-full mt-8 overflow-y-hidden">
<div className="w-[130%]">
<UiTable
headName={"사업비 상세정보"}
@@ -1,5 +1,11 @@
"use client";
/**
* 수요정보등록 화면
*
* 🔗 사용 API
* - 수요정보등록: POST /reuseFc/request/demandInfo
*/
import { useDmStore } from "@/app/store";
import { sdmInfoFormSchema, type DemandCompBizType, type SdmInfoFormData } from "@/app/store/sdmMng";
import { SdmInfoRegForm } from "@/components/ui/sdmInfoInsertForm/component";
@@ -60,7 +66,7 @@ function SdmInfoInsertContent() {
...prev,
sdmNm: searchParams.get("dmdCoNm") || "",
}));
if(searchParams.get("dmdInfoId")){
if (searchParams.get("dmdInfoId")) {
// const data = {
// dmdCoNm: searchParams.get("dmdCoNm") || '',
// ctpvCd: searchParams.get("ctpvCd") || '',
@@ -69,8 +75,8 @@ function SdmInfoInsertContent() {
// daddr: searchParams.get("daddr") || '',
// telno: searchParams.get("telno") || '',
// }
// sessionStorage.setItem("user", JSON.stringify(data || {}));
// sessionStorage.setItem("user", JSON.stringify(data || {}));
}
//sessionStorage.setItem("user", JSON.parse(user||'') || "");
setIsLogin(user || searchParams.get("dmdInfoId") ? true : false);
@@ -121,7 +127,7 @@ function SdmInfoInsertContent() {
const userData = JSON.parse(user);
if (userData.dmdCoNm) {
setFacilityName(userData.dmdCoNm);
form.setValue("sdmNm", userData.dmdCoNm);
form.setValue("sdmNm", userData.dmdCoNm); // 수요처명(회사명)
}
} catch (error) {
console.error("Error parsing user data:", error);
@@ -203,10 +209,10 @@ function SdmInfoInsertContent() {
tph: Number(data.tph) || null,
trbt: Number(data.trbt) || null,
ph: data.ph || "",
blgcOxygDmndQnt: Number(data.bod) ||null,
blgcOxygDmndQnt: Number(data.bod) || null,
clIonQnt: Number(data.clIonQnt) || null,
smll: data.smll || "",
cdtnv: Number(data.cdtnv) ||null,
cdtnv: Number(data.cdtnv) || null,
crmty: Number(data.crmty) || null,
rmrk: data.rmrk || "",
bzmnNo: "",
@@ -0,0 +1,22 @@
"use client";
/**
* 수요처 로그아웃 화면
*
* 🔗 사용 API
*
*/
import { useDmStore } from "@/app/store";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
export default function SdmLogout() {
const router = useRouter();
const { actionLogout } = useDmStore((state) => state);
useEffect(() => {
actionLogout();
router.push("/pages/sdmMng/sdmInfoInsert");
}, [actionLogout, router]);
return null;
}
+3
View File
@@ -1,5 +1,8 @@
"use client";
import "./globals.css";
import { setCookie } from "../src/shared/lib";
setCookie("site-id-key", process.env.NEXT_PUBLIC_SITE_ID || "DM");
export default function RootLayout({
children,
+326 -303
View File
@@ -50,8 +50,8 @@ export const sdmInfoFormSchema = z.object({
// 모든 수질 관련 필드
// 총대장균군수는 null 값을 불검출로 표시하기때문에 해당 검사에서 제외함.
const allFields: (keyof typeof data)[] = [
"tn", "combResdch", "tph",
"trbt", "ph", "bod", "clIonQnt",
"tn", "combResdch", "tph",
"trbt", "ph", "bod", "clIonQnt",
"smll", "cdtnv", "crmty",
];
@@ -104,38 +104,38 @@ export type SdmInfoFormData = z.infer<typeof sdmInfoFormSchema>;
// 수요처 정보
export type DemandCompBizType = {
index : number | '';
dmdInfoId : string | '';
dmdInfoFk : string | '';
bzmnNo : string | '';
dmdCoNm : string | '';
daddr : string | '';
telno : string | '';
rgtr : string | '';
useUsgCd : string | '';
ctpvCd : string | '';
sggCd : string | '';
dmdAplyPswd : string | '';
wntUntprc : number | '';
dmndTmng : Date | '';
dmndQty : number | '';
grssClfg : number | null //총대장균군수
tn : number | null //총질소
combResdch : number | null //결합잔류염소
tph : number | null //총인
trbt : number | null //탁도
ph : string | ''; //수소이온농
blgcOxygDmndQnt : number | null //생물학적산소요구량
clIonQnt : number | null //염화물
smll : string | ''; //냄새
cdtnv : number | null; //전기전도도
crmty : number | null //색도
rmrk : string | '';
reqDt : string | '';
dmdInfoSn : number | '';
status : string | '';
splyCndtList:SupplyCandidate[]|[],
ruseUtztnFcltNm?:string|''
index: number | '';
dmdInfoId: string | '';
dmdInfoFk: string | '';
bzmnNo: string | '';
dmdCoNm: string | '';
daddr: string | '';
telno: string | '';
rgtr: string | '';
useUsgCd: string | '';
ctpvCd: string | '';
sggCd: string | '';
dmdAplyPswd: string | '';
wntUntprc: number | '';
dmndTmng: Date | '';
dmndQty: number | '';
grssClfg: number | null //총대장균군수
tn: number | null //총질소
combResdch: number | null //결합잔류염소
tph: number | null //총인
trbt: number | null //탁도
ph: string | ''; //수소이온농
blgcOxygDmndQnt: number | null //생물학적산소요구량
clIonQnt: number | null //염화물
smll: string | ''; //냄새
cdtnv: number | null; //전기전도도
crmty: number | null //색도
rmrk: string | '';
reqDt: string | '';
dmdInfoSn: number | '';
status: string | '';
splyCndtList: SupplyCandidate[] | [],
ruseUtztnFcltNm?: string | ''
}
@@ -147,107 +147,107 @@ export type SupplyCandidate = {
export type DemandMatchings = {
splyFcltFk : string | '';
splyFcltFlg : string | '';
pbnstRuseFcltBizFk : number | '';
splyBgngDay : string | '';
splyEndDay : string | '';
splyCpct : number | '';
splyFmYn : string | '';
useUsgCd : string | '';
dmdInfoSn : number | '';
splyCndtList : string | '';
mtchnCmptnYmd : string | '';
rvwCmptnYmd : string | '';
regDt : string | '';
rgtr : string | '';
mdfcnDt : string | '';
mdfr : string | '';
splyFcltFk: string | '';
splyFcltFlg: string | '';
pbnstRuseFcltBizFk: number | '';
splyBgngDay: string | '';
splyEndDay: string | '';
splyCpct: number | '';
splyFmYn: string | '';
useUsgCd: string | '';
dmdInfoSn: number | '';
splyCndtList: string | '';
mtchnCmptnYmd: string | '';
rvwCmptnYmd: string | '';
regDt: string | '';
rgtr: string | '';
mdfcnDt: string | '';
mdfr: string | '';
}
// 유사사례
export type SimilarCaseType = {
ruseBizNm : string | '';
bizBgngDate : string | '';
bizEndDate : string | '';
splyFcltKnd : string | '';
splyFcltNm : string | '';
splyFcltCpct : string | '';
dmdFcltNm : string | '';
dmdFcltAddr : string | '';
ruseFcltCpct : string | '';
ruseFcltPplLen : string | '';
ruseFcltUsg : string | '';
ruseFcltSplyCpct : string | '';
ruseFcltPrcsMsrc : string | '';
grnteWqUsg : string | '';
grnteWqGrssClfg : string | '';
grnteWqCombResdch : string | '';
grnteWqTrbt : string | '';
grnteWqBod : string | '';
grnteWqSmll : string | '';
grnteWqCrmty : string | '';
grnteWqTn : string | '';
grnteWqTp : string | '';
grnteWqPh : string | '';
grnteWqClIonQnt : string | '';
grnteWqCndctStat : string | '';
grnteWqRmrk : string | '';
reqBizReuseFcltCst : string | '';
reqBizPplCst : string | '';
reqBizArchCst : string | '';
reqBizMchnCst : string | '';
reqBizMtrngCst : string | '';
reqBizGisCst : string | '';
reqBizCctvCst : string | '';
reqBizCmcnCst : string | '';
reqBizWstCst : string | '';
reqBizDesignCst : string | '';
reqBizSpvsCst : string | '';
reqBizSbsdCst : string | '';
reqBizEtc : string | '';
reqBizGrssCst : string | '';
prcmPlanNlep : string | '';
prcmPlanLcep : string | '';
prcmPlanBrdnCst : string | '';
prcmPlanEcqrRt : string | '';
prcmPlanGrssCst : string | '';
clclnNlep : string | '';
clclnLcep : string | '';
clclnBrdnCst : string | '';
clclnEcqrRt : string | '';
clclnGrssCst : string | '';
ruseBizNm: string | ''; // 사업명
bizBgngDate: string | '';
bizEndDate: string | '';
splyFcltKnd: string | '';
splyFcltNm: string | '';
splyFcltCpct: string | '';
dmdFcltNm: string | '';
dmdFcltAddr: string | '';
ruseFcltCpct: string | '';
ruseFcltPplLen: string | '';
ruseFcltUsg: string | '';
ruseFcltSplyCpct: string | '';
ruseFcltPrcsMsrc: string | '';
grnteWqUsg: string | '';
grnteWqGrssClfg: string | '';
grnteWqCombResdch: string | '';
grnteWqTrbt: string | '';
grnteWqBod: string | '';
grnteWqSmll: string | '';
grnteWqCrmty: string | '';
grnteWqTn: string | '';
grnteWqTp: string | '';
grnteWqPh: string | '';
grnteWqClIonQnt: string | '';
grnteWqCndctStat: string | '';
grnteWqRmrk: string | '';
reqBizReuseFcltCst: string | '';
reqBizPplCst: string | '';
reqBizArchCst: string | '';
reqBizMchnCst: string | '';
reqBizMtrngCst: string | '';
reqBizGisCst: string | '';
reqBizCctvCst: string | '';
reqBizCmcnCst: string | '';
reqBizWstCst: string | '';
reqBizDesignCst: string | '';
reqBizSpvsCst: string | '';
reqBizSbsdCst: string | '';
reqBizEtc: string | '';
reqBizGrssCst: string | '';
prcmPlanNlep: string | '';
prcmPlanLcep: string | '';
prcmPlanBrdnCst: string | '';
prcmPlanEcqrRt: string | '';
prcmPlanGrssCst: string | '';
clclnNlep: string | '';
clclnLcep: string | '';
clclnBrdnCst: string | '';
clclnEcqrRt: string | '';
clclnGrssCst: string | '';
}
// 사업비 상세정보
export type MoneyDetailType = {
reqBizGrssCst : string | '';
reqBizReuseFcltCst : string | '';
reqBizPplCst : string | '';
reqBizArchCst : string | '';
reqBizMchnCst : string | '';
reqBizMtrngCst : string | '';
reqBizGisCst : string | '';
reqBizCctvCst : string | '';
reqBizCmcnCst : string | '';
reqBizWstCst : string | '';
reqBizDesignCst : string | '';
reqBizSpvsCst : string | '';
reqBizSbsdCst : string | '';
reqBizEtc : string | '';
reqBizGrssCst: string | '';
reqBizReuseFcltCst: string | '';
reqBizPplCst: string | '';
reqBizArchCst: string | '';
reqBizMchnCst: string | '';
reqBizMtrngCst: string | '';
reqBizGisCst: string | '';
reqBizCctvCst: string | '';
reqBizCmcnCst: string | '';
reqBizWstCst: string | '';
reqBizDesignCst: string | '';
reqBizSpvsCst: string | '';
reqBizSbsdCst: string | '';
reqBizEtc: string | '';
/** 재원조달계획(백만원원) */
prcmPlanGrssCst : string | '';
prcmPlanNlep : string | '';
prcmPlanLcep : string | '';
prcmPlanBrdnCst : string | '';
prcmPlanEcqrRt : string | '';
prcmPlanGrssCst: string | '';
prcmPlanNlep: string | '';
prcmPlanLcep: string | '';
prcmPlanBrdnCst: string | '';
prcmPlanEcqrRt: string | '';
/** 사업비 정산(백만원) */
clclnGrssCst : string | '';
clclnNlep : string | '';
clclnLcep : string | '';
clclnBrdnCst : string | '';
clclnEcqrRt : string | '';
clclnGrssCst: string | '';
clclnNlep: string | '';
clclnLcep: string | '';
clclnBrdnCst: string | '';
clclnEcqrRt: string | '';
}
// 규칙 타입 선언
export type DisableRulesType = Record<string, string[]>;
@@ -255,144 +255,144 @@ export type DisableRulesType = Record<string, string[]>;
* Store - 데이터
====================================*/
// 수요처 정보
const demandCompList : DemandCompType[] = [
const demandCompList: DemandCompType[] = [
]
const disableRules: DisableRulesType = {
"청소": ["tn", 'tph',"clIonQnt" ,'cdtnv'],
"화장실용수": ["tn", 'tph',"clIonQnt" ,'cdtnv'],
"세척": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'],
"살수": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'],
"조경": ["combResdch", "crmty",'tph','cdtnv'],
"농업_간접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
"농업_직접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
"하천": ["combResdch", "trbt", "crmty" ,'clIonQnt','cdtnv'],
'공업':[]
};
"청소": ["tn", 'tph', "clIonQnt", 'cdtnv'],
"화장실용수": ["tn", 'tph', "clIonQnt", 'cdtnv'],
"세척": ["combResdch", "crmty", 'tph', 'tn', "clIonQnt", 'cdtnv'],
"살수": ["combResdch", "crmty", 'tph', 'tn', "clIonQnt", 'cdtnv'],
"조경": ["combResdch", "crmty", 'tph', 'cdtnv'],
"농업_간접용수": ["combResdch", "crmty", 'tn', 'tph', 'clIonQnt'],
"농업_직접용수": ["combResdch", "crmty", 'tn', 'tph', 'clIonQnt'],
"하천": ["combResdch", "trbt", "crmty", 'clIonQnt', 'cdtnv'],
'공업': []
};
const defaultRules: Record<string, object> = {
"청소": {
grssClfg: null,
combResdch:0.2,
trbt: 2,
bod: 5,
crmty: 20,
ph: "5.8~8.5",
smll:'불쾌하지않을것',
tn:null,
tph: null,
clIonQnt: null,
cdtnv: null,
const defaultRules: Record<string, object> = {
"청소": {
grssClfg: null,
combResdch: 0.2,
trbt: 2,
bod: 5,
crmty: 20,
ph: "5.8~8.5",
smll: '불쾌하지않을것',
tn: null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"화장실용수": {
grssClfg: null,
combResdch:0.2,
trbt: 2,
bod: 5,
crmty: 20,
smll:'불쾌하지않을것',
ph: "5.8~8.5",
tn:null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"세척": {
grssClfg: null,
trbt: 2,
bod: 5,
ph: "5.8~8.5",
combResdch:null,
smll:'불쾌하지않을것',
crmty:null,
tn:null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"살수": {
grssClfg: null,
trbt: 2,
bod: 5,
ph: "5.8~8.5",
smll:'불쾌하지않을것',
combResdch:null,
crmty:null,
tn:null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"조경": {
grssClfg: null,
trbt: 2,
bod: 5,
ph: "5.8~8.5",
smll:'불쾌하지않을것',
clIonQnt:250,
combResdch:null,
crmty:null,
tn:null,
tph: null,
cdtnv: null,
},
"농업_간접용수": {
grssClfg: null,
trbt: 5,
bod: 8,
ph: "5.8~8.5",
cdtnv:2000,
combResdch:null,
crmty:null,
tn:null,
tph: null,
clIonQnt: null,
},
"농업_직접용수": {
grssClfg: null,
trbt: 2,
bod: 8,
smll:'불쾌하지않을것',
ph: "5.8~8.5",
cdtnv:700,
combResdch:null,
crmty:null,
tn:null,
tph: null,
clIonQnt: null,
},
"하천": {
grssClfg: 1000,
bod: 5,
tn: 10,
tph: 0.5,
smll:'불쾌하지않을것',
ph: "5.8~8.5",
combResdch:null,
trbt:null,
crmty:null,
clIonQnt: null,
cdtnv:null
},
'공업':{
grssClfg: null,
bod: null,
tn: null,
tph: null,
ph: "~",
combResdch:null,
smll:'불쾌하지않을것',
trbt:null,
crmty:null,
clIonQnt: null,
cdtnv:null
}
};
},
"화장실용수": {
grssClfg: null,
combResdch: 0.2,
trbt: 2,
bod: 5,
crmty: 20,
smll: '불쾌하지않을것',
ph: "5.8~8.5",
tn: null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"세척": {
grssClfg: null,
trbt: 2,
bod: 5,
ph: "5.8~8.5",
combResdch: null,
smll: '불쾌하지않을것',
crmty: null,
tn: null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"살수": {
grssClfg: null,
trbt: 2,
bod: 5,
ph: "5.8~8.5",
smll: '불쾌하지않을것',
combResdch: null,
crmty: null,
tn: null,
tph: null,
clIonQnt: null,
cdtnv: null,
},
"조경": {
grssClfg: null,
trbt: 2,
bod: 5,
ph: "5.8~8.5",
smll: '불쾌하지않을것',
clIonQnt: 250,
combResdch: null,
crmty: null,
tn: null,
tph: null,
cdtnv: null,
},
"농업_간접용수": {
grssClfg: null,
trbt: 5,
bod: 8,
ph: "5.8~8.5",
cdtnv: 2000,
combResdch: null,
crmty: null,
tn: null,
tph: null,
clIonQnt: null,
},
"농업_직접용수": {
grssClfg: null,
trbt: 2,
bod: 8,
smll: '불쾌하지않을것',
ph: "5.8~8.5",
cdtnv: 700,
combResdch: null,
crmty: null,
tn: null,
tph: null,
clIonQnt: null,
},
"하천": {
grssClfg: 1000,
bod: 5,
tn: 10,
tph: 0.5,
smll: '불쾌하지않을것',
ph: "5.8~8.5",
combResdch: null,
trbt: null,
crmty: null,
clIonQnt: null,
cdtnv: null
},
'공업': {
grssClfg: null,
bod: null,
tn: null,
tph: null,
ph: "~",
combResdch: null,
smll: '불쾌하지않을것',
trbt: null,
crmty: null,
clIonQnt: null,
cdtnv: null
}
};
// 사용용도
const useTypesData : SelectDataType[] = [
const useTypesData: SelectDataType[] = [
{ text: '청소', val: "청소" },
{ text: "화장실용수", val: "화장실용수" },
{ text: "세척", val: "세척" },
@@ -440,8 +440,8 @@ export const similarCaseModalHeader: TableUpperProps[] = [
]
// 유사사례 데이터
const similarCaseList : SimilarCaseType[] = [
const similarCaseList: SimilarCaseType[] = [
]
// 사업비 상세정보 모달 헤더
@@ -477,12 +477,12 @@ export const moneyDetailModalHeader: TableUpperProps[] = [
]
// 사업비 상세정보
const moneyDetailList : MoneyDetailType[] = [
const moneyDetailList: MoneyDetailType[] = [
]
// 수요정보 신청현황 헤더
export const upHeadSdmInfoStatus: TableUpperProps[] = [
{ id: "index", title: "No."},
{ id: "index", title: "No." },
{ id: "ctpvCd", title: "시도", row: 0, rowSpan: 2 },
{ id: "sggCd", title: "시군구", row: 0, rowSpan: 2 },
{ id: "dmdCoNm", title: "회사명", row: 0, rowSpan: 2 },
@@ -501,7 +501,7 @@ export const upHeadSdmInfoStatus: TableUpperProps[] = [
const postSdmData = async (data: DemandCompType) => {
try {
await postFetch("/reuseFc/request", data);
sessionStorage.setItem("user", JSON.stringify(data) );
sessionStorage.setItem("user", JSON.stringify(data));
toast.success("수요처 등록에 성공하였습니다.");
return true;
} catch (error) {
@@ -526,16 +526,16 @@ const postSdmLoginData = async (data: DemandCompType) => {
try {
const res = await postFetch("/reuseFc/request/login", data);
const jsonData = await res.json();
const status = jsonData.status;
const loginData = jsonData.data;
let loginSuccess = false;
if(status === 200 && loginData != null) {
if (status === 200 && loginData != null) {
alert("수요처 로그인에 성공하였습니다.");
sessionStorage.setItem("user", JSON.stringify(loginData));
loginSuccess = true;
} else if(status === 401) {
alert("패스워드가 틀렸습니다.");
} else if (status === 401) {
alert("패스워드가 일치하지 않습니다.");
loginSuccess = false;
} else {
alert("등록된 수요처가 없습니다.");
@@ -553,35 +553,35 @@ const getDemandCompList = async (searchText: string, pageCnt: number) => {
try {
const url = '/reuseFc/request/' + (searchText ? searchText : '') + '/' + pageCnt;
const res = await getFetch(fetchType.WR, url);
return {
data: res?.data || [],
count: res?.count || 0
return {
data: res?.data || [],
count: res?.count || 0
}
} catch (error) {
console.error(error+' 수요처 정보를 불러오지 못했습니다.');
console.error(error + ' 수요처 정보를 불러오지 못했습니다.');
return { data: [], count: 0 };
}
}
const getSdmInfoStatusList = async (dmdInfoId : string) => {
const getSdmInfoStatusList = async (dmdInfoId: string) => {
try {
const url = '/reuseFc/request/' + dmdInfoId;
const res = await getFetch(fetchType.WR, url);
return res?.data || [];
} catch (error) {
console.error(error+' 수요정보 신청현황을 불러오지 못했습니다.');
console.error(error + ' 수요정보 신청현황을 불러오지 못했습니다.');
return [];
}
}
// 유사사례 조회
const fetchGetSimilarCaseList = async (part: string, value: number|string) => {
const fetchGetSimilarCaseList = async (part: string, value: number | string) => {
try {
const url = '/reuseFc/pubFcRuseCase/dm/' + part + '/' + (value ? value : 0);
const res = await getFetch(fetchType.WR, url);
return res?.data || [];
} catch (error) {
console.error(error+' 유사사례 조회에 실패하였습니다.');
console.error(error + ' 유사사례 조회에 실패하였습니다.');
return [];
}
}
@@ -590,23 +590,24 @@ const fetchGetSimilarCaseList = async (part: string, value: number|string) => {
* Store - expaort
====================================*/
export type SdmActions = {
initializeSdmData: () => void;
insertSdmData: (data: DemandCompType) => Promise<void>;
insertSdmInfoData: (data: DemandCompBizType) => Promise<void>;
getDemandCompList: (searchText: string, pageCnt: number) => Promise<void>;
actionLogin: (data: DemandCompType) => Promise<void>;
getSdmInfoStatusList: (dmdInfoId: string) => Promise<void>;
getSimilarCaseList: (part: string, value: number|string) => Promise<void>;
initializeSdmData: () => void;
insertSdmData: (data: DemandCompType) => Promise<void>;
insertSdmInfoData: (data: DemandCompBizType) => Promise<void>;
getDemandCompList: (searchText: string, pageCnt: number) => Promise<void>;
actionLogin: (data: DemandCompType) => Promise<void>;
getSdmInfoStatusList: (dmdInfoId: string) => Promise<void>;
getSimilarCaseList: (part: string, value: number | string) => Promise<void>;
actionLogout: () => Promise<void>;
}
export type SdmType ={
Sdm :{
export type SdmType = {
Sdm: {
isInit: boolean;
useTypesData: SelectDataType[];
demandCompList: DemandCompType[];
upHeadSimilarCaseList: TableUpperProps[];
similarCaseList: SimilarCaseType[];
upHeadMoneyDetailList : TableUpperProps[];
upHeadMoneyDetailList: TableUpperProps[];
moneyDetailList: MoneyDetailType[];
// 수요정보 신청현황
@@ -615,28 +616,28 @@ export type SdmType ={
defaultRules: Record<string, object>
disableRules: DisableRulesType;
// 로그인관련
successNextPage : boolean;
successNextPage: boolean;
successLogin: boolean;
}
}
export const SdmState: SdmType = {
Sdm:{
isInit:false,
Sdm: {
isInit: false,
useTypesData: useTypesData,
demandCompList: demandCompList,
upHeadSimilarCaseList: similarCaseModalHeader,
similarCaseList: similarCaseList,
upHeadMoneyDetailList : moneyDetailModalHeader,
upHeadMoneyDetailList: moneyDetailModalHeader,
moneyDetailList: moneyDetailList,
// 수요정보 신청현황
sdmInfoStatusList: [],
defaultRules:defaultRules,
disableRules:disableRules,
defaultRules: defaultRules,
disableRules: disableRules,
upHeadSdmInfoStatus: upHeadSdmInfoStatus,
// 로그인관련
successNextPage : false,
successNextPage: false,
successLogin: false,
}
}
@@ -648,13 +649,13 @@ export const SdmReducer = (set: any): SdmActions => {
insertSdmData: async (data: DemandCompType) => {
const preRes = await getSdmInfoStatusList(data.dmdInfoId);
if(preRes?.dmdInfoId) {
if (preRes?.dmdInfoId) {
toast.error('이미 등록된 수요처입니다.');
return;
}
const res = await postSdmData(data);
if(res) {
if (res) {
set((state: SdmType) => ({
Sdm: {
...state.Sdm,
@@ -671,7 +672,7 @@ export const SdmReducer = (set: any): SdmActions => {
// 수요처 정보
getDemandCompList: async (searchText: string, pageCnt: number) => {
const res = await getDemandCompList(searchText, pageCnt);
if(res.data.length === 0) {
if (res.data.length === 0) {
set((state: SdmType) => ({
Sdm: {
...state.Sdm,
@@ -693,7 +694,7 @@ export const SdmReducer = (set: any): SdmActions => {
getSdmInfoStatusList: async (dmdInfoId: string) => {
const res = await getSdmInfoStatusList(dmdInfoId);
if(res.length === 0) {
if (res.length === 0) {
set((state: SdmType) => ({
Sdm: {
...state.Sdm,
@@ -704,13 +705,13 @@ export const SdmReducer = (set: any): SdmActions => {
}
//const sdmInfoStatusList : DemandCompBizType[] = [];
const sdmInfoStatusList : DemandCompBizType[]= res.demandInfo.map((el: DemandCompBizType, index: number) => {
const sdmInfoStatusList: DemandCompBizType[] = res.demandInfo.map((el: DemandCompBizType, index: number) => {
const matchingInfo = res.demandMatchings.find((matching: DemandMatchings) => matching.dmdInfoSn === el.dmdInfoSn);
const status = matchingInfo?.splyFcltFlg?.trim() === 'Sub' ? '검토' : matchingInfo?.splyFcltFlg?.trim() === 'matched' ? '매칭완료' : '신청';
const ruseUtztnFcltNm = matchingInfo?.ruseUtztnFcltNm ? matchingInfo.ruseUtztnFcltNm : '';
return( {
return ({
...el,
index: ++index,
bzmnNo: res.bzmnNo,
@@ -723,8 +724,8 @@ export const SdmReducer = (set: any): SdmActions => {
sggCd: res.sggCd,
useUsgCd: el.useUsgCd,
dmndTmng: el.dmndTmng,
dmdInfoSn : el.dmdInfoSn,
status : status,
dmdInfoSn: el.dmdInfoSn,
status: status,
splyCndtList: el.splyCndtList,
ruseUtztnFcltNm: ruseUtztnFcltNm || ''
})
@@ -749,25 +750,47 @@ export const SdmReducer = (set: any): SdmActions => {
},
// 유사사례 조회
getSimilarCaseList: async (part: string, value: number|string) => {
getSimilarCaseList: async (part: string, value: number | string) => {
const res = await fetchGetSimilarCaseList(part, value);
if(res && res.length !== 0) {
const similarCaseList = res.map((el: SimilarCaseType) => {
const maskedBizNm = el.ruseBizNm
? el.ruseBizNm.replace(/^(\s*)^\S+/, "***") // 첫 단어(공백 전까지) 치환
: el.ruseBizNm;
return {
...el,
ruseBizNm: maskedBizNm,
};
});
console.log(similarCaseList);
if (similarCaseList && similarCaseList.length !== 0) {
set((state: SdmType) => ({
Sdm: {
Sdm: {
...state.Sdm,
similarCaseList: res,
similarCaseList: similarCaseList,
}
}))
return;
}else{
} else {
set((state: SdmType) => ({
Sdm: {
Sdm: {
...state.Sdm,
similarCaseList: [],
}
}))
return;
}
},
actionLogout: async () => {
sessionStorage.removeItem("user");
set((state: SdmType) => ({
Sdm: {
...state.Sdm,
successLogin: false,
}
}))
}
}
}
+6 -8
View File
@@ -85,22 +85,20 @@ export const DmStatusReducer = (set: any): DmStatusActions => {
const boardData: DmStatusBoardType[] = data.data.map(
(item: DmStatusDataType) => {
const regionText = cityCd.find((city) => item.region === city.val);
const regionText = item.sidoNm; //cityCd.find((city) => item.region === city.val);
const sewage = item.sewage;
const rainwater = item.rainwater;
const reclaimed = item.reclaimed;
const sewageCnt = item.sewageCnt;
const rainwaterCnt = item.rainwaterCnt;
const reclaimedCnt = item.reclaimedCnt;
console.log("regionText ", regionText);
if (regionText && regionText.text) {
return {
region: regionText ? regionText.text : item.region,
sewage: sewageCnt + "(" + sewage + ")",
rainwater: rainwaterCnt + "(" + rainwater + ")",
reclaimed: reclaimedCnt + "(" + reclaimed + ")",
region: regionText ? regionText : item.region,
sewage: sewageCnt + "(" + sewage.toLocaleString() + ")",
rainwater: rainwaterCnt + "(" + rainwater.toLocaleString() + ")",
reclaimed: reclaimedCnt + "(" + reclaimed.toLocaleString() + ")",
};
}
}
).filter((item): item is DmStatusBoardType => item !== undefined);
+6 -4
View File
@@ -1,14 +1,16 @@
export type DmStatusDataType = {
region: string;
sidoNm: string; // 시도명
region: string; // 시도코드
sewage: string;
rainwater: string;
reclaimed: string;
sewageCnt:string
rainwaterCnt:string
reclaimedCnt:string
sewageCnt:string;
rainwaterCnt:string;
reclaimedCnt:string;
};
export type DmStatusBoardType = {
sidoNm: string; // 시도명
region: string;
sewage: string;
rainwater: string;
+19 -6
View File
@@ -1,23 +1,33 @@
//8880
import { AUTH_USER_ID, CLAIM_NAME } from "@/src/shared/config";
import { DEV_URL_FO, DEV_URL_WR } from "../config";
import { getCookie } from "@common/components/lib/cookie";
const tokenId = getCookie(AUTH_USER_ID);
const Authorization = getCookie(CLAIM_NAME);
export const fetchType = {
COMMON: "common",
WR: "wr",
FO:'fo'
FO: "fo",
SN: "sn"
};
const API_VERSION = "/api/v1"
const servers = {
common: "",
local: "",
fo: "/operation-service" + API_VERSION,
wr: "/reuse-service" + API_VERSION,
sn: "/sewerage-service" + API_VERSION,
}
interface RequestParams {
[key: string]: unknown;
}
export const getFetch = async (type: string, url: string) => {
const baseUrl = type === fetchType.FO ? DEV_URL_FO : DEV_URL_WR;
const baseUrl = servers[type];
const response = await fetch(baseUrl + url, {
method: "GET",
headers: {
@@ -35,7 +45,8 @@ export const getFetch = async (type: string, url: string) => {
};
export const postFetch = async (url: string, params: RequestParams) => {
const response = await fetch(DEV_URL_WR + url, {
const baseUrl = servers[fetchType.WR];
const response = await fetch(baseUrl + url, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -52,7 +63,8 @@ export const postFetch = async (url: string, params: RequestParams) => {
};
export const putFetch = async (url: string, params: RequestParams) => {
const response = await fetch(DEV_URL_WR + url, {
const baseUrl = servers[fetchType.WR];
const response = await fetch(baseUrl + url, {
method: "PUT",
headers: {
"Content-Type": "application/json",
@@ -69,7 +81,8 @@ export const putFetch = async (url: string, params: RequestParams) => {
};
export const deleteFetch = async (url: string, params: RequestParams) => {
const response = await fetch(DEV_URL_WR + url, {
const baseUrl = servers[fetchType.WR];
const response = await fetch(baseUrl + url, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
@@ -950,7 +950,7 @@ export function SdmInfoRegForm({
body={
<ModalSimilarPage sply={sply} usageCd={usageCd} money={money} />
}
bodyClass="sm:max-w-[100vw] w-[1400px] h-[900px]"
bodyClass="sm:max-w-[100vw] w-[1400px] h-[100dvh] max-h-[900px] overflow-y-auto overflow-x-hidden"
open={isSimilarCase}
onOpenChange={(open) => !open && setIsSimilarCase(false)}
noHeaderYn="Y"
+8 -15
View File
@@ -1,13 +1,13 @@
import { NextRequest, NextResponse } from "next/server";
import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config";
import { SERVER_API_FO_URL, SERVER_API_WR_URL } from "./src/shared/config/env";
// import { SERVER_API_FO_URL, SERVER_API_WR_URL } from "./src/shared/config/env";
// const CLAIM_NAME = "Authorization";
// const AUTH_USER_ID = "token-id";
const serverApiUrl = process.env.NEXT_PUBLIC_CS_SERVER_API_URL;
const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || "";
const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || "";
const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || "";
const GATEWAY_URL = process.env.NEXT_PUBLIC_GATEWAY_URL || "";
const BUSINESS_JUSO_API_URL = process.env.NEXT_PUBLIC_FINDADRESS_URL || "";
const AdressKey = process.env.NEXT_PRIVATE_WR_ADDRESS_KEY || "";
@@ -112,7 +112,7 @@ export function middleware(req: NextRequest) {
const url = req.nextUrl.clone();
url.searchParams.set("TYPENAME", typename.replace("hasudo:", ""));
queryParams = url.searchParams.toString();
newUrl = `${SEWERAGE_API_URL}/api/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`;
newUrl = `${GATEWAY_URL}/api/v1/map/geometry${queryParams ? `?${queryParams}` : ""}`;
}
console.log(`[Middleware] Rewriting from '/geoserver' path to: ${newUrl}`);
@@ -121,24 +121,17 @@ export function middleware(req: NextRequest) {
if (pathname.startsWith("/reuse-service")) {
const queryParams = searchParams.toString();
const newUrl = `${SERVER_API_WR_URL}${pathname.replace("/reuse-service", "")}${queryParams ? `?${queryParams}` : ""
}`;
const newUrl = `${GATEWAY_URL}${pathname}${queryParams ? `?${queryParams}` : ""}`;
console.log(`[Middleware] Rewriting from '/reuse-service' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl));
}
if (pathname.startsWith("/operation-service")) {
} else if (pathname.startsWith("/operation-service")) {
const queryParams = searchParams.toString();
const newUrl = `${SERVER_API_FO_URL}${pathname.replace("/operation-service", "")}${queryParams ? `?${queryParams}` : ""
}`;
const newUrl = `${GATEWAY_URL}${pathname}${queryParams ? `?${queryParams}` : ""}`;
console.log(`[Middleware] Rewriting from '/operation-service' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl));
}
if (pathname.startsWith("/sewerage-service")) {
} else if (pathname.startsWith("/sewerage-service")) {
const queryParams = searchParams.toString();
const newUrl = `${SEWERAGE_API_URL}${pathname.replace("/sewerage-service", "")}${queryParams ? `?${queryParams}` : ""
}`;
const newUrl = `${GATEWAY_URL}${pathname}${queryParams ? `?${queryParams}` : ""}`;
console.log(`[Middleware] Rewriting from '/sewerage-service' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl));
}
+3
View File
@@ -5,6 +5,9 @@ const subDomain =
const nextConfig: NextConfig = {
output: "standalone",
experimental: {
proxyTimeout: 600000,
},
async rewrites() {
return {
beforeFiles: [
@@ -9,67 +9,111 @@
* @author jsyang
*/
export default function CalcRainEffect(data : any, weather='ALL') {
/* console.log("%c Calculate RainEffect !" , "background:blue;color:white");
console.log("%c Data Length :"+data.length+" Weather : "+weather , "background:yellow;color:blue");*/
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
for(let idx = 0; idx < data.length; idx++) {
export default function CalcRainEffect(data: any, weather = 'ALL') {
const rtnDataAll: any = [];
const rtnDataSunny: any = [];
const rtnDataRain: any = [];
let rtnData: any = [];
let rainEffectStd = 0;
for (let idx = 0; idx < data.length; idx++) {
const item = data[idx];
if(item){
if(item.infoRnDay && Number(item.infoRnDay) >= 3) { // 강우량이 3 이상인 경우
item.rainEffectDay = 1;
} else {
item.rainEffectDay = 0;
}
if(item.infoRnDay == 'x'){
item.infoRnDay = '0.0';
item.toBeInfoRnDay = '0.0';
}else{
item.infoRnDay = Number(item.infoRnDay).toFixed(1);
item.toBeInfoRnDay = Number(item.infoRnDay).toFixed(1);
}
if (item.infoRnDay == null || item.infoRnDay == 'x' || item.infoRnDay == '') item.infoRnDay = 0;
if (Number(item.infoRnDay) >= 3) { // 강우일
rainEffectStd = 2;
item.toBeInfoRnDay = item.infoRnDay;
} else {
rainEffectStd--;
}
}
// 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
for(let idx = 0; idx < data.length; idx++) {
if(data[idx]) {
// 하루 전이 강우영향일(3 이상)인 경우
if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) {
data[idx]!.rainEffectDay = 1;
}
// 이틀 전이 강우영향일(3 이상)인 경우
if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) {
data[idx]!.rainEffectDay = 1;
}
}
}
for(let idx = 0; idx < data.length; idx++) {
if(data[idx] && data[idx]?.rainEffectDay === 1) {
if(idx > 1){
if (rainEffectStd < 0) { // 청천일
item.rainEffectDay = 0;
rtnDataSunny.push(item);
} else if (rainEffectStd >= 0) { // 강우일 + 강우영향일
item.rainEffectDay = 1;
if (idx > 1) {
// 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정
if(data[idx-1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx-1]!.infoRnDay;
if (data[idx - 1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx - 1]!.infoRnDay;
}
}
if(idx > 2){
if (idx > 2) {
// 전전날 비가 왔고 오늘 강우량 3미만인 경우 전전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전전날 강우량으로 설정
if(data[idx-2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx-2]!.infoRnDay;
if (data[idx - 2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx - 2]!.infoRnDay;
}
}
rtnDataRain.push(item);
}
rtnDataAll.push(item);
}
let rtnData : any = [];
// // 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
// for(let idx = 0; idx < data.length; idx++) {
// const item = data[idx];
// if(item){
// if(item.infoRnDay && Number(item.infoRnDay) >= 3) { // 강우량이 3 이상인 경우
// item.rainEffectDay = 1;
// } else {
// item.rainEffectDay = 0;
// }
// if(item.infoRnDay == 'x'){
// item.infoRnDay = '0.0';
// item.toBeInfoRnDay = '0.0';
// }else{
// item.infoRnDay = Number(item.infoRnDay).toFixed(1);
// item.toBeInfoRnDay = Number(item.infoRnDay).toFixed(1);
// }
// }
// }
// // 이틀 전, 하루 전이 강우영향일(3 이상)인 경우 해당 날도 강우영향일로 설정
// for(let idx = 0; idx < data.length; idx++) {
// if(data[idx]) {
// // 하루 전이 강우영향일(3 이상)인 경우
// if(idx > 0 && data[idx-1]?.infoRnDay && Number(data[idx-1]?.infoRnDay) >= 3) {
// data[idx]!.rainEffectDay = 1;
// }
// // 이틀 전이 강우영향일(3 이상)인 경우
// if(idx > 1 && data[idx-2]?.infoRnDay && Number(data[idx-2]?.infoRnDay) >= 3) {
// data[idx]!.rainEffectDay = 1;
// }
// }
// }
// for(let idx = 0; idx < data.length; idx++) {
// if(data[idx] && data[idx]?.rainEffectDay === 1) {
// if(idx > 1){
// // 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정
// if(data[idx-1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-1]?.infoRnDay.toString().trim()) >= 3) {
// data[idx]!.toBeInfoRnDay = data[idx-1]!.infoRnDay;
// }
// }
// if(idx > 2){
// // 전전날 비가 왔고 오늘 강우량 3미만인 경우 전전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전전날 강우량으로 설정
// if(data[idx-2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx-2]?.infoRnDay.toString().trim()) >= 3) {
// data[idx]!.toBeInfoRnDay = data[idx-2]!.infoRnDay;
// }
// }
// }
// }
// if (weather === 'ALL') {
// rtnData = data;
// } else if (weather === 'SUNNY') {
// rtnData = data.filter((item: any) => item.rainEffectDay === 0);
// } else {
// rtnData = data.filter((item: any) => item.rainEffectDay === 1);
// }
if (weather === 'ALL') {
rtnData = data;
rtnData = rtnDataAll;
} else if (weather === 'SUNNY') {
rtnData = data.filter((item: any) => item.rainEffectDay === 0);
rtnData = rtnDataSunny;
} else {
rtnData = data.filter((item: any) => item.rainEffectDay === 1);
rtnData = rtnDataRain;
}
return rtnData;
}
+50 -23
View File
@@ -4,12 +4,39 @@
item: Record<string, unknown>;
}
export const roundNumber = (value : any, decimals: number) => {
/**
* yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환
* @param {string} yyyymm - 예: "202502", "202412"
* @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31)
*/
export const getDaysInMonth = (yyyymm: string) => {
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
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();
}
export const roundNumber = (value: any, decimals: number) => {
if (typeof value === 'number') {
return addCommas((Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals));
} else if (typeof value === 'string' && !isNaN(Number(value))) {
return addCommas(Number(value).toFixed(decimals));
} else if (typeof value === 'string') {
// 콤마가 포함된 문자열 처리 ('1,083.0' 같은 경우)
const cleanedValue = value.replace(/,/g, '');
if (!isNaN(Number(cleanedValue))) {
return addCommas(Number(cleanedValue).toFixed(decimals));
}
}
return value; // 변환 불가능한 경우 원래 값 반환
}
export const addCommas = (value: string | number): any => {
@@ -18,48 +45,48 @@ export const addCommas = (value: string | number): any => {
index === 0 ? part : part.replace(/(\d{3})/g, '$1,')
).join('.');
} else if (typeof value === 'string') {
return value.includes('.')?value.split('.').map((part, index) =>
return value.includes('.') ? value.split('.').map((part, index) =>
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.'):String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
).join('.') : String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
}
export default function DataForm({ type, column, item }: DataFormProps) {
if(item) {
if (item) {
const value = item[column];
switch(type){
switch (type) {
case 'date':
if(value && typeof value === 'string' && value.length >= 8)
if (value && typeof value === 'string' && value.length >= 8 && !value.includes('-'))
item[column] = value.substring(0, 4) + "-" + value.substring(4, 6) + "-" + value.substring(6, 8);
break;
break;
case 'number':
if(value && value != '') {
if (value && value != '') {
item[column] = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
break;
break;
case 'float0':
if(value) {
item[column] = item[column] = String(value).includes('.')?String(Math.round(parseFloat(value.toString().replace(/,/g, '')) * 1) / 1).split('.').map((part, index) =>
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.')
: String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if (value) {
item[column] = item[column] = String(value).includes('.') ? String(Math.round(parseFloat(value.toString().replace(/,/g, '')) * 1) / 1).split('.').map((part, index) =>
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.')
: String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
break;
break;
case 'float1':
if(value) {
if (value) {
item[column] = roundNumber(value, 1);
}
break;
break;
case 'float2':
if(value) {
if (value) {
item[column] = roundNumber(value, 2);
}
break;
break;
case 'float3':
if(value) {
if (value) {
item[column] = roundNumber(value, 3);
}
break;
break;
}
}
}
@@ -4,14 +4,14 @@ import ListDiv from '@common/business_components/ui/list_div';
import { Table, TableCell, TableHead, TableRow } from '@common/components/ui';
import { useCallback, useEffect, useRef, useState } from 'react';
type FacilityTermModalHeaderProps<T extends { msrDt: string }> = {
fcltyCd : string;
type FacilityTermModalHeaderProps<T extends { msrDt: string }> = { // T는 반드시 msrDt: string 필드를 가져야 한다
fcltyCd: string;
fcltyName: string;
tabName: string;
searchYear: string;
searchList: T[];
ref: React.RefObject<ReturnType<T>>;
queryClick:(returnType:ReturnType<T>) => void;
queryClick: (returnType: ReturnType<T>) => void;
}
export type ReturnType<T> = {
@@ -21,27 +21,28 @@ export type ReturnType<T> = {
filteredList: T[];
}
export default function FacilityTermModalHeader<T extends { msrDt: string }>({
export default function FacilityTermModalHeader<T extends { msrDt: string }>({
searchList,
fcltyName,
tabName,
fcltyName,
tabName,
searchYear,
queryClick,
ref
}: FacilityTermModalHeaderProps<T & { msrDt: string }>) {
const {Common} = useFoStore((state) => state);
const { Common } = useFoStore((state) => state);
const { selectFlowPanel } = Common;
const [startDate, setStartDate] = useState<Date>(new Date(Number(searchYear), 0, 1));
const [endDate, setEndDate] = useState<Date>(new Date(Number(searchYear), 11, 31));
const startPickerRef = useRef<HTMLDivElement>(null);
const endPickerRef = useRef<HTMLDivElement>(null);
const [flowPanel, setFlowPanel] = useState<string>(selectFlowPanel[0]?.val ?? '00');
const [flowPanel, setFlowPanel] = useState<string>(selectFlowPanel[0]?.val ?? '0'); // 강수구분 : 초기값 "전체"
const [copySearchList, setCopySearchList] = useState<T[]>(searchList);
const [standSearchList, setStandSearchList] = useState<T[]>(searchList);
const isDateInRanges = (date: Date) => {
const standYear = parseInt(searchYear);
const dateRanges:{start:Date, end:Date}[] = [];
const isLeapYear = (standYear % 4 === 0 && standYear % 100 !== 0) || (standYear % 400 === 0);
const dateRanges: { start: Date, end: Date }[] = [];
if (tabName.includes("_summer")) {
dateRanges.push({
@@ -51,7 +52,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
} else if (tabName.includes("_winter")) {
dateRanges.push({
start: new Date(standYear, 0, 1),
end: new Date(standYear, 1, 28)
end: new Date(standYear, 1, isLeapYear ? 29 : 28)
});
} else {
dateRanges.push({
@@ -70,67 +71,69 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
useEffect(() => {
let startDate = new Date(Number(searchYear), 0, 1);
let endDate = new Date(Number(searchYear), 11, 31);
const standYear = Number(searchYear);
const isLeapYear = (standYear % 4 === 0 && standYear % 100 !== 0) || (standYear % 400 === 0);
if(tabName.includes("_summer")) {
startDate = new Date(Number(searchYear), 5, 1);
endDate = new Date(Number(searchYear), 7, 31);
if (tabName.includes("_summer")) { // 하절기
startDate = new Date(Number(searchYear), 5, 1); // 6월 ~
endDate = new Date(Number(searchYear), 7, 31); // 8월
setStartDate(startDate);
setEndDate(endDate);
} else if (tabName.includes("_winter")) {
startDate = new Date(Number(searchYear), 0, 1);
endDate = new Date(Number(searchYear), 1, 28);
} else if (tabName.includes("_winter")) { // 동절기
startDate = new Date(Number(searchYear), 0, 1); // 1월 ~
endDate = new Date(Number(searchYear), 1, isLeapYear ? 29 : 28); // 2월
setStartDate(startDate);
setEndDate(endDate);
} else {
} else { // 연간
startDate = new Date(Number(searchYear), 0, 1);
endDate = new Date(Number(searchYear), 11, 31);
setStartDate(startDate);
setEndDate(endDate);
}
let filteredData: T[] = [];
if(tabName.includes("_rain")) {
if (tabName.includes("_rain")) { // 강우시
filteredData = searchList.filter((item) => {
const itemDate = new Date((item as T & { msrDt: string }).msrDt);
const itemDateOnly = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate());
const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
const rainEffectDay = (item as T & { rainEffectDay: number }).rainEffectDay;
if(flowPanel === '2'){
if (flowPanel === '2') { //3~10mm미만
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 3 && infoRnDay < 10;
} else if(flowPanel === '3'){
} else if (flowPanel === '3') { //10~20mm미만
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 10 && infoRnDay < 20;
} else if(flowPanel === '4'){
} else if (flowPanel === '4') { //20~30mm미만
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 20 && infoRnDay < 30;
} else if(flowPanel === '5'){
} else if (flowPanel === '5') { //30~40mm미만
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 30 && infoRnDay < 40;
} else if(flowPanel === '6'){
} else if (flowPanel === '6') { //40~50mm미만
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 40 && infoRnDay < 50;
} else if(flowPanel === '7'){
} else if (flowPanel === '7') { //50~60mm미만
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 50 && infoRnDay < 60;
} else if(flowPanel === '8'){
} else if (flowPanel === '8') {
const infoRnDay = (item as T & { toBeInfoRnDay: number }).toBeInfoRnDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && infoRnDay >= 60;
} else {
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && (rainEffectDay ===1);
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && (rainEffectDay === 1);
}
});
} else if(tabName.includes("_chuncheon")) {
} else if (tabName.includes("_chuncheon")) { // 청천시
filteredData = searchList.filter((item) => {
const itemDate = new Date((item as T & { msrDt: string }).msrDt);
const itemDateOnly = new Date(itemDate.getFullYear(), itemDate.getMonth(), itemDate.getDate());
const startDateOnly = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
const rainEffectDay = (item as T & { rainEffectDay: number }).rainEffectDay;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && rainEffectDay==0;
return (itemDateOnly >= startDateOnly && itemDateOnly <= endDateOnly) && rainEffectDay == 0;
});
} else {
filteredData = searchList.filter((item) => {
@@ -146,7 +149,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
}, [searchList, searchYear, tabName, flowPanel]);
const handleStartDateSelect = (day: Date | undefined) => {
if(day && day > endDate) {
if (day && day > endDate) {
alert('종료일은 시작일 이전일 수 없습니다.');
return;
}
@@ -169,7 +172,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
};
const handleEndDateSelect = (day: Date | undefined) => {
if(day && day < startDate) {
if (day && day < startDate) {
alert('종료일은 시작일 이후일 수 없습니다.');
return;
}
@@ -190,7 +193,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
});
setCopySearchList(filteredData);
};
const fncSetFilteredList = useCallback(() => {
queryClick({
startDate: startDate,
@@ -203,9 +206,9 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
useEffect(() => {
fncSetFilteredList();
}, [fncSetFilteredList]);
useEffect(() => {
if(ref && ref.current) {
if (ref && ref.current) {
const customRef = ref.current;
customRef.startDate = startDate;
customRef.endDate = endDate;
@@ -222,18 +225,18 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
<TableRow className="!h-[20px]">
<TableHead className="w-[120px]">{'시설명'}</TableHead>
{tabName === "tab_term_rain" ? <TableCell className="w-[300px]">{fcltyName}</TableCell> :
<TableCell className="w-[380px]">{fcltyName}</TableCell>}
<TableCell className="w-[380px]">{fcltyName}</TableCell>}
{tabName === "tab_term_rain" && (
<>
<TableHead className="w-[120px]">{'강수구분'}</TableHead>
<TableCell className="w-[250px]">
<div className="justify-center">
<SelectBox
selectArray={selectFlowPanel}
<SelectBox
selectArray={selectFlowPanel}
value={flowPanel}
onSelectValue={(val) => setFlowPanel(val.toString())}
className="mx-3 w-[150px]"
label=""
className="mx-3 w-[150px]"
label=""
selectClass="w-full p-1 border rounded bg-white"
/>
</div>
@@ -244,7 +247,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
<TableCell className="">
<div className="flex">
<div ref={startPickerRef} className="flex justify-center">
<DatePickerRange
<DatePickerRange
mode="single"
selected={startDate}
onSelect={(date) => handleStartDateSelect(date as Date)}
@@ -258,7 +261,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
<DatePickerRange
mode="single"
selected={endDate}
onSelect={(date) => handleEndDateSelect(date as Date)}
onSelect={(date) => handleEndDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
disabled={(date) => !isDateInRanges(date)}
defaultMonth={endDate}
@@ -6,7 +6,10 @@
"use client"
import { useFoStore } from "@/app/store";
import { ContentsDiv, downloadExcel, downloadMultipleExcel, filePickedBlobArray, MainDiv, SelectBox, UITab, type SelectDataType } from "@common/business_components";
import {
ContentsDiv, downloadExcel, downloadMultipleExcel, filePickedBlobArray, MainDiv
, SelectBox, UITab, type SelectDataType
} from "@common/business_components";
import { Button, TabsContent } from "@common/components/ui";
import { useEffect, useState } from "react";
import DashBoardFclty from "../dashboardMain/page";
@@ -50,9 +53,9 @@ type FacilityType = {
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<string>('facilityInfo');
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]);
const [sidoValue, setSidoValue] = useState<string>('0');
const [sigunValue, setSigunValue] = useState<string>('0');
@@ -15,27 +15,13 @@ export type facilityInfoProps = {
fcltyList?: { bscFctCd: string, bscFctNm: string, fcltyCpc: number | '', trtFrfNm: string, efflWqltStndrdNm: string }[];
};
export default function RainManageTab({searchYear = '', fcltyList = []}: facilityInfoProps) {
const {
Common,
searchRainManage,
RainManage
} = useFoStore((state) => state);
export default function RainManageTab({ searchYear = '', fcltyList = [] }: facilityInfoProps) {
const { Common, searchRainManage, RainManage } = useFoStore((state) => state);
const [hasSearched, setHasSearched] = useState(false);
// 이전 시설코드 저장
const [prevFacilityCode, setPrevFacilityCode] = useState<string>('');
const {
isInit,
} = Common;
const {
upHeadListRainManage,
rainManageList,
} = RainManage;
const [prevFacilityCode, setPrevFacilityCode] = useState<string>(''); // 이전 시설코드 저장
const { isInit, } = Common;
const { upHeadListRainManage, rainManageList, } = RainManage;
const tableData = fcltyList;
useEffect(() => {
@@ -50,17 +36,17 @@ export default function RainManageTab({searchYear = '', fcltyList = []}: facilit
useEffect(() => {
setHasSearched(false);
}, [searchYear]);
return (
<div>
<UiTable
<UiTable
headName=""
tableData={rainManageList}
headlist={upHeadListRainManage}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
onPageChange={() => { }}
widthFixed={true}
>
</UiTable>
@@ -9,7 +9,7 @@ import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { roundNumber } from "@/app/components/common/DataForm";
import { useFoStore } from "@/app/store";
import type { PrecipitationPropsDetailProps } from "@/app/store/facilityPrecipitation";
import { DatePickerRange, downloadExcel, UiTable } from "@common/business_components/ui";
import { DatePickerRange, downloadExcelHeaders, UiTable } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
@@ -45,7 +45,7 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
const standYear = parseInt(props.searchYear);
return [{
start: new Date(standYear, 0, 1),
end: new Date(standYear, 11, 31)
end: new Date(standYear, 11, 31) //월의 index는 0부터 시작
}];
};
@@ -112,7 +112,6 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
const getTableData = () => {
const totals = calculateTotals();
totals.infoRnDay = roundNumber(totals.infoRnDay, 1);
return [
{
bscFctCd: "",
@@ -157,19 +156,26 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
const excelDownload = () => {
const totData = getTableData();
const excelDownList: any[] = [];
// 헤더 순서를 명시적으로 정의
const headers = ["날짜", "강수량(mm/일)", "강우일(일)", "강우영향일(일)"] as const;
const excelDownList: Record<string, string | number>[] = [];
if(totData.length > 0){
totData.forEach((item) => {
excelDownList.push({
"날짜": item.rainDt,
"강수량(mm/일)": roundNumber(item.infoRnDay, 1),
"강우일(일)": roundNumber(item.rainDay, 0),
"강우영향일(일)": roundNumber(item.rainEffectDay, 0),
});
// 순서를 보장하기 위해 헤더 순서대로 객체 생성
const row: Record<string, string | number> = {};
row[headers[0]] = item.rainDt;
row[headers[1]] = roundNumber(item.infoRnDay, 1);
row[headers[2]] = roundNumber(item.rainDay, 0);
row[headers[3]] = roundNumber(item.rainEffectDay, 0);
excelDownList.push(row);
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황', sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1' });
downloadExcelHeaders({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 강수현황'
, sheetNameArray: ['지하수유입량'], headerRange: 'A1:D1', headers });
} else if (totData.length == 0) {
alert('다운받을 데이터가 없습니다.');
}
@@ -209,10 +209,13 @@ export default function FacilityPrecipitation() {
<ContentsDiv>
<SearchBaseForm
leftChildren={<>
<SelectBox className="col-span-3" label={labelArray[3] as string} selectArray={selectUpdownData} onSelectValue={(val) => setFcltCpct(val.toString())} value={fcltCpct} selectClass={undefined} />
<SelectBox className="col-span-3" label={labelArray[3] as string} selectArray={selectUpdownData}
onSelectValue={(val) => setFcltCpct(val.toString())} value={fcltCpct} selectClass={undefined} />
<SearchInput className={"col-span-3"} label={labelArray[4] as string} textValue={fcltyName} setText={setFcltyName} />
<SelectBox className="col-span-3" label={labelArray[6] as string} selectArray={selectSearchYear} onSelectValue={(val) => setSearchYear(val.toString())} value={searchYear} selectClass={undefined} />
<SelectBox className="col-span-3" label={labelArray[5] as string} selectArray={selectOperationData} onSelectValue={(val) => setOperationValue(val.toString())} value={operationValue} selectClass={undefined} />
<SelectBox className="col-span-3" label={labelArray[6] as string} selectArray={selectSearchYear}
onSelectValue={(val) => setSearchYear(val.toString())} value={searchYear} selectClass={undefined} />
<SelectBox className="col-span-3" label={labelArray[5] as string} selectArray={selectOperationData}
onSelectValue={(val) => setOperationValue(val.toString())} value={operationValue} selectClass={undefined} />
</>}
rightChildren={undefined}
selectSidoData={selectSidoData}
@@ -226,16 +229,19 @@ export default function FacilityPrecipitation() {
excelClick={excelDownload}
initClick={resetVal}
ref={ref} isAdmin={false}/>
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden">
<div className="w-[120%] min-[1200px]:w-[100%]">
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"시설별 강수현황"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden">
<div className="w-[120%] min-[1200px]:w-[100%]">
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)}
headName={"시설별 강수현황"}
tableData={mainList} headlist={upheadList} pageSize={10} total={total}
resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
</div>
<UnderComment divHeight={"3"} commentArray={["강우일은 3mm 이상만 해당 / 강우영향일은 강우일 및 강우일 후 연속 2일간으로 정의"]} />
</div>
<UnderComment divHeight={"3"} commentArray={["강우일은 3mm 이상만 해당 / 강우영향일은 강우일 및 강우일 후 연속 2일간으로 정의"]} />
</div>
</ListDiv>
</ContentsDiv>
</ListDiv>
</ContentsDiv>
{selectedRow !== null && (
<UiModal
body={<PrecipitationModal searchYear={searchYear} fcltyName={fcltyNm} facilityCd={fcltyCd} detailList={gridListPrecipitationDetail}></PrecipitationModal>}
@@ -25,10 +25,10 @@ const commentArrayRain = [
"강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날"
];
type ModalProps ={
type ModalProps = {
fcltyName: string;
facilityCd : string;
searchYear : string;
facilityCd: string;
searchYear: string;
}
const tabList1 = [
@@ -50,15 +50,13 @@ const tabList3 = [
{ value: 'tab_term_winter_chongin', label: '동절기' }
];
export default function WaterQualityModal({fcltyName='', facilityCd='', searchYear=new Date().getFullYear().toString()} : ModalProps) {
export default function WaterQualityModal({ fcltyName = '', facilityCd = '', searchYear = new Date().getFullYear().toString() }: ModalProps) {
const [tabName, setTabName] = useState<string>('tab_num1');
// 그리드 관련
const {FacilityWaterQltyModal,
searchFacilityWaterQltyListHist,
Common
} = useFoStore((state) => state);
const {btnClass, COD_YEAR} = Common;
// 날짜 필터링 관련 상태
const [copyYearList, setCopyYearList] = useState<FacilityWaterQltyProps[]>([]);
const [chongInWaterQltyYearList, setChongInWaterQltyYearList] = useState<FacilityWaterQltyProps[]>([]);
const { FacilityWaterQltyModal, searchFacilityWaterQltyListHist, Common } = useFoStore((state) => state);
const { btnClass, COD_YEAR } = Common;
const {
upHeadListModalYear,
upHeadListModalYearCod,
@@ -71,7 +69,17 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
const prevExcelListRef = useRef<modalExcelType[] | null>(null);
const prevChoinginExcelListRef = useRef<modalChoinginExcelType[] | null>(null);
useEffect(() => {
searchFacilityWaterQltyListHist(searchYear, facilityCd);
}, [searchYear, facilityCd, searchFacilityWaterQltyListHist]);
useEffect(() => {
const filteredYearData = setFilterAfterData(facilityWaterQltyYearList);
setCopyYearList(filteredYearData as FacilityWaterQltyProps[]);
setChongInWaterQltyYearList(facilityWaterQltyYearList);
}, [facilityWaterQltyYearList]);
// 필터링 된 후 최대, 최소, 평균 값 계산
const setFilterAfterData = (filteredData: FacilityWaterQltyProps[]) => {
// 쉼표가 포함된 문자열을 숫자로 변환하는 함수
@@ -100,7 +108,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
let maxNoProcessInflAmnt = 0;
let maxInfoRnDay = 0;
// 초기값 설정
let minEfflWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltBod) : 0;
let minEfflWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltTn) : 0;
@@ -108,14 +116,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
let minefflWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltToc) : 0;
let minefflWqltCod = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltCod) : 0;
let minEfflWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.efflWqltSs) : 0;
let mininflAssctBfrWqltBod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltBod) : 0;
let mininflAssctBfrWqltTn = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTn) : 0;
let minInflAssctBfrWqltTp = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltTp) : 0;
let mininflAssctBfrWqltToc = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltToc) : 0;
let mininflAssctBfrWqltCod = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltCod) : 0;
let mininflAssctBfrWqltSs = filteredData.length > 0 ? parseNumber(filteredData[0]?.inflAssctBfrWqltSs) : 0;
let minTpInflWqltBod = 99999999;
let minTpInflWqltTp = 99999999;
let minNoProcessInflAmnt = 99999999;
@@ -143,27 +151,27 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
let noProcessInflAmntCnt = 0;
let avgInfoRnDay = 0;
filteredData.forEach((item: FacilityWaterQltyProps) => {
const efflWqltBod = parseNumber(item.efflWqltBod);
const efflWqltTn = parseNumber(item.efflWqltTn);
const efflWqltTp = parseNumber(item.efflWqltTp);
const efflWqltToc = parseNumber(item.efflWqltToc);
const efflWqltCod = parseNumber(item.efflWqltCod?item.efflWqltCod.replaceAll("(","").replaceAll(")",""):0);
const efflWqltCod = parseNumber(item.efflWqltCod ? item.efflWqltCod.replaceAll("(", "").replaceAll(")", "") : 0);
const efflWqltSs = parseNumber(item.efflWqltSs);
const inflAssctBfrWqltBod = parseNumber(item.inflAssctBfrWqltBod);
const inflAssctBfrWqltTn = parseNumber(item.inflAssctBfrWqltTn);
const inflAssctBfrWqltTp = parseNumber(item.inflAssctBfrWqltTp);
const inflAssctBfrWqltToc = parseNumber(item.inflAssctBfrWqltToc);
const inflAssctBfrWqltCod = parseNumber(item.inflAssctBfrWqltCod?item.inflAssctBfrWqltCod.replaceAll("(","").replaceAll(")",""):0);
const inflAssctBfrWqltCod = parseNumber(item.inflAssctBfrWqltCod ? item.inflAssctBfrWqltCod.replaceAll("(", "").replaceAll(")", "") : 0);
const inflAssctBfrWqltSs = parseNumber(item.inflAssctBfrWqltSs);
const tpInflWqltBod = parseNumber(item.tpInflWqltBod);
const tpInflWqltTp = parseNumber(item.tpInflWqltTp);
if(item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined ){
if (item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined) {
tpInflWqltBodCnt += 1;
}
if(item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined ){
if (item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined) {
tpInflWqltTpCnt += 1;
}
@@ -175,7 +183,7 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
maxefflWqltToc = Math.max(maxefflWqltToc, efflWqltToc);
maxefflWqltCod = Math.max(maxefflWqltCod, efflWqltCod);
maxEfflWqltSs = Math.max(maxEfflWqltSs, efflWqltSs);
maxinflAssctBfrWqltBod = Math.max(maxinflAssctBfrWqltBod, inflAssctBfrWqltBod);
maxinflAssctBfrWqltTn = Math.max(maxinflAssctBfrWqltTn, inflAssctBfrWqltTn);
maxInflAssctBfrWqltTp = Math.max(maxInflAssctBfrWqltTp, inflAssctBfrWqltTp);
@@ -202,11 +210,11 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
mininflAssctBfrWqltCod = Math.min(mininflAssctBfrWqltToc, inflAssctBfrWqltCod);
mininflAssctBfrWqltSs = Math.min(mininflAssctBfrWqltSs, inflAssctBfrWqltSs);
if(item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined ){
if (item.tpInflWqltBod != null && item.tpInflWqltBod.trim() != '' && item.tpInflWqltBod != undefined) {
minTpInflWqltBod = Math.min(minTpInflWqltBod, tpInflWqltBod);
avgTpInflWqltBod += tpInflWqltBod;
}
if(item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined ){
if (item.tpInflWqltTp != null && item.tpInflWqltTp.trim() != '' && item.tpInflWqltTp != undefined) {
minTpInflWqltTp = Math.min(minTpInflWqltTp, tpInflWqltTp);
avgTpInflWqltTp += tpInflWqltTp;
}
@@ -227,12 +235,12 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
avginflAssctBfrWqltCod += inflAssctBfrWqltCod;
avginflAssctBfrWqltSs += inflAssctBfrWqltSs;
if(item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined){
const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',',''));
if (item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined) {
const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',', ''));
avgNoProcessInflAmnt += noProcessInflAmnt;
maxNoProcessInflAmnt = Math.max(maxNoProcessInflAmnt, noProcessInflAmnt);
minNoProcessInflAmnt = Math.min(minNoProcessInflAmnt, noProcessInflAmnt);
noProcessInflAmntCnt +=1;
noProcessInflAmntCnt += 1;
}
avgInfoRnDay += infoRnDay;
@@ -241,18 +249,18 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
const newFilteredData = [
{
msrDt: '평균',
efflWqltBod: filteredData.length==0 || avgEfflWqltBod===0?'0.0':roundNumber((avgEfflWqltBod / filteredData.length), 1),
efflWqltToc: filteredData.length==0 || avgefflWqltToc===0?'0.0':roundNumber((avgefflWqltToc / filteredData.length), 1),
efflWqltCod: filteredData.length==0 || avgefflWqltCod===0?"(0.0)":"("+roundNumber((avgefflWqltCod / filteredData.length), 1)+")",
efflWqltSs: filteredData.length==0 || avgEfflWqltSs===0?'0.0':roundNumber((avgEfflWqltSs / filteredData.length), 1),
efflWqltTn: filteredData.length==0 || avgEfflWqltTn ===0?'0.000':roundNumber((avgEfflWqltTn / filteredData.length), 3),
efflWqltTp: filteredData.length==0 || avgEfflWqltTp ===0?'0.000':roundNumber((avgEfflWqltTp / filteredData.length), 3),
inflAssctBfrWqltBod: filteredData.length==0 || avginflAssctBfrWqltBod===0?'0.0':roundNumber((avginflAssctBfrWqltBod / filteredData.length), 1),
inflAssctBfrWqltTn: filteredData.length==0 || avginflAssctBfrWqltTn===0?'0.000':roundNumber((avginflAssctBfrWqltTn / filteredData.length), 3),
inflAssctBfrWqltTp: filteredData.length==0 || avgInflAssctBfrWqltTp===0?'0.000':roundNumber((avgInflAssctBfrWqltTp / filteredData.length), 3),
inflAssctBfrWqltToc: filteredData.length==0 || avginflAssctBfrWqltToc===0?'0.0':roundNumber((avginflAssctBfrWqltToc / filteredData.length), 1),
inflAssctBfrWqltCod: filteredData.length==0 || avginflAssctBfrWqltCod===0?'(0.0)':"("+roundNumber((avginflAssctBfrWqltCod / filteredData.length), 1)+")",
inflAssctBfrWqltSs: filteredData.length==0 || avginflAssctBfrWqltSs===0?'0.0':roundNumber((avginflAssctBfrWqltSs / filteredData.length), 1),
efflWqltBod: filteredData.length == 0 || avgEfflWqltBod === 0 ? '0.0' : roundNumber((avgEfflWqltBod / filteredData.length), 1),
efflWqltToc: filteredData.length == 0 || avgefflWqltToc === 0 ? '0.0' : roundNumber((avgefflWqltToc / filteredData.length), 1),
efflWqltCod: filteredData.length == 0 || avgefflWqltCod === 0 ? "(0.0)" : "(" + roundNumber((avgefflWqltCod / filteredData.length), 1) + ")",
efflWqltSs: filteredData.length == 0 || avgEfflWqltSs === 0 ? '0.0' : roundNumber((avgEfflWqltSs / filteredData.length), 1),
efflWqltTn: filteredData.length == 0 || avgEfflWqltTn === 0 ? '0.000' : roundNumber((avgEfflWqltTn / filteredData.length), 3),
efflWqltTp: filteredData.length == 0 || avgEfflWqltTp === 0 ? '0.000' : roundNumber((avgEfflWqltTp / filteredData.length), 3),
inflAssctBfrWqltBod: filteredData.length == 0 || avginflAssctBfrWqltBod === 0 ? '0.0' : roundNumber((avginflAssctBfrWqltBod / filteredData.length), 1),
inflAssctBfrWqltTn: filteredData.length == 0 || avginflAssctBfrWqltTn === 0 ? '0.000' : roundNumber((avginflAssctBfrWqltTn / filteredData.length), 3),
inflAssctBfrWqltTp: filteredData.length == 0 || avgInflAssctBfrWqltTp === 0 ? '0.000' : roundNumber((avgInflAssctBfrWqltTp / filteredData.length), 3),
inflAssctBfrWqltToc: filteredData.length == 0 || avginflAssctBfrWqltToc === 0 ? '0.0' : roundNumber((avginflAssctBfrWqltToc / filteredData.length), 1),
inflAssctBfrWqltCod: filteredData.length == 0 || avginflAssctBfrWqltCod === 0 ? '(0.0)' : "(" + roundNumber((avginflAssctBfrWqltCod / filteredData.length), 1) + ")",
inflAssctBfrWqltSs: filteredData.length == 0 || avginflAssctBfrWqltSs === 0 ? '0.0' : roundNumber((avginflAssctBfrWqltSs / filteredData.length), 1),
bscFctCd: "",
bscFctNm: "",
lclgvrnmntNm: "",
@@ -260,25 +268,25 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
sggNm: "",
addr: "",
fctCpc: 0,
noProcessInflAmnt : roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0),
infoRnDay: filteredData.length==0 || avgInfoRnDay===0?'0.0':roundNumber(avgInfoRnDay / filteredData.length, 1),
tpInflWqltBod: filteredData.length==0 || avgTpInflWqltBod ===0 ?'0.0':roundNumber(avgTpInflWqltBod / tpInflWqltBodCnt, 1),
tpInflWqltTp: filteredData.length==0 || avgTpInflWqltTp === 0?'0.000':roundNumber(avgTpInflWqltTp / tpInflWqltTpCnt, 3)
noProcessInflAmnt: roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0),
infoRnDay: filteredData.length == 0 || avgInfoRnDay === 0 ? '0.0' : roundNumber(avgInfoRnDay / filteredData.length, 1),
tpInflWqltBod: filteredData.length == 0 || avgTpInflWqltBod === 0 ? '0.0' : roundNumber(avgTpInflWqltBod / tpInflWqltBodCnt, 1),
tpInflWqltTp: filteredData.length == 0 || avgTpInflWqltTp === 0 ? '0.000' : roundNumber(avgTpInflWqltTp / tpInflWqltTpCnt, 3)
},
{
msrDt : '최대',
efflWqltBod : Math.round(maxEfflWqltBod * 10) / 10?roundNumber(maxEfflWqltBod, 1):'0.0',
efflWqltToc : Math.round(maxefflWqltToc * 10) / 10?roundNumber(maxefflWqltToc, 1):'0.0',
efflWqltCod : Math.round(maxefflWqltCod * 10) / 10?"("+roundNumber(maxefflWqltCod, 1)+")":'(0.0)',
efflWqltSs : Math.round(maxEfflWqltSs * 10) / 10?roundNumber(maxEfflWqltSs, 1):'0.0',
efflWqltTn : Math.round(maxEfflWqltTn * 1000) / 1000?roundNumber(maxEfflWqltTn, 3):'0.000',
efflWqltTp : Math.round(maxEfflWqltTp * 1000) / 1000?roundNumber(maxEfflWqltTp, 3):'0.000',
inflAssctBfrWqltBod : Math.round(maxinflAssctBfrWqltBod * 10) / 10?roundNumber(maxinflAssctBfrWqltBod, 1):'0.0',
inflAssctBfrWqltTn : Math.round(maxinflAssctBfrWqltTn * 1000) / 1000?roundNumber(maxinflAssctBfrWqltTn, 3):'0.000',
inflAssctBfrWqltTp : Math.round(maxInflAssctBfrWqltTp * 1000) / 1000?roundNumber(maxInflAssctBfrWqltTp, 3):'0.000',
inflAssctBfrWqltToc : Math.round(maxinflAssctBfrWqltToc * 10) / 10?roundNumber(maxinflAssctBfrWqltToc, 1):'0.0',
inflAssctBfrWqltCod : Math.round(maxinflAssctBfrWqltCod * 10) / 10?"("+roundNumber(maxinflAssctBfrWqltCod, 1)+")":'(0.0)',
inflAssctBfrWqltSs : Math.round(maxinflAssctBfrWqltSs * 10) / 10?roundNumber(maxinflAssctBfrWqltSs, 1):'0.0',
msrDt: '최대',
efflWqltBod: Math.round(maxEfflWqltBod * 10) / 10 ? roundNumber(maxEfflWqltBod, 1) : '0.0',
efflWqltToc: Math.round(maxefflWqltToc * 10) / 10 ? roundNumber(maxefflWqltToc, 1) : '0.0',
efflWqltCod: Math.round(maxefflWqltCod * 10) / 10 ? "(" + roundNumber(maxefflWqltCod, 1) + ")" : '(0.0)',
efflWqltSs: Math.round(maxEfflWqltSs * 10) / 10 ? roundNumber(maxEfflWqltSs, 1) : '0.0',
efflWqltTn: Math.round(maxEfflWqltTn * 1000) / 1000 ? roundNumber(maxEfflWqltTn, 3) : '0.000',
efflWqltTp: Math.round(maxEfflWqltTp * 1000) / 1000 ? roundNumber(maxEfflWqltTp, 3) : '0.000',
inflAssctBfrWqltBod: Math.round(maxinflAssctBfrWqltBod * 10) / 10 ? roundNumber(maxinflAssctBfrWqltBod, 1) : '0.0',
inflAssctBfrWqltTn: Math.round(maxinflAssctBfrWqltTn * 1000) / 1000 ? roundNumber(maxinflAssctBfrWqltTn, 3) : '0.000',
inflAssctBfrWqltTp: Math.round(maxInflAssctBfrWqltTp * 1000) / 1000 ? roundNumber(maxInflAssctBfrWqltTp, 3) : '0.000',
inflAssctBfrWqltToc: Math.round(maxinflAssctBfrWqltToc * 10) / 10 ? roundNumber(maxinflAssctBfrWqltToc, 1) : '0.0',
inflAssctBfrWqltCod: Math.round(maxinflAssctBfrWqltCod * 10) / 10 ? "(" + roundNumber(maxinflAssctBfrWqltCod, 1) + ")" : '(0.0)',
inflAssctBfrWqltSs: Math.round(maxinflAssctBfrWqltSs * 10) / 10 ? roundNumber(maxinflAssctBfrWqltSs, 1) : '0.0',
bscFctCd: "",
bscFctNm: "",
lclgvrnmntNm: "",
@@ -286,25 +294,25 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
sggNm: "",
addr: "",
fctCpc: 0,
noProcessInflAmnt : roundNumber(maxNoProcessInflAmnt, 0),
infoRnDay: Math.round(maxInfoRnDay * 10) / 10?roundNumber(maxInfoRnDay, 1):'0.0',
tpInflWqltBod: Math.round(maxTpInflWqltBod * 10) / 10?roundNumber(maxTpInflWqltBod, 1):'0.0',
tpInflWqltTp: Math.round(maxTpInflWqltTp * 1000) / 1000?roundNumber(maxTpInflWqltTp, 3):'0.000'
noProcessInflAmnt: roundNumber(maxNoProcessInflAmnt, 0),
infoRnDay: Math.round(maxInfoRnDay * 10) / 10 ? roundNumber(maxInfoRnDay, 1) : '0.0',
tpInflWqltBod: Math.round(maxTpInflWqltBod * 10) / 10 ? roundNumber(maxTpInflWqltBod, 1) : '0.0',
tpInflWqltTp: Math.round(maxTpInflWqltTp * 1000) / 1000 ? roundNumber(maxTpInflWqltTp, 3) : '0.000'
},
{
msrDt : '최소',
efflWqltBod : Math.round(minEfflWqltBod * 10) / 10?roundNumber(minEfflWqltBod, 1) : '0.0',
efflWqltToc : Math.round(minefflWqltToc * 10) / 10?roundNumber(minefflWqltToc, 1) : '0.0',
efflWqltCod : Math.round(minefflWqltCod * 10) / 10?"("+roundNumber(minefflWqltCod, 1)+")" : '(0.0)',
efflWqltSs : Math.round(minEfflWqltSs * 10) / 10?roundNumber(minEfflWqltSs, 1) : '0.0',
efflWqltTn : Math.round(minEfflWqltTn * 1000) / 1000?roundNumber(minEfflWqltTn, 3) : '0.000',
efflWqltTp : Math.round(minEfflWqltTp * 1000) / 1000?roundNumber(minEfflWqltTp, 3) : '0.000',
inflAssctBfrWqltBod : Math.round(mininflAssctBfrWqltBod * 10) / 10?roundNumber(mininflAssctBfrWqltBod, 1) : '0.0',
inflAssctBfrWqltTn : Math.round(mininflAssctBfrWqltTn * 1000) / 1000?roundNumber(mininflAssctBfrWqltTn, 3) : '0.000',
inflAssctBfrWqltTp : Math.round(minInflAssctBfrWqltTp * 1000) / 1000?roundNumber(minInflAssctBfrWqltTp, 3) : '0.000',
inflAssctBfrWqltToc : Math.round(mininflAssctBfrWqltToc * 10) / 10?roundNumber(mininflAssctBfrWqltToc, 1) : '0.0',
inflAssctBfrWqltCod : Math.round(mininflAssctBfrWqltCod * 10) / 10?"("+roundNumber(mininflAssctBfrWqltCod, 1)+")" : '(0.0)',
inflAssctBfrWqltSs : Math.round(mininflAssctBfrWqltSs * 10) / 10?roundNumber(mininflAssctBfrWqltSs, 1) : '0.0',
msrDt: '최소',
efflWqltBod: Math.round(minEfflWqltBod * 10) / 10 ? roundNumber(minEfflWqltBod, 1) : '0.0',
efflWqltToc: Math.round(minefflWqltToc * 10) / 10 ? roundNumber(minefflWqltToc, 1) : '0.0',
efflWqltCod: Math.round(minefflWqltCod * 10) / 10 ? "(" + roundNumber(minefflWqltCod, 1) + ")" : '(0.0)',
efflWqltSs: Math.round(minEfflWqltSs * 10) / 10 ? roundNumber(minEfflWqltSs, 1) : '0.0',
efflWqltTn: Math.round(minEfflWqltTn * 1000) / 1000 ? roundNumber(minEfflWqltTn, 3) : '0.000',
efflWqltTp: Math.round(minEfflWqltTp * 1000) / 1000 ? roundNumber(minEfflWqltTp, 3) : '0.000',
inflAssctBfrWqltBod: Math.round(mininflAssctBfrWqltBod * 10) / 10 ? roundNumber(mininflAssctBfrWqltBod, 1) : '0.0',
inflAssctBfrWqltTn: Math.round(mininflAssctBfrWqltTn * 1000) / 1000 ? roundNumber(mininflAssctBfrWqltTn, 3) : '0.000',
inflAssctBfrWqltTp: Math.round(minInflAssctBfrWqltTp * 1000) / 1000 ? roundNumber(minInflAssctBfrWqltTp, 3) : '0.000',
inflAssctBfrWqltToc: Math.round(mininflAssctBfrWqltToc * 10) / 10 ? roundNumber(mininflAssctBfrWqltToc, 1) : '0.0',
inflAssctBfrWqltCod: Math.round(mininflAssctBfrWqltCod * 10) / 10 ? "(" + roundNumber(mininflAssctBfrWqltCod, 1) + ")" : '(0.0)',
inflAssctBfrWqltSs: Math.round(mininflAssctBfrWqltSs * 10) / 10 ? roundNumber(mininflAssctBfrWqltSs, 1) : '0.0',
bscFctCd: "",
bscFctNm: "",
lclgvrnmntNm: "",
@@ -312,10 +320,10 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
sggNm: "",
addr: "",
fctCpc: 0,
noProcessInflAmnt : roundNumber(minNoProcessInflAmnt, 0),
infoRnDay: Math.round(minInfoRnDay * 10) / 10?'0.0':roundNumber(minInfoRnDay, 1),
tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999?roundNumber(minTpInflWqltBod, 1):'0.0',
tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999?roundNumber(minTpInflWqltTp, 3):'0.000'
noProcessInflAmnt: roundNumber(minNoProcessInflAmnt, 0),
infoRnDay: Math.round(minInfoRnDay * 10) / 10 ? roundNumber(minInfoRnDay, 1) : '0.0',
tpInflWqltBod: Math.round(minTpInflWqltBod * 10) / 10 && minTpInflWqltBod != 99999999 ? roundNumber(minTpInflWqltBod, 1) : '0.0',
tpInflWqltTp: Math.round(minTpInflWqltTp * 1000) / 1000 && minTpInflWqltTp != 99999999 ? roundNumber(minTpInflWqltTp, 3) : '0.000'
},
...filteredData
];
@@ -323,20 +331,6 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
return newFilteredData;
}
// 날짜 필터링 관련 상태
const [copyYearList, setCopyYearList] = useState<FacilityWaterQltyProps[]>([]);
const [chongInWaterQltyYearList, setChongInWaterQltyYearList] = useState<FacilityWaterQltyProps[]>([]);
useEffect(() => {
searchFacilityWaterQltyListHist(searchYear, facilityCd);
}, [searchYear, facilityCd, searchFacilityWaterQltyListHist]);
useEffect(() => {
const filteredYearData = setFilterAfterData(facilityWaterQltyYearList);
setCopyYearList(filteredYearData as FacilityWaterQltyProps[]);
setChongInWaterQltyYearList(filteredYearData as FacilityWaterQltyProps[]);
}, [facilityWaterQltyYearList]);
const yesterDay = new Date();
yesterDay.setDate(yesterDay.getDate() - 1);
const yesterDayStr = yesterDay.toISOString().split('T')[0];
@@ -350,14 +344,14 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
const filterData = useCallback((returnType: ReturnType<FacilityWaterQltyProps>) => {
const filteredData = setFilterAfterData(returnType.filteredList);
setCopyYearList(filteredData as FacilityWaterQltyProps[]);
setCopyYearList(filteredData as FacilityWaterQltyProps[]); // 처리시설/총인설비 수질현황
}, []);
const excelDownload = () => {
if(tabName === 'tab_num1'){
if (tabName === 'tab_num1') { //처리시설 수질현황
const excelDownList: modalExcelType[] = [];
if(copyYearList.length > 0){
if (copyYearList.length > 0) {
copyYearList.forEach((item) => {
excelDownList.push({
날짜: item.msrDt,
@@ -371,27 +365,30 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
"유출SS(mg/L)": CommaToNumber(item.efflWqltSs),
"유출TN(mg/L)": CommaToNumber(item.efflWqltTn),
"유출TP(mg/L)": CommaToNumber(item.efflWqltTp),
"강우량(mm/일)": CommaToNumber(item.infoRnDay?item.infoRnDay.toString():"0.0"),
"강우량(mm/일)": CommaToNumber(item.infoRnDay ? item.infoRnDay.toString() : "0.0"),
});
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcelFormat(
{ data: JSON.parse(JSON.stringify(excelDownList))
, fileName: searchYear+'년 '+fcltyName + ' 수질현황'
{
data: JSON.parse(JSON.stringify(excelDownList))
, fileName: searchYear + '년 ' + fcltyName + ' 수질현황'
, sheetNameArray: [fcltyName + ' 수질현황']
, headerRange: 'A1:L1'
, decimalArray1: [1,2,3,6,7,8,11]
, decimalArray3: [4,5,9,10]
, decimalArray1: [1, 2, 3, 6, 7, 8, 11]
, decimalArray3: [4, 5, 9, 10]
});
} else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) {
alert('다운받을 데이터가 없습니다.');
}
prevExcelListRef.current = excelDownList;
}else{
} else { // 총인설비 수질현황
const excelDownList: modalChoinginExcelType[] = [];
if(chongInWaterQltyYearList.length > 0){
chongInWaterQltyYearList.forEach((item) => {
// if (chongInWaterQltyYearList.length > 0) {
// chongInWaterQltyYearList.forEach((item) => {
if (copyYearList.length > 0) {
copyYearList.forEach((item) => {
excelDownList.push({
날짜: item.msrDt,
"유입BOD(mg/L)": CommaToNumber(item.tpInflWqltBod),
@@ -403,12 +400,13 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
}
if (excelDownList && excelDownList.length > 0) {
downloadExcelFormat(
{ data: JSON.parse(JSON.stringify(excelDownList))
, fileName: searchYear+'년 '+fcltyName + ' 총인설비수질현황'
{
data: JSON.parse(JSON.stringify(excelDownList))
, fileName: searchYear + '년 ' + fcltyName + ' 총인설비수질현황'
, sheetNameArray: [fcltyName + ' 총인설비수질현황']
, headerRange: 'A1:E1'
, decimalArray1: [1,3]
, decimalArray3: [2,4]
, decimalArray1: [1, 3]
, decimalArray3: [2, 4]
});
} else if (prevChoinginExcelListRef.current && prevChoinginExcelListRef.current.length > 0) {
alert('다운받을 데이터가 없습니다.');
@@ -424,168 +422,125 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
return (
<>
<UITab tabList={tabList1} defaultValue="tab_num1" onValueChange={(value) => setTabName(value)}>
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownload}>
<Button className={btnClass} style={{ float: 'right' }} color="green" onClick={excelDownload}>
{"엑셀다운로드"}
</Button>
{/* 처리시설 수질현황 */}
<TabsContent value="tab_num1">
<UITab tabList={tabList2} defaultValue="tab_term_year">
<TabsContent value="tab_term_year">
<TabsContent value="tab_term_year">{/* 연간 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={facilityWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName={"tab_term_year"}
searchYear={searchYear}
ref={ref}
queryClick={filterData}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_year"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[350px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear)<COD_YEAR?upHeadListModalYearCod:upHeadListModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[310px]"
boldArray={[0,1,2]}
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear) < COD_YEAR ? upHeadListModalYearCod : upHeadListModalYear}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[310px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalYear} layoutNum={3} />
</UiTable>
</div>
<div className="card-header">
<div className="card-header border-t mt-1">
<h3 className="text-2xl font-medium text-label">수질 TMS</h3>
{/*<h3 className="text-2xl font-medium text-label text-right">({msrmtDate?msrmtDate.substring(0,4)+'-'+msrmtDate.substring(4,6)+'-'+msrmtDate.substring(6,8):yesterDayStr})</h3> */}
<h3 className="text-2xl font-medium text-label text-right">({msrmtDate ? msrmtDate.substring(0, 4) + '-' + msrmtDate.substring(4, 6) + '-' + msrmtDate.substring(6, 8) : yesterDayStr})</h3>
</div>
<div className="overflow-y-auto h-[250px]">
<UiTable
headName={undefined}
tableData={tmsList}
headlist={upHeadListModalTms}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
boldArray={[0,1,2]}
<UiTable
headName={undefined}
tableData={tmsList}
headlist={upHeadListModalTms}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalTms} layoutNum={4} />
</UiTable>
{msrmtDate != yesterDayStr?.replaceAll('-','') ? (
<UnderComment commentArray={["전날 데이터 결측으로 인해 가장 최근 데이터 표출함"]} divHeight="0"/>
{msrmtDate != yesterDayStr?.replaceAll('-', '') ? (
<UnderComment commentArray={["전날 데이터 결측으로 인해 가장 최근 데이터 표출함"]} divHeight="0" />
) : null}
</div>
</TabsContent>
<TabsContent value="tab_term_summer">
<TabsContent value="tab_term_summer">{/* 하절기 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={facilityWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_summer"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_summer"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[500px]">
<UiTable
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear)<COD_YEAR?upHeadListModalYearCod:upHeadListModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => { } }
className="h-[500px]"
boldArray={[0,1,2]}
headlist={Number(searchYear) < COD_YEAR ? upHeadListModalYearCod : upHeadListModalYear}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalYear} layoutNum={3} />
</UiTable>
</div>
</TabsContent>
<TabsContent value="tab_term_winter">
<TabsContent value="tab_term_winter">{/* 동절기 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={facilityWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_winter"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_winter"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[500px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear)<COD_YEAR?upHeadListModalYearCod:upHeadListModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[500px]"
boldArray={[0,1,2]}
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear) < COD_YEAR ? upHeadListModalYearCod : upHeadListModalYear}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalYear} layoutNum={3} />
</UiTable>
</div>
</TabsContent>
<TabsContent value="tab_term_chuncheon">
<TabsContent value="tab_term_chuncheon">{/* 청천시 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={facilityWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_chuncheon"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_chuncheon"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[500px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear)<COD_YEAR?upHeadListModalYearCod:upHeadListModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[500px]"
boldArray={[0,1,2]}
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear) < COD_YEAR ? upHeadListModalYearCod : upHeadListModalYear}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalYear} layoutNum={3} />
</UiTable>
</div>
<UnderComment commentArray={commentArrayChungchun} divHeight="10"/>
<UnderComment commentArray={commentArrayChungchun} divHeight="10" />
</TabsContent>
<TabsContent value="tab_term_rain">
<TabsContent value="tab_term_rain">{/* 강우시 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={facilityWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_rain"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_rain"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[500px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear)<COD_YEAR?upHeadListModalYearCod:upHeadListModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[500px]"
boldArray={[0,1,2]}
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={Number(searchYear) < COD_YEAR ? upHeadListModalYearCod : upHeadListModalYear}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalYear} layoutNum={3} />
</UiTable>
</div>
<UnderComment commentArray={commentArrayRain} divHeight="10"/>
<UnderComment commentArray={commentArrayRain} divHeight="10" />
</TabsContent>
</UITab>
</TabsContent>
@@ -593,81 +548,57 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
{/* 총인설비 수질현황 */}
<TabsContent value="tab_num2" >
<UITab tabList={tabList3} defaultValue="tab_term_year_chongin">
<TabsContent value="tab_term_year_chongin">
<TabsContent value="tab_term_year_chongin">{/* 연간 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={chongInWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_year"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_year"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[550px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={upHeadListModalChongIn}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[500px]"
boldArray={[0,1,2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalChongIn} layoutNum={5} />
</UiTable>
</div>
</TabsContent>
<TabsContent value="tab_term_summer_chongin">
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={chongInWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_summer"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
/>
<div className="overflow-y-auto h-[550px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={upHeadListModalChongIn}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[500px]"
boldArray={[0,1,2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalChongIn} layoutNum={5} />
</UiTable>
</div>
</TabsContent>
<TabsContent value="tab_term_winter_chongin">
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={chongInWaterQltyYearList}
fcltyCd={facilityCd}
fcltyName={fcltyName}
tabName="tab_term_winter"
searchYear={searchYear}
ref={ref}
queryClick={filterData}
/>
<div className="overflow-y-auto h-[550px]">
<UiTable
headName={undefined}
tableData={copyYearList}
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={upHeadListModalChongIn}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[500px]"
boldArray={[0,1,2]}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalChongIn} layoutNum={5} />
</UiTable>
</div>
</TabsContent>
<TabsContent value="tab_term_summer_chongin">{/* 하절기 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={chongInWaterQltyYearList}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_summer"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[550px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={upHeadListModalChongIn}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalChongIn} layoutNum={5} />
</UiTable>
</div>
</TabsContent>
<TabsContent value="tab_term_winter_chongin">{/* 동절기 */}
<FacilityTermModalHeader<FacilityWaterQltyProps>
searchList={chongInWaterQltyYearList}
fcltyCd={facilityCd} fcltyName={fcltyName} tabName="tab_term_winter"
searchYear={searchYear} ref={ref} queryClick={filterData}
/>
<div className="overflow-y-auto h-[550px]">
<UiTable
headName={undefined}
tableData={copyYearList}
headlist={upHeadListModalChongIn}
pageSize={0} total={0} cellClick={undefined}
onPageChange={() => { }} className="h-[500px]" boldArray={[0, 1, 2]}
>
<HeadMakeColSpan upHeadList={upHeadListModalChongIn} layoutNum={5} />
</UiTable>
@@ -678,4 +609,4 @@ export default function WaterQualityModal({fcltyName='', facilityCd='', searchYe
</UITab>
</>
);
}
}
@@ -23,7 +23,7 @@ export default function ProcessFacilitySearch() {
} = useFoStore((state) => state) || { FacilityWaterQltyList: { facilityWaterQltyList: [], facilityWaterQltyCount: 0 } };
const {
isInit,
isInit,
selectUpdownData,
selectOperationData,
selectSidoData,
@@ -66,26 +66,26 @@ export default function ProcessFacilitySearch() {
const [fcltyCd, setFcltyCd] = useState<string>("");
const [modalYear, setModalYear] = useState<string>("");
const searchFcltyQltyList = useCallback(({ partValue, regionValue, unitWaterShedValue, middleRegionValue, envPartValue, sidoValue, sigunValue }: ReturnType, pageNo: number, pageCnt:number=20) => {
const searchFcltyQltyList = useCallback(({ partValue, regionValue, unitWaterShedValue, middleRegionValue, envPartValue, sidoValue, sigunValue }: ReturnType, pageNo: number, pageCnt: number = 20) => {
let nameCd, partStr;
switch (partValue) {
case 'R':
if (regionValue !== '0') {
if(unitWaterShedValue==='0') nameCd = regionValue;
else if (middleRegionValue==='0') nameCd = unitWaterShedValue;
if (unitWaterShedValue === '0') nameCd = regionValue;
else if (middleRegionValue === '0') nameCd = unitWaterShedValue;
else nameCd = middleRegionValue;
}
partStr = partValue
break;
default:
if(sidoValue !== '0') nameCd = ref.current.sidoValue!="0"?ref.current.sidoValue:sidoValue;
if(sigunValue !== '0') nameCd = sigunValue;
partStr = envPartValue !== '0' ? envPartValue:partValue;
break;
if (sidoValue !== '0') nameCd = ref.current.sidoValue != "0" ? ref.current.sidoValue : sidoValue;
if (sigunValue !== '0') nameCd = sigunValue;
partStr = envPartValue !== '0' ? envPartValue : partValue;
break;
}
if(partStr ==='G'){
if (partStr === 'G') {
searchFacilityWaterQltyList(pageNo, pageCnt, searchYearValue);
}else{
} else {
searchFacilityWaterQltyList(pageNo, pageCnt, searchYearValue, partStr, nameCd || '0', fcltCpct, operationValue, fcltyName.trim() !== "" || fcltyName.trim() !== null ? fcltyName : undefined);
}
}, [operationValue, fcltyName, searchFacilityWaterQltyList, searchYearValue, fcltCpct]);
@@ -138,34 +138,34 @@ export default function ProcessFacilitySearch() {
useEffect(() => {
if (!isInit) {
if(!initTrigger){
if (!initTrigger) {
initializeCommonData();
searchFcltyQltyList(ref.current, 1, 10);
setInitTrigger(true);
setInitTrigger(true);
}
}
}, [isInit, initializeCommonData, searchFacilityWaterQltyList, searchFcltyQltyList, initTrigger]);
useEffect(() => {
if(!excelTrigger) return;
if (!excelTrigger) return;
if (excelList && excelList.length > 0) {
downloadExcelFormat(
{
data: excelList as unknown as JSON[],
fileName: '시설별 수질현황',
sheetNameArray: ['시설별 수질현황'],
data: excelList as unknown as JSON[],
fileName: '시설별 수질현황',
sheetNameArray: ['시설별 수질현황'],
headerRange: 'A1:T1',
decimalArray1:[10,11,12,15,16,17],
decimalArray3:[13,14,18,19]
decimalArray1: [10, 11, 12, 15, 16, 17],
decimalArray3: [13, 14, 18, 19]
}
);
}
}, [excelList, excelTrigger]);
const chkVal = useCallback((returntype:ReturnType) => {
const chkVal = useCallback((returntype: ReturnType) => {
// setWidthSize(returntype.partValue=='A' ?"w-[120%]":"w-[130%]")
setUpheadList(returntype.partValue == 'R' ? upHeadList2 : returntype.partValue == 'G'?upHeadList3:upHeadList1);
setUpheadList(returntype.partValue == 'R' ? upHeadList2 : returntype.partValue == 'G' ? upHeadList3 : upHeadList1);
setResetPage(true);
}, [upHeadList1, upHeadList2, upHeadList3]);
@@ -173,7 +173,7 @@ export default function ProcessFacilitySearch() {
setExcelTrigger(true);
searchFcltyQltyList(ref.current, 1, 10000);
}, [searchFcltyQltyList]);
const handlePageChange = useCallback((page: number) => {
setResetPage(false);
searchFcltyQltyList(ref.current, page, 10);
@@ -202,7 +202,7 @@ export default function ProcessFacilitySearch() {
queryClick={chkVal}
excelClick={excelDownload}
initClick={resetVal}
ref={ref} isAdmin={false} initSidoValue={"11"}/>
ref={ref} isAdmin={false} initSidoValue={"11"} />
<ListDiv>
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden">
@@ -215,7 +215,7 @@ export default function ProcessFacilitySearch() {
{selectedRow !== null && (
<UiModal
body={<WaterQualityModal fcltyName={fcltyNm} facilityCd={fcltyCd} searchYear={modalYear}></WaterQualityModal>}
bodyClass="sm:max-w-[90vw] w-[1300px] h-[920px]"
bodyClass="sm:max-w-[90vw] w-[1300px] h-[100dvh] max-h-[930px] overflow-y-auto"
open={selectedRow !== null}
onOpenChange={(open) => !open && closeModal()}
noHeaderYn="Y"
@@ -8,6 +8,7 @@
import FacilityTermModalHeader from "@/app/components/common/FacilityTermModalHeader";
import { useFoStore } from "@/app/store";
import type { FlowRateModalInterface, modalExcelType } from "@/app/store/flowRate";
import { dataFormSetting } from "@/app/store/flowRate";
import { downloadExcel, UITab, UiTable } from "@common/business_components/ui";
import { Button, TabsContent } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
@@ -34,11 +35,8 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
const [copyYearList, setCopyYearList] = useState<FlowRateModalInterface[]>([]);
const [isLoading, setIsLoading] = useState(true);
const prevExcelListRef = useRef<modalExcelType[] | null>(null);
const {
modalFlowRateListYear,
upHeadListFlowRateModalYear,
} = FlowRateModal;
const { modalFlowRateListYear, upHeadListFlowRateModalYear, } = FlowRateModal;
const ref = useRef<ReturnType<FlowRateModalInterface>>({
startDate: new Date(),
endDate: new Date(),
@@ -52,11 +50,11 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
const filteredData = setFilterAfterData(returnType.filteredList as FlowRateModalInterface[]);
setCopyYearList(filteredData);
}, []);
// 필터링 된 후 최대, 최소, 평균 값 계산
const setFilterAfterData = (filteredData: FlowRateModalInterface[]) => {
if (!filteredData || filteredData.length === 0) return [];
// 쉼표가 포함된 문자열을 숫자로 변환하는 함수
const parseNumber = (value: string | number | null | undefined): number => {
if (value === null || value === undefined || value === '') return 0;
@@ -79,7 +77,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
let minreturnAmnt = parseNumber(filteredData[0]?.returnAmnt);
let minefflAmnt = parseNumber(filteredData[0]?.efflAmnt);
let mininfoRnDay = parseNumber(filteredData[0]?.infoRnDay && filteredData[0]?.infoRnDay.toString().trim() !== 'x' ? filteredData[0]?.infoRnDay.toString().trim() : 0);
let minNoProcessInflAmnt = 99999999;
let minNoProcessInflAmnt = 99999999; // 미처리하수 추정량
let avgtotInflAmnt = 0;
let avginflAmnt = 0;
@@ -89,7 +87,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
let avginfoRnDay = 0;
let avgNoProcessInflAmnt = 0;
let noProcessInflAmntCnt = 0;
filteredData.forEach((item: FlowRateModalInterface) => {
const totInflAmnt = parseNumber(item.totInflAmnt);
const inflAmnt = parseNumber(item.inflAmnt);
@@ -119,24 +117,30 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
avgefflAmnt += efflAmnt;
avginfoRnDay += infoRnDay;
if(item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined){
const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',',''));
if (item.noProcessInflAmnt && item.noProcessInflAmnt.toString().trim() != '' && item.noProcessInflAmnt != undefined) {
const noProcessInflAmnt = Number(item.noProcessInflAmnt.toString().replaceAll(',', ''));
avgNoProcessInflAmnt += noProcessInflAmnt;
maxNoProcessInflAmnt = Math.max(maxNoProcessInflAmnt, noProcessInflAmnt);
minNoProcessInflAmnt = Math.min(minNoProcessInflAmnt, noProcessInflAmnt);
noProcessInflAmntCnt +=1;
noProcessInflAmntCnt += 1;
}
});
const formattedData = filteredData.map((item: FlowRateModalInterface) => {
const newItem = { ...item };
dataFormSetting(newItem);
return newItem;
});
const newFilteredData = [
{
msrDt: '평균',
totInflAmnt: avgtotInflAmnt && avgtotInflAmnt!=0 ? roundUp((avgtotInflAmnt / filteredData.length), 0) : 0,
inflAmnt: avginflAmnt && avginflAmnt!=0 ? roundUp((avginflAmnt / filteredData.length), 0) : 0,
sumFlow: avgsumFlow && avgsumFlow!=0 ? roundUp((avgsumFlow / filteredData.length), 0) : 0,
returnAmnt: avgreturnAmnt && avgreturnAmnt!=0 ? roundUp((avgreturnAmnt / filteredData.length), 0) : 0,
efflAmnt: avgefflAmnt && avgefflAmnt!=0 ? roundUp((avgefflAmnt / filteredData.length), 0) : 0,
noProcessInflAmnt : roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0),
totInflAmnt: avgtotInflAmnt && avgtotInflAmnt != 0 ? roundUp((avgtotInflAmnt / filteredData.length), 0) : 0,
inflAmnt: avginflAmnt && avginflAmnt != 0 ? roundUp((avginflAmnt / filteredData.length), 0) : 0,
sumFlow: avgsumFlow && avgsumFlow != 0 ? roundUp((avgsumFlow / filteredData.length), 0) : 0,
returnAmnt: avgreturnAmnt && avgreturnAmnt != 0 ? roundUp((avgreturnAmnt / filteredData.length), 0) : 0,
efflAmnt: avgefflAmnt && avgefflAmnt != 0 ? roundUp((avgefflAmnt / filteredData.length), 0) : 0,
noProcessInflAmnt: roundNumber(avgNoProcessInflAmnt / noProcessInflAmntCnt, 0),
infoRnDay: avginfoRnDay > 0 ? roundUp((avginfoRnDay / filteredData.length), 1) : '0.0',
rainEffectDay: 0,
},
@@ -147,7 +151,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
sumFlow: roundUp(maxsumFlow, 0),
returnAmnt: roundUp(maxreturnAmnt, 0),
efflAmnt: roundUp(maxefflAmnt, 0),
noProcessInflAmnt : roundNumber(maxNoProcessInflAmnt, 0),
noProcessInflAmnt: roundNumber(maxNoProcessInflAmnt, 0),
infoRnDay: maxinfoRnDay > 0 ? roundUp(maxinfoRnDay, 1) : '0.0',
rainEffectDay: 0,
},
@@ -158,11 +162,11 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
sumFlow: roundUp(minsumFlow, 0),
returnAmnt: roundUp(minreturnAmnt, 0),
efflAmnt: roundUp(minefflAmnt, 0),
noProcessInflAmnt : roundNumber(minNoProcessInflAmnt, 0),
noProcessInflAmnt: roundNumber(minNoProcessInflAmnt, 0),
infoRnDay: mininfoRnDay > 0 ? roundUp(mininfoRnDay, 1) : '0.0',
rainEffectDay: 0,
},
...filteredData
...formattedData
];
return newFilteredData;
}
@@ -185,7 +189,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
const excelDownload = () => {
const excelDownList: modalExcelType[] = [];
if(copyYearList.length > 0){
if (copyYearList.length > 0) {
copyYearList.forEach((item) => {
excelDownList.push({
"날짜": item.msrDt,
@@ -200,7 +204,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 유량현황', sheetNameArray: [props.fcltyName + ' 유량현황'], headerRange: 'A1:H1' });
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear + '년 ' + props.fcltyName + ' 유량현황', sheetNameArray: [props.fcltyName + ' 유량현황'], headerRange: 'A1:H1' });
} else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) {
alert('다운받을 데이터가 없습니다.');
}
@@ -210,10 +214,10 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
return (
<>
<UITab tabList={tabList} defaultValue="tab_term_year">
<Button className={btnClass} style={{float: 'right'}} color="green" onClick={excelDownload}>
<Button className={btnClass} style={{ float: 'right' }} color="green" onClick={excelDownload}>
{"엑셀다운로드"}
</Button>
<TabsContent value="tab_term_year">
<TabsContent value="tab_term_year"> {/* 연간 */}
<FacilityTermModalHeader<FlowRateModalInterface>
searchList={modalFlowRateListYear}
fcltyCd={props.facilityCd}
@@ -224,23 +228,23 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
queryClick={filterData}
/>
<div className="h-[370px] overflow-y-auto overflow-x-hidden">
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[370px]"
boldArray={[0,1,2]}
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => { }}
className="h-[370px]"
boldArray={[0, 1, 2]}
/>
</div>
<div className="mt-20">
<UnderComment commentArray={[commentArray]} />
</div>
</TabsContent>
<TabsContent value="tab_term_summer">
<TabsContent value="tab_term_summer"> {/* 하절기 */}
<FacilityTermModalHeader<FlowRateModalInterface>
searchList={modalFlowRateListYear}
fcltyCd={props.facilityCd}
@@ -251,23 +255,23 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
queryClick={filterData}
/>
<div className="h-[370px] overflow-y-auto overflow-x-hidden">
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[370px]"
boldArray={[0,1,2]}
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => { }}
className="h-[370px]"
boldArray={[0, 1, 2]}
/>
</div>
<div className="mt-20">
<UnderComment commentArray={[commentArray]} />
</div>
</TabsContent>
<TabsContent value="tab_term_winter">
<TabsContent value="tab_term_winter"> {/* 동절기 */}
<FacilityTermModalHeader<FlowRateModalInterface>
searchList={modalFlowRateListYear}
fcltyCd={props.facilityCd}
@@ -278,23 +282,23 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
queryClick={filterData}
/>
<div className="h-[370px] overflow-y-auto overflow-x-hidden">
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[370px]"
boldArray={[0,1,2]}
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => { }}
className="h-[370px]"
boldArray={[0, 1, 2]}
/>
</div>
<div className="mt-20">
<UnderComment commentArray={[commentArray]} />
</div>
</TabsContent>
<TabsContent value="tab_term_chuncheon">
<TabsContent value="tab_term_chuncheon"> {/* 청천시 */}
<FacilityTermModalHeader<FlowRateModalInterface>
searchList={modalFlowRateListYear}
fcltyCd={props.facilityCd}
@@ -305,23 +309,23 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
queryClick={filterData}
/>
<div className="h-[370px] overflow-y-auto overflow-x-hidden">
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => {}}
className="h-[370px]"
boldArray={[0,1,2]}
<UiTable
headName="유량현황"
tableData={copyYearList}
headlist={upHeadListFlowRateModalYear}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={() => { }}
className="h-[370px]"
boldArray={[0, 1, 2]}
/>
</div>
<div className="mt-20">
<UnderComment commentArray={[commentArray]} />
</div>
</TabsContent>
<TabsContent value="tab_term_rain">
<TabsContent value="tab_term_rain"> {/* 강우시 */}
<FacilityTermModalHeader<FlowRateModalInterface>
searchList={modalFlowRateListYear}
fcltyCd={props.facilityCd}
@@ -332,10 +336,11 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
queryClick={filterData}
/>
<div className="h-[370px] overflow-y-auto overflow-x-hidden">
<UiTable headName="유량현황" tableData={copyYearList} headlist={upHeadListFlowRateModalYear} pageSize={0} total={0} cellClick={undefined} onPageChange={() => {}} className="h-[370px]" boldArray={[0,1,2]}/>
<UiTable headName="유량현황" tableData={copyYearList} headlist={upHeadListFlowRateModalYear} pageSize={0} total={0}
cellClick={undefined} onPageChange={() => { }} className="h-[370px]" boldArray={[0, 1, 2]} />
</div>
<div className="mt-20">
<UnderComment commentArray={["미처리하수 추정량 산식 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]/강우시 일별유입BOD)","강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날"]} />
<UnderComment commentArray={["미처리하수 추정량 산식 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]/강우시 일별유입BOD)", "강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날"]} />
</div>
</TabsContent>
</UITab>
@@ -216,7 +216,7 @@ export default function ProcessFacilitySearch() {
{selectedRow !== null && (
<UiModal
body={<FlowRateModal fcltyName={fcltyNm} facilityCd={fcltyCd} searchYear={searchYearValue}></FlowRateModal>}
bodyClass="sm:max-w-[90vw] w-[1250px] h-[780px]"
bodyClass="sm:max-w-[90vw] w-[1250px] h-[100dvh] max-h-[780px]"
open={selectedRow !== null}
onOpenChange={(open: boolean) => !open && closeModal()}
/>
@@ -6,6 +6,7 @@
"use client"
import { useFoStore } from "@/app/store";
import { useShallow } from 'zustand/react/shallow';
import { ContentsDiv, downloadExcel, MainDiv, SearchBaseForm, SelectBox, Title, UiModal, UiTable, type ReturnType } from "@common/business_components";
import ListDiv from "@common/business_components/ui/list_div";
import { useCallback, useEffect, useRef, useState } from "react";
@@ -13,19 +14,22 @@ import ProcessFacilityInfoModal from "./modal/page";
import LoadingOverlay from "@common/business_components/ui/loadingBar";
export default function ProcessArea() {
const {Common,
const {
Common,
ProcessArea,
ProcessAreaSearch,
initializeCommonData,
searchProcessAreaList
} = useFoStore((state) => state) || {
Common: { isInit: false, selectSidoData: [], selectSigunData: [], selectRegionData: [], selectUnitWaterShedData: [], selectMiddleRegionData: [], selectEnvPartData: [], selectSearchYear: [{ val: "0" }], btnClass: "" },
ProcessArea: { processAreaList: [], processAreaCount: 0, excelList: [], upHeadList1: [] },
ProcessAreaSearch: { processFacilityLabelArray: [] },
initializeCommonData: () => {},
searchProcessAreaList: () => {}
};
} = useFoStore(
useShallow((state) => ({ // 다른 무관한 상태가 변경되어도 이 컴포넌트는 불필요하게 다시 렌더링 되지 않음.
Common: state.Common,
ProcessArea: state.ProcessArea,
ProcessAreaSearch: state.ProcessAreaSearch,
initializeCommonData: state.initializeCommonData,
searchProcessAreaList: state.searchProcessAreaList,
}))
);
const {
isInit,
selectSidoData,
@@ -37,7 +41,7 @@ export default function ProcessArea() {
selectSearchYear,
btnClass,
} = Common;
const {
processFacilityLabelArray,
} = ProcessAreaSearch;
@@ -54,11 +58,11 @@ export default function ProcessArea() {
// 그리드 관련
const searchInputRef = useRef<HTMLDivElement & HTMLInputElement>(null);
// 모달 상태 추가
// 모달 상태 추가
const [selectedRow, setSelectedRow] = useState<number | null>(null);
const [fcltyNm, setFcltyNm] = useState<string>("");
const [fcltyCd, setFcltyCd] = useState<string>("");
const [resetPage, setResetPage] = useState<boolean>(false);
const [searchYearValue, setSearchYearValue] = useState<string>(selectSearchYear[0]?.val || "0");
@@ -74,7 +78,7 @@ export default function ProcessArea() {
sigunText: '',
});
const searchProcessArea = useCallback(({ sidoText, sigunText}: ReturnType, pageNo: number, pageCnt:number=20) => {
const searchProcessArea = useCallback(({ sidoText, sigunText }: ReturnType, pageNo: number, pageCnt: number = 20) => {
searchProcessAreaList(pageNo, pageCnt, sidoText, sigunText, searchYearValue);
}, [searchProcessAreaList, searchYearValue]);
@@ -118,11 +122,11 @@ export default function ProcessArea() {
useEffect(() => {
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
fileName: '처리구역정보',
sheetNameArray: ['처리구역정보'],
headerRange: 'A1:W1'
downloadExcel({
data: excelList as unknown as JSON[],
fileName: '처리구역정보',
sheetNameArray: ['처리구역정보'],
headerRange: 'A1:W1'
});
}
}, [excelList]);
@@ -143,7 +147,7 @@ export default function ProcessArea() {
<ContentsDiv>
<SearchBaseForm
leftChildren={<>
<SelectBox className="col-span-3" label={processFacilityLabelArray[6] as string} selectArray={selectSearchYear} onSelectValue={(val) => setSearchYearValue(val.toString())} value={searchYearValue} selectClass={undefined}/>
<SelectBox className="col-span-3" label={processFacilityLabelArray[6] as string} selectArray={selectSearchYear} onSelectValue={(val) => setSearchYearValue(val.toString())} value={searchYearValue} selectClass={undefined} />
</>}
rightChildren={undefined}
selectSidoData={selectSidoData}
@@ -163,15 +167,16 @@ export default function ProcessArea() {
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll min-[1900px]:overflow-x-hidden">
<div className="w-[160%] min-[1900px]:w-[100%]">
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList} headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
<UiTable cellClick={(index: number | undefined) => index !== undefined && cellClick(index)} headName={"처리구역정보"} tableData={mainList}
headlist={upHeadList1} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
</div>
</div>
</ListDiv>
</ContentsDiv>
{selectedRow !== null && (
<UiModal
body={<ProcessFacilityInfoModal fcltyName={fcltyNm} facilityCd={fcltyCd}></ProcessFacilityInfoModal>}
bodyClass="sm:max-w-[90vw] w-[1200px] h-[900px]"
<UiModal
body={<ProcessFacilityInfoModal fcltyName={fcltyNm} facilityCd={fcltyCd}></ProcessFacilityInfoModal>}
bodyClass="sm:max-w-[90vw] w-[1200px] h-[100dvh] max-h-[900px] overflow-y-auto"
open={selectedRow !== null}
onOpenChange={(open: boolean) => !open && closeModal()}
/>
@@ -292,7 +292,7 @@ export default function ProcessFacilitySearch() {
{selectedRow !== null && (
<UiModal
body={<ProcessFacilityInfoModal fcltyName={modalFcltyNm} facilityCd={modalFcltyCd} sido={modalSido} gugun={modalGugun} daddr={modalAddr} fctCpc={modalFctCpc} trtFrfNm={modalTrtFrfNm} rnDt={modalRnDt} cmplDt={modalCmplDt} trstOprEtpNm={modalTrstOprEtpNm} bscFctClsNm={modalBscFctClsNm} mnstr={modalMnstr} efflWtrrgn={modalEfflWtrrgn} lgbsn={modalLgbsn} efflWqltStndrdNm={modalEfflWqltStndrdNm} rgnNm={modalRgnNm} rvbsn={modalRvbsn}></ProcessFacilityInfoModal>}
bodyClass="sm:max-w-[70vw] sm:max-h-[95vh]"
bodyClass="sm:max-w-[70vw] h-[100dvh] max-h-[800px]"
open={selectedRow !== null}
onOpenChange={(open) => !open && closeModal()}
/>
+2 -1
View File
@@ -215,7 +215,8 @@ export default function Rdi() {
<LoadingOverlay isLoading={isLoading} />
<div className="h-full w-full overflow-x-scroll min-[1200px]:overflow-x-hidden">
<div className="w-[120%] min-[1200px]:w-[100%]">
<UiTable cellClick={ undefined } headName={"RDII추정"} tableData={mainList} headlist={upheadList} pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
<UiTable cellClick={ undefined } headName={"RDII추정"} tableData={mainList} headlist={upheadList}
pageSize={10} total={total} resetPageNo={resetPage} onPageChange={handlePageChange} widthFixed={true} />
</div>
<UnderComment divHeight={"0"} commentArray={commentArray} />
</div>
@@ -8,7 +8,7 @@
import { roundNumber } from "@/app/components/common/DataForm";
import { useFoStore } from "@/app/store";
import type { modalTableType } from "@/app/store/sewageOccur";
import { DateMonthPicker, downloadExcel, UiTable } from "@common/business_components/ui";
import { DateMonthPicker, downloadExcelHeaders, UiTable } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Table, TableCell, TableHead, TableRow } from "@common/components/ui";
import { useEffect, useState } from "react";
@@ -69,20 +69,25 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
}
}, [endYearMonth, startYearMonth]);
const excelDownload = () => {
const excelDownload = () => {
// 헤더 순서를 명시적으로 정의
const headers = ["날짜", "물사용량(m³/일)", "오수전환율(%)", "오수발생량 추정(m³/일)"] as const;
const excelDownList: any[] = [];
if(detailList.length > 0){
detailList.forEach((item) => {
excelDownList.push({
"날짜": item.msrDt,
"물사용량(m³/일)": roundNumber(item.waterUsage, 0),
"오수전환율(%)": roundNumber(item.swageChangePercent, 0),
"오수발생량 추정(m³/일)": roundNumber(item.estimationSewage, 0),
});
// 순서를 보장하기 위해 헤더 순서대로 객체 생성
const row: Record<string, string | number> = {};
row[headers[0]] = item.msrDt;
row[headers[1]] = roundNumber(item.waterUsage, 0);
row[headers[2]] = roundNumber(item.swageChangePercent, 0);
row[headers[3]] = roundNumber(item.estimationSewage, 0);
excelDownList.push(row);
});
}
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 오수발생량 추정', sheetNameArray: [props.fcltyName + ' 오수발생량 추정'], headerRange: 'A1:D1' });
downloadExcelHeaders({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear+'년 '+props.fcltyName + ' 오수발생량 추정'
, sheetNameArray: [props.fcltyName + ' 오수발생량 추정'], headerRange: 'A1:D1', headers });
} else if (detailList.length == 0) {
alert('다운받을 데이터가 없습니다.');
}
@@ -250,7 +250,7 @@ export default function PlanSewage() {
facilityCd={fcltyCd}
searchYear={searchYear}
/>}
bodyClass="sm:max-w-[90vw] w-[1000px] h-[770px]"
bodyClass="sm:max-w-[90vw] w-[1000px] h-[100dvh] max-h-[770px]"
open={selectedRow !== null}
onOpenChange={(open) => !open && closeModal()}
noHeaderYn="Y"
@@ -29,7 +29,7 @@ const tabList1 = [
export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYear=new Date().getFullYear().toString()} : ModalProps) {
// 그리드 관련
const {Common, UnderWaterDetail, unserWaterModal} = useFoStore((state) => state);
const {Common, UnderWaterDetail, underWaterModal} = useFoStore((state) => state);
const { btnClass } = Common;
const [startYmDate, setStartYmDate] = useState<string>(searchYear+'01');
const [endYmDate, setEndYmDate] = useState<string>(searchYear+'12');
@@ -74,8 +74,8 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea
}, [searchYear, tabTerm]);
useEffect(()=>{
unserWaterModal(fcltyCd, searchYear, searchYear+'01', searchYear+'12');
}, [fcltyCd, searchYear, unserWaterModal]);
underWaterModal(fcltyCd, searchYear, searchYear+'01', searchYear+'12');
}, [fcltyCd, searchYear, underWaterModal]);
useEffect(() => {
if(endYmDate < startYmDate) {
@@ -93,8 +93,8 @@ export default function UnderWaterInputModal({fcltyCd='', fcltyName='',searchYea
}, [startYmDate, endYmDate, gridListUnderWaterDetail, prevStartYmDate, prevEndYmDate]);
useEffect(() => {
unserWaterModal(fcltyCd, searchYear, prevStartYmDate, prevEndYmDate);
} , [fcltyCd, searchYear, unserWaterModal, prevStartYmDate, prevEndYmDate]);
underWaterModal(fcltyCd, searchYear, prevStartYmDate, prevEndYmDate);
} , [fcltyCd, searchYear, underWaterModal, prevStartYmDate, prevEndYmDate]);
const excelDownload = () => {
const excelDownList: any[] = [];
@@ -251,7 +251,7 @@ export default function UnderWaterInput() {
{selectedRow !== null && (
<UiModal
body={<UnderWaterInputModal fcltyCd={fcltyCd} fcltyName={fcltyNm} searchYear={searchYear}></UnderWaterInputModal>}
bodyClass="sm:max-w-[90vw] w-[1000px] h-[770px]"
bodyClass="sm:max-w-[90vw] w-[1000px] h-[100dvh] max-h-[770px]"
open={selectedRow !== null}
onOpenChange={(open) => !open && closeModal()}
noHeaderYn="Y"
File diff suppressed because it is too large Load Diff
@@ -153,7 +153,9 @@ export const fetchFacilityRainDetailList = async (searchYear: string|undefined,
}
};
const fetchFacilityPrecipitationList = async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
const fetchFacilityPrecipitationList = async (pageNo: number, pageSize: number, searchYear: string, part?: string
, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
const tailStr = '/'+pageNo + '/' + pageSize + '/' + searchYear + (part?'/' + part:'' ) + (nameCd?'/' + nameCd:'' ) + (fcltCpct?'/' + fcltCpct:'' ) + (operationValue?'/' + operationValue:'' ) + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') ;
const url = '/fclt/rain' + tailStr;
const res = await getFetch('fo', url);
+164 -186
View File
@@ -2,7 +2,7 @@
import DataForm, { roundNumber } from "@/app/components/common/DataForm";
import type { TableUpperProps } from "../dashboard";
import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { COD_YEAR } from "../common";
import { COD_YEAR } from "../common"; // 2021년
import CommaToNumber from "@/app/components/common/CommaToNumber";
export type { TableUpperProps };
@@ -37,8 +37,8 @@ export interface FacilityWaterQltyProps {
inflAssctAftWqltBod: string | '',
inflAssctBfrWqltToc: string | '',
inflAssctAftWqltToc: string | '',
inflAssctBfrWqltCod : string | '',
inflAssctAftWqltCod : string | '',
inflAssctBfrWqltCod: string | '',
inflAssctAftWqltCod: string | '',
inflAssctBfrWqltSs: string | '',
inflAssctAftWqltSs: string | '',
inflAssctBfrWqltTn: string | '',
@@ -47,14 +47,14 @@ export interface FacilityWaterQltyProps {
inflAssctAftWqltTp: string | '',
efflWqltBod: string | '',
efflWqltToc: string | '',
efflWqltCod : string | '',
efflWqltCod: string | '',
efflWqltSs: string | '',
efflWqltTn: string | '',
efflWqltTp: string | '',
rgnNm:string|'',
rvbsn:string|'',
lgbsn:string|'',
mdmbsn:string|'',
rgnNm: string | '',
rvbsn: string | '',
lgbsn: string | '',
mdmbsn: string | '',
inflAmnt: number | '',
lclgvrnmntNm: string,
infoRnDay: number | string | '',
@@ -68,14 +68,14 @@ export interface FacilityWaterQltyProps {
tpInflWqltTp: string | '',
tpInflWqltEclgyTox: string | '',
tpInflWqltClfgrpcnt: string | '',
noProcessInflAmnt : string | number | '',
noProcessInflAmnt: string | number | '',
}
export interface ExcelType {
시설코드: string,
권역:string|'',
단위유역:string|'',
중권역:string|'',
환경청:string|'',
권역: string | '',
단위유역: string | '',
중권역: string | '',
환경청: string | '',
시도: string,
시군구: string,
시설이름: string,
@@ -146,74 +146,74 @@ const mainLabelArray: string[] = ['구분', '시도', '시군구', '용량별',
// 시설수질리스트 헤더(행정별)
const upHeadList1: TableUpperProps[] = [
{ id: "C", title: "행정명", colSpan: 2, row:0, widthPercent:10 },
{ id: "sidoNm", title: "시도", row: 1, widthPercent:5},
{ id: "sggNm", title: "시군구", row: 1, widthPercent:5 },
{ id: "C", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 },
{ id: "sidoNm", title: "시도", row: 1, widthPercent: 5 },
{ id: "sggNm", title: "시군구", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", rowSpan: 2, row: 0, widthPercent: 10 },
{ id: "addr", title: "주소", rowSpan: 2, row: 0 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0, widthPercent:10 },
{ id: "A", title: "유입", colSpan: 5, row: 0, widthPercent:25 },
{ id: "B", title: "방류", colSpan: 5, row: 0, widthPercent:25 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent:5 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent:5 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent:5 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1, widthPercent:5 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent:5 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent:5 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent:5 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent:5 },
{ id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 4, align: "right", row: 1, widthPercent:5 },
{ id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent:5 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0, widthPercent: 10 },
{ id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 25 },
{ id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 25 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 4, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 4, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
];
// 시설수질리스트 헤더(권역별)
const upHeadList2: TableUpperProps[] = [
{ id: "C", title: "유역", colSpan: 3, row: 0, widthPercent:15 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row:1, widthPercent:5 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row:1, widthPercent:5 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row:1, widthPercent:5 },
{ id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent:10 },
{ id: "addr", title: "주소", row:0, rowSpan:2 },
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2, widthPercent:8 },
{ id: "A", title: "유입", colSpan: 5, row: 0, widthPercent:25 },
{ id: "B", title: "방류", colSpan: 5, row: 0, widthPercent:25 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1, widthPercent:5 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent:5 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent:5 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent:5 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent:5 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1, widthPercent:5 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent:5 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent:5 },
{ id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent:5 },
{ id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent:5 },
{ id: "C", title: "유역", colSpan: 3, row: 0, widthPercent: 15 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe1", upSequnce: 1, row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe1", upSequnce: 2, row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe1", upSequnce: 3, row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "addr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 25 },
{ id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 25 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 5 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 5 },
{ id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 5 },
];
// 시설수질리스트 헤더(환경청별)
const upHeadList3: TableUpperProps[] = [
{ id: "C", title: "유역", colSpan: 3, row: 0, widthPercent: 15 },
{ id: "rvbsn", title: "권역", row:1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 7 },
{ id: "rvbsn", title: "권역", row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "D", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 },
{ id: "sidoNm", title: "시도", upName: "upChangeRe2", row:1, widthPercent: 5 },
{ id: "sggNm", title: "시군구", upName: "upChangeRe2", row:1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 },
{ id: "addr", title: "주소", row:0, rowSpan:2 },
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row:0, rowSpan:2, widthPercent: 5 },
{ id: "sidoNm", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "sggNm", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "addr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row: 0, rowSpan: 2, widthPercent: 5 },
{ id: "A", title: "유입", colSpan: 5, row: 0, widthPercent: 20 },
{ id: "B", title: "방류", colSpan: 5, row: 0, widthPercent: 20 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row:1, widthPercent: 4 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent: 4 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent: 4 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row:1, widthPercent: 4 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row:1, widthPercent: 4 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row:1, widthPercent: 4 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent: 4 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent: 4 },
{ id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row:1, widthPercent: 4 },
{ id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row:1, widthPercent: 4 },
{ id: "inflAssctBfrWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe3", upSequnce: 1, align: "right", row: 1, widthPercent: 4 },
{ id: "inflAssctBfrWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 4 },
{ id: "inflAssctBfrWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 4 },
{ id: "inflAssctBfrWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe3", upSequnce: 2, align: "right", row: 1, widthPercent: 4 },
{ id: "inflAssctBfrWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe3", upSequnce: 3, align: "right", row: 1, widthPercent: 4 },
{ id: "efflWqltBod", title: "BOD\n(mg/L)", upName: "upChangeRe4", upSequnce: 1, align: "right", row: 1, widthPercent: 4 },
{ id: "efflWqltToc", title: "TOC\n(COD)\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 4 },
{ id: "efflWqltSs", title: "SS\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 4 },
{ id: "efflWqltTn", title: "T-N\n(mg/L)", upName: "upChangeRe4", upSequnce: 2, align: "right", row: 1, widthPercent: 4 },
{ id: "efflWqltTp", title: "T-P\n(mg/L)", upName: "upChangeRe4", upSequnce: 3, align: "right", row: 1, widthPercent: 4 },
];
/**
@@ -282,9 +282,9 @@ const upHeadListModalChongIn: TableUpperProps[] = [
====================================*/
// 메인페이지
// 시설정보 수질 리스트 데이터 호출
const fetchFacilityWaterQltyList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string|undefined, nameCd?: string|undefined, fcltCpct?: string|undefined, operationValue?: string|undefined, fcltyNm?: string | undefined): Promise<{ data: FacilityWaterQltyProps[], count: number }> => {
const fetchFacilityWaterQltyList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string | undefined, nameCd?: string | undefined, fcltCpct?: string | undefined, operationValue?: string | undefined, fcltyNm?: string | undefined): Promise<{ data: FacilityWaterQltyProps[], count: number }> => {
try {
const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const tailStr = partCd ? '/' + partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const url = '/fclt/qlty/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
return { data: res.data, count: res.count }
@@ -295,7 +295,7 @@ const fetchFacilityWaterQltyList = async (pageNo: number, pageSize: number, sear
}
// 시설정보 수질 리스트 데이터 호출(모달-수질TMS)
const fetchFacilityWaterQltyTmsList = async (facilityCd: string|undefined) => {
const fetchFacilityWaterQltyTmsList = async (facilityCd: string | undefined) => {
try {
const res = await getFetch('wr', '/il/getTms/' + facilityCd);
return { data: res.data, count: res.count };
@@ -306,7 +306,7 @@ const fetchFacilityWaterQltyTmsList = async (facilityCd: string|undefined) => {
};
// 시설정보 수질 리스트 데이터 호출(모달-이력)
export const fetchFacilityWaterQltyListHist = async (searchYear: string|undefined, facilityCd: string|undefined): Promise<WaterQualityHistoryResponse | null> => {
export const fetchFacilityWaterQltyListHist = async (searchYear: string | undefined, facilityCd: string | undefined): Promise<WaterQualityHistoryResponse | null> => {
try {//
const res = await getFetch('fo', '/fclt/qlty/hist/' + searchYear + '/' + facilityCd);
return res;
@@ -316,9 +316,9 @@ export const fetchFacilityWaterQltyListHist = async (searchYear: string|undefine
}
};
// 시설정보 RDII 상세 [{BOD - inflAssctBfrWqltBod, 유입유량 inflAmnt, 강우량 infoRnDay, 측정일 msrDt}]
export const fetchFacilityRdiiDetailList = async (searchYear: string|undefined, swtrmtFcltCdList: string[]): Promise<FacilityRdiiDetailProps | null> => {
export const fetchFacilityRdiiDetailList = async (searchYear: string | undefined, swtrmtFcltCdList: string[]): Promise<FacilityRdiiDetailProps | null> => {
try {
const res = await postFetch('fo', '/rdii/detail/'+searchYear, swtrmtFcltCdList);
const res = await postFetch('fo', '/rdii/detail/' + searchYear, swtrmtFcltCdList);
return res;
} catch (error) {
console.error('시설정보 RDII 상세 데이터를 가져오는데 실패했습니다:', error);
@@ -345,7 +345,7 @@ export type FacilityWaterQltyType = {
FacilityWaterQltyModal: {
// 처리시설 수질현황
upHeadListModalYear: TableUpperProps[];
upHeadListModalYearCod : TableUpperProps[];
upHeadListModalYearCod: TableUpperProps[];
facilityWaterQltyYearList: FacilityWaterQltyProps[];
upHeadListModalTms: TableUpperProps[];
facilityWaterQltyTmsList: FacilityWaterQltyTmsProps[];
@@ -432,7 +432,8 @@ const dataFormSetting = (item: FacilityWaterQltyProps) => {
export type FacilityWaterQltyStore = FacilityWaterQltyType & FacilityWaterQltyActions;
export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType) => FacilityWaterQltyType) => void): FacilityWaterQltyActions => {
type SetFunc = (fn: (state: FacilityWaterQltyType) => FacilityWaterQltyType) => void;
export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions => {
return {
// 메인페이지
/**
@@ -446,7 +447,9 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
* @param operationValue : 운영상태코드
* @param fcltyNm : 시설명
*/
searchFacilityWaterQltyList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
searchFacilityWaterQltyList: async (pageNo: number, pageSize: number, searchYear: string, part?: string
, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FacilityWaterQltyType) => ({
...state,
FacilityWaterQltyMain: {
@@ -457,53 +460,53 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
const res = await fetchFacilityWaterQltyList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
const rtnData = res.data.map(item => {
dataFormSetting(item)
if(item.inflAssctBfrWqltTn) {
item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000)/1000).toFixed(3);
if (item.inflAssctBfrWqltTn) {
item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000) / 1000).toFixed(3);
}
if(item.efflWqltTn){
item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000)/1000).toFixed(3);
if (item.efflWqltTn) {
item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000) / 1000).toFixed(3);
}
if(item.inflAssctBfrWqltTp){
item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000)/1000).toFixed(3);
if (item.inflAssctBfrWqltTp) {
item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000) / 1000).toFixed(3);
}
if(item.efflWqltTp){
item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000)/1000).toFixed(3);
if (item.efflWqltTp) {
item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000) / 1000).toFixed(3);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltToc) {
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
if (item.efflWqltToc) {
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1);
}
if(item.inflAssctBfrWqltBod){
item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltBod) {
item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10) / 10).toFixed(1);
}
if(item.efflWqltBod){
item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10)/10).toFixed(1);
if (item.efflWqltBod) {
item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10) / 10).toFixed(1);
}
if(item.inflAssctBfrWqltSs){
item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltSs) {
item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10) / 10).toFixed(1);
}
if(item.efflWqltSs){
item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10)/10).toFixed(1);
if (item.efflWqltSs) {
item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10) / 10).toFixed(1);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltToc) {
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
if (item.efflWqltToc) {
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1);
}
return item;
});
const excelDownList: ExcelType[] = [];
if(pageSize>5000){
if (pageSize > 5000) {
res.data.forEach(item => {
dataFormSetting(item)
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
item.inflAssctBfrWqltToc = Number(searchYear)<COD_YEAR? "("+item.inflAssctBfrWqltToc+")" : item.inflAssctBfrWqltToc;
item.efflWqltToc = Number(searchYear)<COD_YEAR? "("+item.efflWqltToc+")" : item.efflWqltToc;
item.inflAssctBfrWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.inflAssctBfrWqltToc + ")" : item.inflAssctBfrWqltToc;
item.efflWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.efflWqltToc + ")" : item.efflWqltToc;
excelDownList.push({
시설코드: item.bscFctCd,
권역: item.rvbsn,
@@ -527,27 +530,27 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
"유출TP(mg/L)": CommaToNumber(item.efflWqltTp),
});
});
}else{
} else {
res.data.forEach((item: FacilityWaterQltyProps) => {
dataFormSetting(item)
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
item.inflAssctBfrWqltToc = Number(searchYear)<COD_YEAR? "("+item.inflAssctBfrWqltToc+")" : item.inflAssctBfrWqltToc;
item.efflWqltToc = Number(searchYear)<COD_YEAR? "("+item.efflWqltToc+")" : item.efflWqltToc;
item.inflAssctBfrWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.inflAssctBfrWqltToc + ")" : item.inflAssctBfrWqltToc;
item.efflWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.efflWqltToc + ")" : item.efflWqltToc;
});
}
set((state: FacilityWaterQltyType) => ({
...state,
FacilityWaterQltyMain: pageSize<5000?{
FacilityWaterQltyMain: pageSize < 5000 ? {
...state.FacilityWaterQltyMain,
facilityWaterQltyList: rtnData,
facilityWaterQltyCount: res.count,
isLoading : false,
}:{
isLoading: false,
} : {
...state.FacilityWaterQltyMain,
excelList: excelDownList,
isLoading : false,
isLoading: false,
},
}))
},
@@ -555,10 +558,10 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
searchFacilityWaterQltyListHist: async (searchYear: string, facilityCd: string) => {
const res = await fetchFacilityWaterQltyListHist(searchYear, facilityCd);
const res1 = await fetchFacilityWaterQltyTmsList(facilityCd);
let rtnMsrmtDate = '';
const rtnTmsList: FacilityWaterQltyTmsProps[] = [];
if(res1.data){
if (res1.data) {
rtnTmsList.push({
part: '평균',
toc: res1.data.tocAvgVl,
@@ -566,7 +569,6 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
tn: res1.data.tnAvgVl,
tp: res1.data.tpAvgVl,
});
rtnTmsList.push({
part: '최대',
toc: res1.data.tocMaxVl,
@@ -574,7 +576,6 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
tn: res1.data.tnMaxVl,
tp: res1.data.tpMaxVl,
});
rtnTmsList.push({
part: '최소',
toc: res1.data.tocMinVl,
@@ -584,42 +585,21 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
});
rtnMsrmtDate = res1.data.msrmtDate;
}else{
rtnTmsList.push({
part: '평균',
toc: 0,
ss: 0,
tn: 0,
tp: 0,
});
rtnTmsList.push({
part: '최대',
toc: 0,
ss: 0,
tn: 0,
tp: 0,
});
rtnTmsList.push({
part: '최소',
toc: 0,
ss: 0,
tn: 0,
tp: 0,
});
} else {
rtnTmsList.push({ part: '평균', toc: 0, ss: 0, tn: 0, tp: 0, });
rtnTmsList.push({ part: '최대', toc: 0, ss: 0, tn: 0, tp: 0, });
rtnTmsList.push({ part: '최소', toc: 0, ss: 0, tn: 0, tp: 0, });
rtnMsrmtDate = '';
}
if(Array.isArray(res) || !res || !('data' in res) || !res.data || !res.data.wqltObjs || res.data.wqltObjs.length === 0) {
if (Array.isArray(res) || !res || !('data' in res) || !res.data || !res.data.wqltObjs || res.data.wqltObjs.length === 0) {
set((state: FacilityWaterQltyType) => ({
...state,
FacilityWaterQltyModal: {
...state.FacilityWaterQltyModal,
facilityWaterQltyYearList: [],
tmsList : rtnTmsList,
msrmtDate : rtnMsrmtDate
tmsList: rtnTmsList,
msrmtDate: rtnMsrmtDate
}
}))
return;
@@ -627,19 +607,17 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
// facilityPrecipitation의 rainEffectDay 계산 로직을 적용
const data = CalcRainEffect(res.data.wqltObjs);
/**
* [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​
/강우시 일별유입BOD)
*/
//let rainInflAmnt = 0;
let sunnyInflAmnt = 0;
let sunnyBod = 0;
//let rainDay = 0;
let sunnyDay = 0;
data.forEach(item => {
if(item.rainEffectDay == 1){
if (item.rainEffectDay == 1) {
//rainDay += 1;
//rainInflAmnt += Number(item.inflAmnt);
} else {
@@ -650,69 +628,69 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
});
//const yearRainAmnt = rainInflAmnt===0?0:rainInflAmnt / rainDay;
const yearSunnyAmnt = sunnyInflAmnt===0?0:sunnyInflAmnt / sunnyDay;
const yearSunnyBod = sunnyBod===0?0:sunnyBod / sunnyDay;
const yearSunnyAmnt = sunnyInflAmnt === 0 ? 0 : sunnyInflAmnt / sunnyDay;
const yearSunnyBod = sunnyBod === 0 ? 0 : sunnyBod / sunnyDay;
//
const rtnData = data.map((item: FacilityWaterQltyProps) => {
dataFormSetting(item)
if(item.inflAssctBfrWqltTn) {
item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000)/1000).toFixed(3);
if (item.inflAssctBfrWqltTn) {
item.inflAssctBfrWqltTn = Number(Math.round(Number(item.inflAssctBfrWqltTn) * 1000) / 1000).toFixed(3);
}
if(item.efflWqltTn){
item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000)/1000).toFixed(3);
if (item.efflWqltTn) {
item.efflWqltTn = Number(Math.round(Number(item.efflWqltTn) * 1000) / 1000).toFixed(3);
}
if(item.inflAssctBfrWqltTp){
item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000)/1000).toFixed(3);
if (item.inflAssctBfrWqltTp) {
item.inflAssctBfrWqltTp = Number(Math.round(Number(item.inflAssctBfrWqltTp) * 1000) / 1000).toFixed(3);
}
if(item.efflWqltTp){
item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000)/1000).toFixed(3);
if (item.efflWqltTp) {
item.efflWqltTp = Number(Math.round(Number(item.efflWqltTp) * 1000) / 1000).toFixed(3);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltToc) {
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
if (item.efflWqltToc) {
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1);
}
if(item.inflAssctBfrWqltCod){
item.inflAssctBfrWqltCod = "("+Number(Math.round(Number(item.inflAssctBfrWqltCod) * 10)/10).toFixed(1)+")";
if (item.inflAssctBfrWqltCod) {
item.inflAssctBfrWqltCod = "(" + Number(Math.round(Number(item.inflAssctBfrWqltCod) * 10) / 10).toFixed(1) + ")";
}
if(item.efflWqltCod){
item.efflWqltCod = "("+Number(Math.round(Number(item.efflWqltCod) * 10)/10).toFixed(1)+")";
if (item.efflWqltCod) {
item.efflWqltCod = "(" + Number(Math.round(Number(item.efflWqltCod) * 10) / 10).toFixed(1) + ")";
}
if(item.inflAssctBfrWqltBod){
item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltBod) {
item.inflAssctBfrWqltBod = Number(Math.round(Number(item.inflAssctBfrWqltBod) * 10) / 10).toFixed(1);
}
if(item.efflWqltBod){
item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10)/10).toFixed(1);
if (item.efflWqltBod) {
item.efflWqltBod = Number(Math.round(Number(item.efflWqltBod) * 10) / 10).toFixed(1);
}
if(item.inflAssctBfrWqltSs){
item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltSs) {
item.inflAssctBfrWqltSs = Number(Math.round(Number(item.inflAssctBfrWqltSs) * 10) / 10).toFixed(1);
}
if(item.efflWqltSs){
item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10)/10).toFixed(1);
if (item.efflWqltSs) {
item.efflWqltSs = Number(Math.round(Number(item.efflWqltSs) * 10) / 10).toFixed(1);
}
if(item.inflAssctBfrWqltToc){
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10)/10).toFixed(1);
if (item.inflAssctBfrWqltToc) {
item.inflAssctBfrWqltToc = Number(Math.round(Number(item.inflAssctBfrWqltToc) * 10) / 10).toFixed(1);
}
if(item.efflWqltToc){
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10)/10).toFixed(1);
if (item.efflWqltToc) {
item.efflWqltToc = Number(Math.round(Number(item.efflWqltToc) * 10) / 10).toFixed(1);
}
if(item.tpInflWqltBod){
item.tpInflWqltBod = item.tpInflWqltBod?Number(Math.round(Number(item.tpInflWqltBod) * 10)/10).toFixed(1):Number(item.tpInflWqltBod)===0?'0.0':'';
}else{
if (item.tpInflWqltBod) { // 총인 유입수질 BOD(mg/L)
item.tpInflWqltBod = item.tpInflWqltBod ? Number(Math.round(Number(item.tpInflWqltBod) * 10) / 10).toFixed(1) : Number(item.tpInflWqltBod) === 0 ? '0.0' : '';
} else {
item.tpInflWqltBod = '';
}
if(item.tpInflWqltTp){
item.tpInflWqltTp = item.tpInflWqltTp?Number(Math.round(Number(item.tpInflWqltTp) * 1000)/1000).toFixed(3): Number(item.tpInflWqltTp)===0?'0.000':'';
}else{
if (item.tpInflWqltTp) { // 총인 유입수질 TP(mg/L)
item.tpInflWqltTp = item.tpInflWqltTp ? Number(Math.round(Number(item.tpInflWqltTp) * 1000) / 1000).toFixed(3) : Number(item.tpInflWqltTp) === 0 ? '0.000' : '';
} else {
item.tpInflWqltTp = '';
}
const dayBod = Number(item.inflAssctBfrWqltBod);
const noProcessInflAmnt = roundNumber(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod, 0)
item.noProcessInflAmnt = noProcessInflAmnt && Number(noProcessInflAmnt.replaceAll(',','')) > 0 ? noProcessInflAmnt : '';
item.noProcessInflAmnt = noProcessInflAmnt && Number(noProcessInflAmnt.replaceAll(',', '')) > 0 ? noProcessInflAmnt : '';
return item;
})
@@ -721,8 +699,8 @@ export const facilityWaterQltyReducer = (set: (fn: (state: FacilityWaterQltyType
FacilityWaterQltyModal: {
...state.FacilityWaterQltyModal,
facilityWaterQltyYearList: rtnData,
tmsList : rtnTmsList,
msrmtDate : rtnMsrmtDate
tmsList: rtnTmsList,
msrmtDate: rtnMsrmtDate
}
}))
},
+160 -155
View File
@@ -1,6 +1,6 @@
import { getFetch } from "@/app/components/api";
import type { TableUpperProps } from "../dashboard";
import DataForm, { roundNumber } from "@/app/components/common/DataForm";
import DataForm from "@/app/components/common/DataForm";
import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { fetchFacilityWaterQltyListHist } from "../facilityWaterQlty";
import CommaToNumber from "@/app/components/common/CommaToNumber";
@@ -12,34 +12,34 @@ import CommaToNumber from "@/app/components/common/CommaToNumber";
/**
* (1) 메인페이지
*/
const FlowRateSearchLabelArray:string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
const FlowRateSearchLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
export type flowRateListProps = {
bscFctCd : string,
sido : string,
gugun : string,
bscFctNm : string,
daddr : string,
fctCpc : number,
lclgvrnmntNm : string,
totInflAmnt : number | '',
inflAmnt : number | '',
sumFlow : number | '',
returnAmnt : number | '',
efflAmnt : number | '',
rgnNm : string,
rvbsn : string,
lgbsn : string,
mdmbsn : string,
infoRnDay : number | '',
bscFctCd: string,
sido: string,
gugun: string,
bscFctNm: string,
daddr: string,
fctCpc: number,
lclgvrnmntNm: string,
totInflAmnt: number | '',
inflAmnt: number | '',
sumFlow: number | '',
returnAmnt: number | '',
efflAmnt: number | '',
rgnNm: string,
rvbsn: string,
lgbsn: string,
mdmbsn: string,
infoRnDay: number | '',
}
export interface ExcelType {
시설코드: string,
권역:string|'',
단위유역:string|'',
중권역:string|'',
환경청:string|'',
권역: string | '',
단위유역: string | '',
중권역: string | '',
환경청: string | '',
시도: string,
시군구: string,
시설이름: string,
@@ -66,105 +66,105 @@ export type modalExcelType = {
* (2) 모달
*/
export interface FlowRateModalInterface {
msrDt : string,
totInflAmnt : number | '',
inflAmnt : number | '',
sumFlow : number | '',
returnAmnt : number | '',
efflAmnt : number | '',
infoRnDay : number | string | '',
rainEffectDay : number | string | '' ,
noProcessInflAmnt : number | string | ''
msrDt: string,
totInflAmnt: number | '',
inflAmnt: number | '',
sumFlow: number | '',
returnAmnt: number | '',
efflAmnt: number | '',
infoRnDay: number | string | '',
rainEffectDay: number | string | '',
noProcessInflAmnt: number | string | ''
}
export type FlowRateModalProps = {
msrDt : string,
totInflAmnt : number,
inflAmnt : number,
sumFlow : number,
returnAmnt : number,
efflAmnt : number,
infoRnDay : number | string | '',
rainEffectDay : number | string | '',
noProcessInflAmnt : number | string | ''
msrDt: string,
totInflAmnt: number,
inflAmnt: number,
sumFlow: number,
returnAmnt: number,
efflAmnt: number,
infoRnDay: number | string | '',
rainEffectDay: number | string | '',
noProcessInflAmnt: number | string | ''
}
/**====================================
* Store - data
====================================*/
/**
* (1) 메인페이지
*/
/**
* (1) 메인페이지
*/
// 리스트 (행정별)
const upHeadList1:TableUpperProps[] = [
const upHeadList1: TableUpperProps[] = [
{ id: "A", title: "행정명", row: 0, colSpan: 2, widthPercent: 16 },
{ id: "sido", title: "시도", upName:"upChangeRe", row:1, widthPercent: 8 },
{ id: "gugun", title: "시군구", upName:"upChangeRe", row:1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10},
{ id: "sido", title: "시도", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "gugun", title: "시군구", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }
{ id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }
];
// 리스트 (권역별)
const upHeadList2:TableUpperProps[] = [
const upHeadList2: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 24 },
{ id: "rvbsn", title: "권역", upName:"upChangeRe", row:1, widthPercent: 8 },
{ id: "lgbsn", title: "단위유역", upName:"upChangeRe", row:1, widthPercent: 8 },
{ id: "mdmbsn", title: "중권역", upName:"upChangeRe", row:1, widthPercent: 8 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe", row: 1, widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }
{ id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }
];
// 리스트 (환경청별별)
const upHeadList3:TableUpperProps[] = [
const upHeadList3: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3, widthPercent: 15 },
{ id: "rvbsn", title: "권역", upName:"upChangeRe1", row:1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", upName:"upChangeRe1", row:1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", upName:"upChangeRe1", row:1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 7 },
{ id: "B", title: "행정명", row: 0 ,colSpan: 2, widthPercent: 10 },
{ id: "sido", title: "시도", upName:"upChangeRe2", row:1, widthPercent: 5 },
{ id: "gugun", title: "시군구", upName:"upChangeRe2", row:1, widthPercent: 5 },
{ id: "rvbsn", title: "권역", upName: "upChangeRe1", row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", upName: "upChangeRe1", row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", upName: "upChangeRe1", row: 1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "B", title: "행정명", row: 0, colSpan: 2, widthPercent: 10 },
{ id: "sido", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "gugun", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align:"right", row: 0, rowSpan: 2, widthPercent: 7 }
{ id: "fctCpc", title: "시설용량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "totInflAmnt", title: "총 유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "inflAmnt", title: "하수유입량\n(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "sumFlow", title: '연계처리량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "returnAmnt", title: '총인 반류수량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "efflAmnt", title: '방류량\n(m³/일)', align: "right", row: 0, rowSpan: 2, widthPercent: 7 }
];
const flowRateList:flowRateListProps[] = [
const flowRateList: flowRateListProps[] = [
]
/**
* (2) 모달
*/
const upHeadListFlowRateModal:TableUpperProps[] = [
{ id: "msrDt", title: "날짜"},
{ id: "totInflAmnt", title: "총 유입량(m³/일)", align:"right"},
{ id: "inflAmnt", title: "하수유입량(m³/일)", align:"right"},
{ id: "sumFlow", title: "연계처리량(m³/일)", align:"right"},
{ id: "returnAmnt", title: "총인 반류수량(m³/일)", align:"right"},
{ id: "efflAmnt", title: "방류량(m³/일)", align:"right"},
{ id: "noProcessInflAmnt", title: "미처리하수 추정량(m³/일)", align:"right"},
{ id: "infoRnDay", title: "강우량(mm/일)", align:"right"}
const upHeadListFlowRateModal: TableUpperProps[] = [
{ id: "msrDt", title: "날짜" },
{ id: "totInflAmnt", title: "총 유입량(m³/일)", align: "right" },
{ id: "inflAmnt", title: "하수유입량(m³/일)", align: "right" },
{ id: "sumFlow", title: "연계처리량(m³/일)", align: "right" },
{ id: "returnAmnt", title: "총인 반류수량(m³/일)", align: "right" },
{ id: "efflAmnt", title: "방류량(m³/일)", align: "right" },
{ id: "noProcessInflAmnt", title: "미처리하수 추정량(m³/일)", align: "right" },
{ id: "infoRnDay", title: "강우량(mm/일)", align: "right" }
]
const modalFlowRateListYear:FlowRateModalProps[] = [
const modalFlowRateListYear: FlowRateModalProps[] = [
]
/**====================================
@@ -172,12 +172,13 @@ const modalFlowRateListYear:FlowRateModalProps[] = [
====================================*/
const fetchFlowRateList = async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
try {
const tailStr = partCd ? '/'+ partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const tailStr = partCd ? '/' + partCd + '/' + nameCd + '/' + fcltCpct + '/' + operationValue + (fcltyNm && fcltyNm !== '' ? '/' + fcltyNm : '') : '';
const url = '/fclt/flow/' + pageNo + '/' + pageSize + '/' + searchYear + tailStr;
const res = await getFetch('fo', url);
return { data: res.data, count: res.count }
} catch (error) {
console.error('시설정보 유량현황 데이터를 가져오는데 실패했습니다:', error);
console.log(error);
return { data: [], count: 0 };
}
}
@@ -186,12 +187,12 @@ export const fetchFlowRateModalList = async (bscFctCd: string, searchYear: strin
try {
const url = '/fclt/flow/' + bscFctCd + '/' + searchYear;
const res = await getFetch('fo', url);
// msrDt 오름차순으로 정렬
const sortedData = res.data.sort((a: FlowRateModalInterface, b: FlowRateModalInterface) => {
return new Date(a.msrDt).getTime() - new Date(b.msrDt).getTime();
});
return { data: sortedData }
} catch (error) {
console.error('시설정보 유량현황 모달 데이터를 가져오는데 실패했습니다:', error);
@@ -206,69 +207,69 @@ export const fetchFlowRateModalList = async (bscFctCd: string, searchYear: strin
export type FlowRateSearchActions = {
searchFlowRateList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
searchFlowRateModalList : (bscFctCd: string, searchYear: string) => void;
searchFlowRateModalList: (bscFctCd: string, searchYear: string) => void;
}
export type FlowRateSearchType = {
FlowRateSearch: {
isInit: boolean;
flowRateSearchLabelArray:string[];
flowRateSearchLabelArray: string[];
},
FlowRateList : {
isInit : boolean;
FlowRateList: {
isInit: boolean;
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
upHeadList3: TableUpperProps[];
flowRateList:flowRateListProps[];
flowRateList: flowRateListProps[];
flowRateCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
FlowRateModal : {
isInit : boolean;
modalFlowRateListYear : FlowRateModalProps[];
upHeadListFlowRateModalYear : TableUpperProps[];
FlowRateModal: {
isInit: boolean;
modalFlowRateListYear: FlowRateModalProps[];
upHeadListFlowRateModalYear: TableUpperProps[];
}
}
export type FlowRateSearchStore = FlowRateSearchType & FlowRateSearchActions;
const dataFormSetting=(item : flowRateListProps | FlowRateModalProps)=> {
export const dataFormSetting = (item: flowRateListProps | FlowRateModalProps | FlowRateModalInterface) => {
DataForm({ type: 'date', column: 'msrDt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'totInflAmnt', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'sumFlow', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'efflWqltBod', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'returnAmnt', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'efflAmnt', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'totInflAmnt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'sumFlow', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'efflWqltBod', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'returnAmnt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'efflAmnt', item: item as unknown as Record<string, unknown> });
}
export const flowRateSearchInitState:FlowRateSearchType = {
export const flowRateSearchInitState: FlowRateSearchType = {
FlowRateSearch: {
isInit: false,
flowRateSearchLabelArray: FlowRateSearchLabelArray,
},
FlowRateList : {
isInit : false,
upHeadList1 : upHeadList1,
upHeadList2 : upHeadList2,
upHeadList3 : upHeadList3,
flowRateList : flowRateList,
flowRateCount : 0,
FlowRateList: {
isInit: false,
upHeadList1: upHeadList1,
upHeadList2: upHeadList2,
upHeadList3: upHeadList3,
flowRateList: flowRateList,
flowRateCount: 0,
excelList: [],
isLoading: true,
},
FlowRateModal : {
isInit : false,
upHeadListFlowRateModalYear : upHeadListFlowRateModal,
modalFlowRateListYear : modalFlowRateListYear,
FlowRateModal: {
isInit: false,
upHeadListFlowRateModalYear: upHeadListFlowRateModal,
modalFlowRateListYear: modalFlowRateListYear,
}
}
export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => FlowRateSearchType) => void)=>FlowRateSearchActions=(set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => {
export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => FlowRateSearchActions = (set: (fn: (state: FlowRateSearchType) => FlowRateSearchType) => void) => {
return {
searchFlowRateList: async (pageNo: number, pageSize: number, searchYear: string, partCd?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: FlowRateSearchType) => ({
@@ -283,12 +284,12 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow
const excelDownList: ExcelType[] = [];
const rtnData = data.map((item: flowRateListProps) => {
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0)
item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0); // 하수유입량 + 연계처리량 + 반류수유량(m³/일)
dataFormSetting(item);
return item;
});
if(pageSize>5000){
if (pageSize > 5000) {
rtnData.forEach((item: flowRateListProps) => {
excelDownList.push({
시설코드: item.bscFctCd,
@@ -312,15 +313,15 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow
set((state: FlowRateSearchType) => ({
...state,
FlowRateList: pageSize<5000?{
FlowRateList: pageSize < 5000 ? {
...state.FlowRateList,
flowRateList: rtnData,
flowRateCount: res.count,
isLoading : false,
}:{
isLoading: false,
} : {
...state.FlowRateList,
excelList: excelDownList,
isLoading : false,
isLoading: false,
},
}))
},
@@ -329,44 +330,48 @@ export const flowRateSearchReducer:(set:(fn: (state: FlowRateSearchType) => Flow
const inflData = CalcRainEffect(res.data);
const res2 = await fetchFacilityWaterQltyListHist(searchYear, bscFctCd);
const wqltData = CalcRainEffect(res2?.data.wqltObjs);
const wqltData = res2?.data.wqltObjs;
//const wqltData = CalcRainEffect(res2?.data.wqltObjs);
/**
* [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]​
/강우시 일별유입BOD)
* [(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)] / 강우시 일별유입BOD
*/
//let rainInflAmnt = 0;
let sunnyInflAmnt = 0;
let sunnyBod = 0;
//let rainDay = 0;
let sunnyInflAmnt = 0; // 청천시 일별유입유량
let sunnyBod = 0; // 청천시 일별유입BOD
let sunnyDay = 0;
inflData.forEach(item => {
if(item.rainEffectDay == 1){
//rainDay += 1;
//rainInflAmnt += Number(item.inflAmnt);
let rainEffectDay = 0;
wqltData?.forEach(item => {
if (item.infoRnDay == null) item.infoRnDay = 0;
if (Number(item.infoRnDay) >= 3) {
rainEffectDay = 2;
} else {
const msrDt = item.msrDt.replaceAll('-','');
rainEffectDay--;
}
if (rainEffectDay < 0) { //청천시
sunnyDay += 1;
sunnyInflAmnt += Number(item.inflAmnt);
sunnyBod += Number(wqltData.filter((wqitem)=>wqitem.msrDt === msrDt)[0].inflAssctBfrWqltBod);
sunnyBod += Number(item.inflAssctBfrWqltBod);
}
});
//const yearRainAmnt = rainInflAmnt===0?0:rainInflAmnt / rainDay;
const yearSunnyAmnt = sunnyInflAmnt===0?0:sunnyInflAmnt / sunnyDay;
const yearSunnyBod = sunnyBod===0?0:sunnyBod / sunnyDay;
const yearSunnyAmnt = sunnyDay > 0 ? sunnyInflAmnt / sunnyDay : 0; // 청천시 연평균유입유량
const yearSunnyBod = sunnyDay > 0 ? sunnyBod / sunnyDay : 0; // 청천시 연평균유입BOD
console.log(inflData);
const rtnData = inflData.map((item: FlowRateModalProps) => {
const dayBod = Number(wqltData.filter(wqitem=>wqitem.msrDt === item.msrDt.replaceAll('-',''))[0].inflAssctBfrWqltBod);
const noProcessInflAmnt = roundNumber(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod, 0)
item.totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0);
item.noProcessInflAmnt = noProcessInflAmnt && Number(noProcessInflAmnt.replaceAll(',','')) > 0 ? noProcessInflAmnt : '';
dataFormSetting(item);
return item;
const targetWqItem = wqltData?.find(wqitem => wqitem.msrDt === item.msrDt.replaceAll('-', ''));
const dayBod = targetWqItem ? Number(targetWqItem.inflAssctBfrWqltBod) : 0;
const noProcessInflAmnt = Math.round(((Number(item.inflAmnt) * dayBod) - (yearSunnyAmnt * yearSunnyBod)) / dayBod)
const totInflAmnt = Number(item.inflAmnt || 0) + Number(item.sumFlow || 0) + Number(item.returnAmnt || 0);
return {
...item,
totInflAmnt,
noProcessInflAmnt: noProcessInflAmnt && noProcessInflAmnt > 0 ? noProcessInflAmnt : '',
msrDt: (item.msrDt.length === 8 && !item.msrDt.includes('-')) ?
`${item.msrDt.slice(0, 4)}-${item.msrDt.slice(4, 6)}-${item.msrDt.slice(6, 8)}`
: item.msrDt,
};
});
console.log(rtnData);
set((state: FlowRateSearchType) => ({
...state,
FlowRateModal: {
+262 -260
View File
@@ -12,52 +12,52 @@ export type { TableUpperProps };
*/
// 처리구역 리스트
export type ProcessAreaProps = {
swtrmtFcltCd : string,
swtrmtFcltCd: string,
ctpvNm?: string,
sggNm?: string,
swtrmtFcltNm : string,
location : string,
fctCpc : number | '',
fcltCpctSum : number | '',
ruse : boolean,
planYrDt4 : string,
planYr : string,
planYrDc1 : string,
planYrDc2 : string,
planYrDc3 : string,
planYrDc4 : string,
swtrmtFcltNm: string,
location: string,
fctCpc: number | '',
fcltCpctSum: number | '',
ruse: boolean,
planYrDt4: string,
planYr: string,
planYrDc1: string,
planYrDc2: string,
planYrDc3: string,
planYrDc4: string,
/**
* 증설계획
*/
// 기승인(당초4단계), 현재, 변경1~4
planSwageQntSumDt4 : number | '',
planSwageQntSum : number | '',
planSwageQntSumDc1 : number | '',
planSwageQntSumDc2 : number | '',
planSwageQntSumDc3 : number | '',
planSwageQntSumDc4 : number | '',
planSwageQntSumDt4: number | '',
planSwageQntSum: number | '',
planSwageQntSumDc1: number | '',
planSwageQntSumDc2: number | '',
planSwageQntSumDc3: number | '',
planSwageQntSumDc4: number | '',
/**
* 처리인구
*/
// 기승인(당초4단계), 변경1~4
swtrmtPpltnCntDt4 : number | '',
swtrmtPpltnCnt : number | '',
swtrmtPpltnCntDc1 : number | '',
swtrmtPpltnCntDc2 : number | '',
swtrmtPpltnCntDc3 : number | '',
swtrmtPpltnCntDc4 : number | '',
swtrmtPpltnCntDt4: number | '',
swtrmtPpltnCnt: number | '',
swtrmtPpltnCntDc1: number | '',
swtrmtPpltnCntDc2: number | '',
swtrmtPpltnCntDc3: number | '',
swtrmtPpltnCntDc4: number | '',
/**
* 처리구역면적
*/
// 기승인(당초4단계), 변경1~4
swtrmtZoneAreaDt4 : number | '',
swtrmtZoneArea : number | '',
swtrmtZoneAreaDc1 : number | '',
swtrmtZoneAreaDc2 : number | '',
swtrmtZoneAreaDc3 : number | '',
swtrmtZoneAreaDc4 : number | '',
swtrmtZoneAreaDt4: number | '',
swtrmtZoneArea: number | '',
swtrmtZoneAreaDc1: number | '',
swtrmtZoneAreaDc2: number | '',
swtrmtZoneAreaDc3: number | '',
swtrmtZoneAreaDc4: number | '',
// 처리구역
trtDstr : string | '',
trtDstr: string | '',
}
export interface ExcelType {
@@ -89,32 +89,32 @@ export interface ExcelType {
// (2) 처리구역 팝업
// 시설증설 계획
export type FcltyImproveInfoProps = {
planSwageQntSumDt4 : number | '',
planSwageQntSum : number | '',
planSwageQntSumDc1 : number | '',
planSwageQntSumDc2 : number | '',
planSwageQntSumDc3 : number | '',
planSwageQntSumDc4 : number | '',
planSwageQntSumDt4: number | '',
planSwageQntSum: number | '',
planSwageQntSumDc1: number | '',
planSwageQntSumDc2: number | '',
planSwageQntSumDc3: number | '',
planSwageQntSumDc4: number | '',
}
// 처리인구 계획
export type ProcessPopulationProps = {
swtrmtPpltnCntDt4 : number | '',
swtrmtPpltnCnt : number | '',
swtrmtPpltnCntDc1 : number | '',
swtrmtPpltnCntDc2 : number | '',
swtrmtPpltnCntDc3 : number | '',
swtrmtPpltnCntDc4 : number | '',
swtrmtPpltnCntDt4: number | '',
swtrmtPpltnCnt: number | '',
swtrmtPpltnCntDc1: number | '',
swtrmtPpltnCntDc2: number | '',
swtrmtPpltnCntDc3: number | '',
swtrmtPpltnCntDc4: number | '',
}
// 처리구역 계획
export type ProcessAreaPlanProps = {
swtrmtZoneAreaDt4 : number | '',
swtrmtZoneArea : number | '',
swtrmtZoneAreaDc1 : number | '',
swtrmtZoneAreaDc2 : number | '',
swtrmtZoneAreaDc3 : number | '',
swtrmtZoneAreaDc4 : number | '',
trtDstr : string,
swtrmtZoneAreaDt4: number | '',
swtrmtZoneArea: number | '',
swtrmtZoneAreaDc1: number | '',
swtrmtZoneAreaDc2: number | '',
swtrmtZoneAreaDc3: number | '',
swtrmtZoneAreaDc4: number | '',
trtDstr: string,
}
/**====================================
@@ -123,93 +123,93 @@ export type ProcessAreaPlanProps = {
/**
* (1) 메인페이지
*/
*/
// 검색단
const ProcessFacilityLabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '시설상태', '연도별', '권역', '단위유역', '중권역', '환경청별'];
const ProcessFacilityLabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '시설상태', '연도별', '권역', '단위유역', '중권역', '환경청별'];
// 리스트 헤더(행정별)
const upHeadList1:TableUpperProps[] = [
{ id: "A", title: "행정구역", colSpan:2, rowSpan:2, row:0 },
{ id: "ctpvNm", title: "시도", upName:"upChangeRe", row:2, widthPercent:4 },
{ id: "sggNm", title: "시군구", upName:"upChangeRe", row:2, widthPercent:4 },
{ id: "swtrmtFcltNm", title: "시설명", rowSpan:3, row:0, widthPercent: 6 },
{ id: "location", title: "주소", rowSpan:3, row:0, widthPercent: 12 },
{ id: "fctCpc", title: "시설용량(m³/일)", align:"right", rowSpan:3, row:0, widthPercent: 5 },
{ id: "B", title: "시설계획", colSpan:19, row: 0 },
{ id: "C", title: "증설계획(m³/일)", colSpan:6, row: 1 },
{ id: "planSwageQntSumDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "planSwageQntSum", title: "현재", row:2, align:"right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc1", title: "1단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc2", title: "2단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc3", title: "3단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc4", title: "4단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "D", title: "처리인구(인)", colSpan:6, row:1 },
{ id: "swtrmtPpltnCntDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCnt", title: "현재", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc1", title: "1단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc2", title: "2단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc3", title: "3단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc4", title: "4단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "E", title: "처리구역(km²)", colSpan:7, row:1 },
{ id: "swtrmtZoneAreaDt4", title: "기승인\n4단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtZoneArea", title: "현재", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc1", title: "1단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc2", title: "2단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc3", title: "3단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc4", title: "4단계", row:2, align:"right", widthPercent: 3.5 },
{ id: "trtDstr", title: "처리구역", row:2}
const upHeadList1: TableUpperProps[] = [
{ id: "A", title: "행정구역", colSpan: 2, rowSpan: 2, row: 0 },
{ id: "ctpvNm", title: "시도", upName: "upChangeRe", row: 2, widthPercent: 4 },
{ id: "sggNm", title: "시군구", upName: "upChangeRe", row: 2, widthPercent: 4 },
{ id: "swtrmtFcltNm", title: "시설명", rowSpan: 3, row: 0, widthPercent: 6 },
{ id: "location", title: "주소", rowSpan: 3, row: 0, widthPercent: 12 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 3, row: 0, widthPercent: 5 },
{ id: "B", title: "시설계획", colSpan: 18, row: 0 },
{ id: "C", title: "증설계획(m³/일)", colSpan: 6, row: 1 },
{ id: "planSwageQntSumDt4", title: "기승인\n4단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "planSwageQntSum", title: "현재", row: 2, align: "right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc1", title: "1단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc2", title: "2단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc3", title: "3단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "planSwageQntSumDc4", title: "4단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "D", title: "처리인구(인)", colSpan: 6, row: 1 },
{ id: "swtrmtPpltnCntDt4", title: "기승인\n4단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCnt", title: "현재", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc1", title: "1단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc2", title: "2단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc3", title: "3단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtPpltnCntDc4", title: "4단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "E", title: "처리구역(km²)", colSpan: 6, row: 1 },
{ id: "swtrmtZoneAreaDt4", title: "기승인\n4단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtZoneArea", title: "현재", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc1", title: "1단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc2", title: "2단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc3", title: "3단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "swtrmtZoneAreaDc4", title: "4단계", row: 2, align: "right", widthPercent: 3.5 },
{ id: "trtDstr", title: "처리구역", row: 0, rowSpan: 3 } // row - header에서 몇번째 행인지
];
const processAreaList:ProcessAreaProps[] = [
const processAreaList: ProcessAreaProps[] = [
]
/**
* 처리구역정보 상세팝업
*/
*/
// 시설증설 계획 (헤더)
const upHeadListFcltyImproveInfo:TableUpperProps[] = [
{ id: "planSwageQntSumDt4", title: "기승인\n4단계(m³/일)", rowSpan:2, row:0, align:"right"},
{ id: "A", title: "증설계획(m³/일)", colSpan:5, row:0},
{ id: "planSwageQntSum", title: "현재", row:1, align:"right"},
{ id: "planSwageQntSumDc1", title: "1단계", row:1, align:"right"},
{ id: "planSwageQntSumDc2", title: "2단계", row:1, align:"right"},
{ id: "planSwageQntSumDc3", title: "3단계", row:1, align:"right"},
{ id: "planSwageQntSumDc4", title: "4단계", row:1, align:"right"},
const upHeadListFcltyImproveInfo: TableUpperProps[] = [
{ id: "planSwageQntSumDt4", title: "기승인\n4단계(m³/일)", rowSpan: 2, row: 0, align: "right" },
{ id: "A", title: "증설계획(m³/일)", colSpan: 5, row: 0 },
{ id: "planSwageQntSum", title: "현재", row: 1, align: "right" },
{ id: "planSwageQntSumDc1", title: "1단계", row: 1, align: "right" },
{ id: "planSwageQntSumDc2", title: "2단계", row: 1, align: "right" },
{ id: "planSwageQntSumDc3", title: "3단계", row: 1, align: "right" },
{ id: "planSwageQntSumDc4", title: "4단계", row: 1, align: "right" },
];
// 시설증설 계획 (리스트)
const gridListFcltyImproveInfo:FcltyImproveInfoProps[] = [
const gridListFcltyImproveInfo: FcltyImproveInfoProps[] = [
];
// 처리인구 계획 (헤더)
const upHeadListProcessPopulation:TableUpperProps[] = [
{ id: "swtrmtPpltnCntDt4", title: "기승인\n4단계(인)", rowSpan:2, row:0, align:"right"},
{ id: "A", title: "처리인구(인)", colSpan:5, row:0},
{ id: "swtrmtPpltnCnt", title: "현재", row:1, align:"right"},
{ id: "swtrmtPpltnCntDc1", title: "1단계", row:1, align:"right"},
{ id: "swtrmtPpltnCntDc2", title: "2단계", row:1, align:"right"},
{ id: "swtrmtPpltnCntDc3", title: "3단계", row:1, align:"right"},
{ id: "swtrmtPpltnCntDc4", title: "4단계", row:1, align:"right"},
const upHeadListProcessPopulation: TableUpperProps[] = [
{ id: "swtrmtPpltnCntDt4", title: "기승인\n4단계(인)", rowSpan: 2, row: 0, align: "right" },
{ id: "A", title: "처리인구(인)", colSpan: 5, row: 0 },
{ id: "swtrmtPpltnCnt", title: "현재", row: 1, align: "right" },
{ id: "swtrmtPpltnCntDc1", title: "1단계", row: 1, align: "right" },
{ id: "swtrmtPpltnCntDc2", title: "2단계", row: 1, align: "right" },
{ id: "swtrmtPpltnCntDc3", title: "3단계", row: 1, align: "right" },
{ id: "swtrmtPpltnCntDc4", title: "4단계", row: 1, align: "right" },
];
// 처리인구 계획 (리스트)
const gridListProcessPopulation:ProcessPopulationProps[] = [
const gridListProcessPopulation: ProcessPopulationProps[] = [
];
// 처리구역 계획 (헤더)
const upHeadListProcessAreaPlan:TableUpperProps[] = [
{ id: "swtrmtZoneAreaDt4", title: "기승인\n4단계(km²)", rowSpan:2, row:0, align:"right"},
{ id: "A", title: "처리면적(km²)", colSpan:6, row:0, align:"right"},
{ id: "swtrmtZoneArea", title: "현재", row:1, align:"right"},
{ id: "swtrmtZoneAreaDc1", title: "1단계", row:1, align:"right"},
{ id: "swtrmtZoneAreaDc2", title: "2단계", row:1, align:"right"},
{ id: "swtrmtZoneAreaDc3", title: "3단계", row:1, align:"right"},
{ id: "swtrmtZoneAreaDc4", title: "4단계", row:1, align:"right"},
{ id: "trtDstr", title: "처리구역", row:1}
const upHeadListProcessAreaPlan: TableUpperProps[] = [
{ id: "swtrmtZoneAreaDt4", title: "기승인\n4단계(km²)", rowSpan: 2, row: 0, align: "right" },
{ id: "A", title: "처리면적(km²)", colSpan: 5, row: 0, align: "right" },
{ id: "swtrmtZoneArea", title: "현재", row: 1, align: "right" },
{ id: "swtrmtZoneAreaDc1", title: "1단계", row: 1, align: "right" },
{ id: "swtrmtZoneAreaDc2", title: "2단계", row: 1, align: "right" },
{ id: "swtrmtZoneAreaDc3", title: "3단계", row: 1, align: "right" },
{ id: "swtrmtZoneAreaDc4", title: "4단계", row: 1, align: "right" },
// { id: "trtDstr", title: "처리구역", row: 1 }
];
// 시설증설 계획 (리스트)
const gridListProcessAreaPlan:ProcessAreaPlanProps[] = [
const gridListProcessAreaPlan: ProcessAreaPlanProps[] = [
];
/**====================================
@@ -227,113 +227,115 @@ const gridListProcessAreaPlan:ProcessAreaPlanProps[] = [
}
}; */
const fetchFacilityDetailInfo = async (pageNo:number, pageSize:number, swtrmtFcltCd: string[]) : Promise<{data:any[], count:number}> => {
try {
const res = await postFetch('fo', '/prcsFclt/ruseInfo/'+pageNo+'/'+pageSize, swtrmtFcltCd);
return {data: res.data, count:res.count};
} catch (error) {
console.error('시설정보 데이터를 가져오는데 실패했습니다:', error);
return {data:[], count:0};
}
const fetchFacilityDetailInfo = async (pageNo: number, pageSize: number, swtrmtFcltCd: string[]): Promise<{ data: any[], count: number }> => {
try {
const res = await postFetch('fo', '/prcsFclt/ruseInfo/' + pageNo + '/' + pageSize, swtrmtFcltCd);
return { data: res.data, count: res.count };
} catch (error) {
console.error('시설정보 데이터를 가져오는데 실패했습니다:', error);
return { data: [], count: 0 };
}
};
// 시설정보 리스트 데이터 호출(구분 선택 후 시설명 있을 경우)
const fetchProcessAreaList = async (pageNo : number, pageSize : number, ctpvNm : string | undefined, sggNm : string | undefined, targetYear : string | undefined, set : (fn: (state: ProcessAreaType) => ProcessAreaType) => void): Promise<{data:any[], count:number}> => {
try {
const res = await fetchPlanInfo(targetYear, ctpvNm, sggNm, undefined);
if(res && res.length > 0){
const enrichedData = await Promise.all(
res.map(async (item: ProcessAreaProps) => {
upHeadList1.forEach((head:TableUpperProps) => {
/* if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재\n(' + item.planYr + '년)';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계\n(' + item.planYrDc1 + '년)';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = '2단계\n(' + item.planYrDc2 + '년)';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = '3단계\n(' + item.planYrDc3 + '년)';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = '4단계\n(' + item.planYrDc4 + '년)';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계(' + item.planYrDt4 + '년)';
} */
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = '2단계';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = '3단계';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = '4단계';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계';
}
});
return item;
const fetchProcessAreaList = async (pageNo: number, pageSize: number, ctpvNm: string | undefined, sggNm: string | undefined
, targetYear: string | undefined, set: (fn: (state: ProcessAreaType) => ProcessAreaType) => void): Promise<{ data: any[], count: number }> => {
try {
const res = await fetchPlanInfo(targetYear, ctpvNm, sggNm, undefined);
if (res && res.length > 0) {
const enrichedData = await Promise.all(
res.map(async (item: ProcessAreaProps) => {
upHeadList1.forEach((head: TableUpperProps) => {
/* if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재\n(' + item.planYr + '년)';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계\n(' + item.planYrDc1 + '년)';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = '2단계\n(' + item.planYrDc2 + '년)';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = '3단계\n(' + item.planYrDc3 + '년)';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = '4단계\n(' + item.planYrDc4 + '년)';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계(' + item.planYrDt4 + '년)';
} */
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = '현재';
} else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = '1단계';
} else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = '2단계';
} else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = '3단계';
} else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = '4단계';
} else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = '기승인\n4단계';
}
});
return item;
})
);
const startIndex = (pageNo - 1) * pageSize;
const endIndex = startIndex + pageSize;
const paginatedData = enrichedData.slice(startIndex, endIndex);
const fcltyCdList: string[] = [];
paginatedData.forEach(item => {
fcltyCdList.push(item.swtrmtFcltCd);
})
);
const startIndex = (pageNo - 1) * pageSize;
const endIndex = startIndex + pageSize;
const paginatedData = enrichedData.slice(startIndex, endIndex);
const fcltyCdList : string[]= [];
paginatedData.forEach(item => {
fcltyCdList.push(item.swtrmtFcltCd);
})
const detailFcltylist = await fetchFacilityDetailInfo(1, pageSize, fcltyCdList);
paginatedData.forEach(item => {
const filterdData = detailFcltylist.data.filter(fItem=>fItem.bscFctCd === item.swtrmtFcltCd)[0] || null;
item.fcltCpctSum = filterdData ? filterdData.fctCpc : '';
item.location = filterdData ? filterdData.addr : '';
item.ctpvNm = filterdData ? filterdData.sido : '';
item.sggNm = filterdData ? filterdData.gugun : '';
});
return {data: paginatedData, count: enrichedData.length};
}else{
return {data: [], count: 0};
}
} catch (error) {
console.error('시설계획정보를 가져오는데 실패했습니다:', error);
set((state) => ({
...state,
ProcessArea : {
...state.ProcessArea,
isLoading : false
const detailFcltylist = await fetchFacilityDetailInfo(1, pageSize, fcltyCdList);
paginatedData.forEach(item => {
const filterdData = detailFcltylist.data.filter(fItem => fItem.bscFctCd === item.swtrmtFcltCd)[0] || null;
item.fcltCpctSum = filterdData ? filterdData.fctCpc : '';
item.location = filterdData ? filterdData.addr : '';
item.ctpvNm = filterdData ? filterdData.sido : '';
item.sggNm = filterdData ? filterdData.gugun : '';
item.trtDstr = filterdData ? filterdData.trtDstr : '';
});
return { data: paginatedData, count: enrichedData.length };
} else {
return { data: [], count: 0 };
}
}));
return {data: [], count: 0};
}
} catch (error) {
console.error('시설계획정보를 가져오는데 실패했습니다:', error);
set((state) => ({
...state,
ProcessArea: {
...state.ProcessArea,
isLoading: false
}
}));
return { data: [], count: 0 };
}
};
/**====================================
* Store - expaort
=====================================*/
export type ProcessAreaActions = {
searchProcessAreaList : (pageNo: number, pageSize: number, ctpvNm?:string, sggNm?:string, targetYear?:string) => void;
initModalData : (swtrmtFcltCd:string) => void;
searchProcessAreaList: (pageNo: number, pageSize: number, ctpvNm?: string, sggNm?: string, targetYear?: string) => void;
initModalData: (swtrmtFcltCd: string) => void;
}
export type ProcessAreaType = {
ProcessAreaSearch: {
isInit: boolean;
processFacilityLabelArray:string[];
processFacilityLabelArray: string[];
},
ProcessArea : {
ProcessArea: {
isInit: boolean;
upHeadList1: TableUpperProps[];
processAreaList: ProcessAreaProps[];
processAreaCount: number;
excelList: ExcelType[];
isLoading: boolean;
},
},
ProcessAreaDetail : {
ProcessAreaDetail: {
isInit: boolean;
upHeadListFcltyImproveInfo: TableUpperProps[];
gridListFcltyImproveInfo: FcltyImproveInfoProps[]; // Changed from facilityAreaProps to ProcessAreaProps
@@ -350,23 +352,23 @@ export const processAreaInitState: ProcessAreaType = {
processFacilityLabelArray: ProcessFacilityLabelArray,
},
ProcessArea : {
isInit : false,
upHeadList1 : upHeadList1,
processAreaList : processAreaList,
processAreaCount : 0,
excelList : [],
isLoading : true,
ProcessArea: {
isInit: false,
upHeadList1: upHeadList1,
processAreaList: processAreaList,
processAreaCount: 0,
excelList: [],
isLoading: true,
},
ProcessAreaDetail : {
isInit : false,
upHeadListFcltyImproveInfo : upHeadListFcltyImproveInfo,
gridListFcltyImproveInfo : gridListFcltyImproveInfo,
upHeadListProcessPopulation : upHeadListProcessPopulation,
gridListProcessPopulation : gridListProcessPopulation,
upHeadListProcessAreaPlan : upHeadListProcessAreaPlan,
gridListProcessAreaPlan : gridListProcessAreaPlan,
ProcessAreaDetail: {
isInit: false,
upHeadListFcltyImproveInfo: upHeadListFcltyImproveInfo,
gridListFcltyImproveInfo: gridListFcltyImproveInfo,
upHeadListProcessPopulation: upHeadListProcessPopulation,
gridListProcessPopulation: gridListProcessPopulation,
upHeadListProcessAreaPlan: upHeadListProcessAreaPlan,
gridListProcessAreaPlan: gridListProcessAreaPlan,
},
}
@@ -375,14 +377,14 @@ type SetStateFunction = (state: ProcessAreaType | ((state: ProcessAreaType) => P
export type ProcessAreaStore = ProcessAreaType & ProcessAreaActions;
export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set: SetStateFunction) => {
export const processAreaReducer: (set: SetStateFunction) => ProcessAreaActions = (set: SetStateFunction) => {
return {
/**
* 시설정보 리스트 데이터 호출
* @param pageNo : 페이지 번호
* @param pageSize : 페이지 크기
*/
searchProcessAreaList: async ( pageNo:number, pageSize:number, ctpvNm?:string, sggNm?:string, targetYear?:string) => {
searchProcessAreaList: async (pageNo: number, pageSize: number, ctpvNm?: string, sggNm?: string, targetYear?: string) => {
set((state: ProcessAreaType) => ({
...state,
ProcessArea: {
@@ -391,12 +393,12 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set:
},
}));
const res = await fetchProcessAreaList(pageNo, pageSize, ctpvNm, sggNm, targetYear, set);
res.data.forEach((item:ProcessAreaProps) => {
res.data.forEach((item: ProcessAreaProps) => {
item.fctCpc = item.fcltCpctSum;
DataForm({ type: 'float1', column: 'fctCpc', item:item as unknown as Record<string, unknown>});
DataForm({ type: 'float1', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
})
const excelDownList: ExcelType[] = [];
if(pageSize>5000){
if (pageSize > 5000) {
res.data.forEach(item => {
item.fctCpc = item.fctCpc ? parseFloat(item.fctCpc.toString().replace(/,/g, '')) : '';
excelDownList.push({
@@ -425,78 +427,78 @@ export const processAreaReducer:(set:SetStateFunction)=>ProcessAreaActions=(set:
처리구역: item.trtDstr
});
});
}else{
} else {
res.data.forEach(item => {
item.fctCpc = item.fctCpc ? parseFloat(item.fctCpc.toString().replace(/,/g, '')) : '';
})
}
set((state:ProcessAreaType) => ({
set((state: ProcessAreaType) => ({
...state,
ProcessArea: pageSize<5000?{
ProcessArea: pageSize < 5000 ? {
...state.ProcessArea,
processAreaList: res.data,
processAreaCount: res.count,
isLoading : false,
}:{
isLoading: false,
} : {
...state.ProcessArea,
excelList: excelDownList,
isLoading : false,
isLoading: false,
},
}))
},
initModalData: async (swtrmtFcltCd:string) => {
initModalData: async (swtrmtFcltCd: string) => {
set((state: ProcessAreaType) => {
const rtnData = state.ProcessArea.processAreaList.find((item: ProcessAreaProps) => item.swtrmtFcltCd === swtrmtFcltCd);
if (rtnData) {
upHeadListFcltyImproveInfo.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.planYr? '현재\n(' + rtnData.planYr + '년)':head.title = '현재';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.planYrDc1? '1단계\n(' + rtnData.planYrDc1 + '년)':head.title = '1단계';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.planYrDc2? '2단계\n(' + rtnData.planYrDc2 + '년)':head.title = '2단계';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.planYrDc3? '3단계\n(' + rtnData.planYrDc3 + '년)':head.title = '3단계';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.planYrDc4? '4단계\n(' + rtnData.planYrDc4 + '년)':head.title = '4단계';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.planYrDt4? '기승인\n4단계(' + rtnData.planYrDt4 + '년)':head.title = '기승인\n4단계';
upHeadListFcltyImproveInfo.forEach((head: TableUpperProps) => {
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.planYr ? '현재\n(' + rtnData.planYr + '년)' : head.title = '현재';
} else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.planYrDc1 ? '1단계\n(' + rtnData.planYrDc1 + '년)' : head.title = '1단계';
} else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.planYrDc2 ? '2단계\n(' + rtnData.planYrDc2 + '년)' : head.title = '2단계';
} else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.planYrDc3 ? '3단계\n(' + rtnData.planYrDc3 + '년)' : head.title = '3단계';
} else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.planYrDc4 ? '4단계\n(' + rtnData.planYrDc4 + '년)' : head.title = '4단계';
} else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.planYrDt4 ? '기승인\n4단계(' + rtnData.planYrDt4 + '년)' : head.title = '기승인\n4단계';
}
});
upHeadListProcessAreaPlan.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.planYr? '현재\n(' + rtnData.planYr + '년)':head.title = '현재';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.planYrDc1?'1단계\n(' + rtnData.planYrDc1 + '년)':head.title = '1단계';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.planYrDc2?'2단계\n(' + rtnData.planYrDc2 + '년)':head.title = '2단계';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.planYrDc3? '3단계\n(' + rtnData.planYrDc3 + '년)':head.title = '3단계';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.planYrDc4?'4단계\n(' + rtnData.planYrDc4 + '년)':head.title = '4단계';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.planYrDt4?'기승인\n4단계(' + rtnData.planYrDt4 + '년)':head.title = '기승인\n4단계';
upHeadListProcessAreaPlan.forEach((head: TableUpperProps) => {
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.planYr ? '현재\n(' + rtnData.planYr + '년)' : head.title = '현재';
} else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.planYrDc1 ? '1단계\n(' + rtnData.planYrDc1 + '년)' : head.title = '1단계';
} else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.planYrDc2 ? '2단계\n(' + rtnData.planYrDc2 + '년)' : head.title = '2단계';
} else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.planYrDc3 ? '3단계\n(' + rtnData.planYrDc3 + '년)' : head.title = '3단계';
} else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.planYrDc4 ? '4단계\n(' + rtnData.planYrDc4 + '년)' : head.title = '4단계';
} else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.planYrDt4 ? '기승인\n4단계(' + rtnData.planYrDt4 + '년)' : head.title = '기승인\n4단계';
}
});
upHeadListProcessPopulation.forEach((head:TableUpperProps) => {
if(head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.planYr?'현재\n(' + rtnData.planYr + '년)':head.title = '현재';
} else if(head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.planYrDc1?'1단계\n(' + rtnData.planYrDc1 + '년)':head.title = '1단계';
} else if(head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.planYrDc2?'2단계\n(' + rtnData.planYrDc2 + '년)':head.title = '2단계';
} else if(head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.planYrDc3?'3단계\n(' + rtnData.planYrDc3 + '년)':head.title = '3단계';
} else if(head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.planYrDc4?'4단계\n(' + rtnData.planYrDc4 + '년)':head.title = '4단계';
} else if(head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.planYrDt4?'기승인\n4단계(' + rtnData.planYrDt4 + '년)':head.title = '기승인\n4단계';
upHeadListProcessPopulation.forEach((head: TableUpperProps) => {
if (head.id === 'planSwageQntSum' || head.id === 'swtrmtPpltnCnt' || head.id === 'swtrmtZoneArea') {
head.title = rtnData.planYr ? '현재\n(' + rtnData.planYr + '년)' : head.title = '현재';
} else if (head.id === 'planSwageQntSumDc1' || head.id === 'swtrmtPpltnCntDc1' || head.id === 'swtrmtZoneAreaDc1') {
head.title = rtnData.planYrDc1 ? '1단계\n(' + rtnData.planYrDc1 + '년)' : head.title = '1단계';
} else if (head.id === 'planSwageQntSumDc2' || head.id === 'swtrmtPpltnCntDc2' || head.id === 'swtrmtZoneAreaDc2') {
head.title = rtnData.planYrDc2 ? '2단계\n(' + rtnData.planYrDc2 + '년)' : head.title = '2단계';
} else if (head.id === 'planSwageQntSumDc3' || head.id === 'swtrmtPpltnCntDc3' || head.id === 'swtrmtZoneAreaDc3') {
head.title = rtnData.planYrDc3 ? '3단계\n(' + rtnData.planYrDc3 + '년)' : head.title = '3단계';
} else if (head.id === 'planSwageQntSumDc4' || head.id === 'swtrmtPpltnCntDc4' || head.id === 'swtrmtZoneAreaDc4') {
head.title = rtnData.planYrDc4 ? '4단계\n(' + rtnData.planYrDc4 + '년)' : head.title = '4단계';
} else if (head.id === 'planSwageQntSumDt4' || head.id === 'swtrmtPpltnCntDt4' || head.id === 'swtrmtZoneAreaDt4') {
head.title = rtnData.planYrDt4 ? '기승인\n4단계(' + rtnData.planYrDt4 + '년)' : head.title = '기승인\n4단계';
}
});
// 시설증설 계획 데이터 생성
const fcltyImproveInfo: FcltyImproveInfoProps = {
planSwageQntSumDt4: rtnData.planSwageQntSumDt4,
+26 -109
View File
@@ -29,7 +29,7 @@ export type SewageOccurProps = {
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,
@@ -39,6 +39,8 @@ export type SewageOccurDetailProps = {
sumWtrUsg: number, // 물사용량 합
avgWtrUsg: number, // 일평균 물사용량
monWtrUsg: number, // 월 물사용량
maxEstSewerage: number, // 최대 오수발생량 추정
minEstSewerage: number, // 최소 오수발생량 추정
}
export type WtrUsgYmProps = {
bscFctCd: string, // 처리구역시설코드
@@ -332,6 +334,7 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) =
// wtrUsgRes.data.forEach(fclt => {
// wtrUsgMap[fclt.bscFctCd] = fclt.wtrUsg;
// });
let maxEstimationSewage = 0, minEstimationSewage = 999999999;
for (const item of sewageOccurPropsList) {
const detailList = soccurDetailRes?.data[item.bscFctCd];
@@ -367,18 +370,16 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) =
// console.log("totWaterUsage:", totWaterUsage);
const count = detailList ? detailList.length : 0;
const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량
item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 일평균 유입량 * 65%
const avg = count == 0 ? 0 : totWaterUsage / count; // 연간 하수유입량(m³/일)
item.waterUsage = parseFloat((avg * 0.65).toFixed(2)); // 물사용량 = 연간 하수유입량(m³/일) * 65% : 실제 수용가의 물사용량 없는 경우
if (wtrUsgYearTotal > 0 && wtrUsgYearDays > 0) {
item.waterUsage = wtrUsgYearDays > 0 ? wtrUsgYearTotal / 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.estimationSewage = parseFloat((item.waterUsage * OSU_PERCENT).toFixed(2)); // 오수발생량 추정(m³/일)
if (item.bscFctCd === '11200PB001R') {
console.log('chungcunSumFlow:', chungcunSumFlow);
console.log('sumChungcunDay:', sumChungcunDay);
}
if (item.estimationSewage > maxEstimationSewage) maxEstimationSewage = item.estimationSewage;
if (item.estimationSewage < minEstimationSewage) minEstimationSewage = item.estimationSewage;
// 반올림 처리
["fctCpc", "waterUsage", "swageChangePercent", "estimationSewage", "sewageInputYear", "sewageInputChungchun"].forEach(
(key) => (item[key] = roundNumber(item[key], 0))
@@ -427,93 +428,11 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) =
}));
}
/* fetchSewageOccurList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm).then(async (res) => {
const excelDownList: ExcelType[] = [];
const data = res.data;
// Promise.all을 사용하여 모든 비동기 작업이 완료될 때까지 기다림
const calData = await Promise.all(data.map(async (item: SewageOccurProps) => {
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.swageChangePercent = 90;
const bscFctCd = item.bscFctCd;
const res2 = await getFetch('fo', '/fclt/flow/' + bscFctCd + '/' + searchYear) as FlowResponse;
let sumChungcunDay = 0;
let chungcunSumFlow = 0;
let totWaterUsage = 0;
// 강우영향일 계산 (강우량이 3 초과이면 무조건 강우영향일)
const rainEffectData = CalcRainEffect(res2.data);
rainEffectData.forEach((item: FlowDataItem) => {
if(Number(item.rainEffectDay) === 0){
chungcunSumFlow += Number(item.inflAmnt);
sumChungcunDay += 1;
}
totWaterUsage += Number(item.inflAmnt);
});
const avg = totWaterUsage /res2.count;
item.waterUsage = parseFloat((avg * 0.65).toFixed(2));
item.sewageInputYear = parseFloat(avg.toFixed(2));
item.sewageInputChungchun = parseFloat((chungcunSumFlow===0?0:(chungcunSumFlow / sumChungcunDay)).toFixed(2));
item.estimationSewage = parseFloat((item.waterUsage * (item.swageChangePercent/100)).toFixed(2));
return item;
}));
calData.forEach((item: SewageOccurProps) => {
DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'waterUsage', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'swageChangePercent', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'estimationSewage', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'sewageInputYear', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'sewageInputChungchun', item: item as unknown as Record<string, unknown> });
});
if(pageSize>5000){
calData.forEach((item: SewageOccurProps) => {
excelDownList.push({
시설코드: item.bscFctCd,
권역: item.rvbsn,
단위유역: item.lgbsn,
중권역: item.mdmbsn,
환경청: item.rgnNm,
시설명: item.bscFctNm,
시도: item.sidoNm,
시군구: item.sggNm,
주소: item.daddr,
"시설용량(m³/일)": item.fctCpc,
"물사용량(m³/일)": item.waterUsage,
"오수전환율(%)": item.swageChangePercent,
"오수발생량추정(m³/일)": item.estimationSewage,
"연간하수유입량(m³/일)": item.sewageInputYear,
"청천시하수유입량(m³/일)": item.sewageInputChungchun,
});
});
}
// 조회 데이터 설정
set((state: any) => ({
...state,
SewageOccur: pageSize<5000?{
...state.SewageOccur,
sewageOccurList: calData,
sewageOccurCount: res.count,
isLoading : false,
}:{
...state.SewageOccur,
excelList: excelDownList,
isLoading : false,
},
}))
}); */
},
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;
@@ -554,15 +473,15 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) =
} 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
, usage: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0, monWtrUsg: 0, maxEstSewerage: 0, minEstSewerage: 999999999
};
}
}
tot += Number(item.inflAmnt)
tot += Number(item.inflAmnt); // 연간 유입량
cnt++
});
// 물사용량
// 수용가 실제 물사용량
let totWtrUsg = 0;
let cntWtrUsg = 0;
if (wtrUsgRes && wtrUsgRes.data && wtrUsgRes.data[bscFctCd]) {
@@ -582,25 +501,23 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) =
const tableData: modalTableType[] = []
let maxWaterUsage = 0;
let minWaterUsage = 9999999999;
let maxWaterUsage = 0, minWaterUsage = 9999999999;
let maxEstSewage = 0, minEstSewage = 9999999999;
let avgWaterUsage = 0;
monthData.forEach((item, index) => {
item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 = 일평균유입수 * 0.65
if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg;
item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 = 일평균유입수 * 0.65 : 수용가 실제 물사용량이 없으면
if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; //수용가 실제 물사용량이 있는 경우
const estSewage = Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1; // 오수발생량 추정
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
swageChangePercent: OSU_PERCENT * 100, //오수전환율 (Math.round((item.usage/item.usage*OSU_PERCENT) * 100) / 100) * 100,
estimationSewage: estSewage,
})
if (item.avgWtrUsg > maxWaterUsage) {
maxWaterUsage = item.avgWtrUsg;
}
if (item.avgWtrUsg < minWaterUsage) {
minWaterUsage = item.avgWtrUsg;
}
if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg; // 물사용량 최대
if (item.avgWtrUsg < minWaterUsage) minWaterUsage = item.avgWtrUsg; // 물사용량 최소
if (maxEstSewage < estSewage) maxEstSewage = estSewage; // 오수발생량 최대
if (minEstSewage > estSewage) minEstSewage = estSewage; // 오수발생량 최소
});
avgWaterUsage = tot / cnt * 0.65
@@ -617,13 +534,13 @@ export const sewageOccurReducer: (set: any) => SewageOccurActions = (set: any) =
msrDt: '최대',
waterUsage: roundNumber(Math.round(maxWaterUsage * 100) / 100, 0),
swageChangePercent: OSU_PERCENT * 100,
estimationSewage: roundNumber(Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, 0),
estimationSewage: roundNumber(maxEstSewage / 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),
estimationSewage: roundNumber(minEstSewage / 1, 0),
},
...tableData
]
+21 -20
View File
@@ -42,8 +42,9 @@ import {
export type FoStore = CommonStore & tableType & DashBoardStore & ProcessFacilityStore & ProcessAreaStore & FlowRateSearchStore & FacilityPrecipitationStore & FacilityWaterQltyStore & PlanSewageStore & SewageOccurStore & UnderWaterStore & RdiStore;
export type FoState = CommonType & tableState & ProcessFacilityType & ProcessAreaType & FacilityPrecipitationType & FlowRateSearchType & DashBoardType & FacilityWaterQltyType & PlanSewageType & SewageOccurType & UnderWaterType & RdiType;
export const StoreZus =
(initState: FoState = { ...commonState,
export const StoreZus =
(initState: FoState = {
...commonState,
...tableStateExport
, ...processFacilityInitState
, ...processAreaInitState
@@ -57,22 +58,22 @@ export const StoreZus =
, ...rdiInitState
}
) => {
return createStore<FoStore>()((set) => {
return {
...initState,
...CommonReducer(set),
...tableActionsExport(set),
...dashBoardReducer(set),
...processFacilityReducer(set),
...processAreaReducer(set),
...facilityPrecipitationReducer(set),
...flowRateSearchReducer(set),
...facilityWaterQltyReducer(set),
...planSewageReducer(set),
...sewageOccurReducer(set),
...underWaterReducer(set),
...rdiReducer(set),
}
})
}
return createStore<FoStore>()((set, get) => {
return {
...initState,
...CommonReducer(set),
...tableActionsExport(set),
...dashBoardReducer(set, get),
...processFacilityReducer(set),
...processAreaReducer(set),
...facilityPrecipitationReducer(set),
...flowRateSearchReducer(set),
...facilityWaterQltyReducer(set),
...planSewageReducer(set),
...sewageOccurReducer(set),
...underWaterReducer(set),
...rdiReducer(set),
}
})
}
//store 등록하는 부분
+285 -300
View File
@@ -5,20 +5,21 @@ import type { ExcelType, UnderWaterInputModalProps, UnderWaterProps, WtrUsgYmPro
// import CalcRainEffect from "@/app/components/common/CalcRainEffect";
import { OSU_PERCENT } from "../common";
import { fetchFacilityListInit } from "../processFacility";
import { getDaysInMonth } from "@/app/components/common/DataForm";
export type { TableUpperProps };
// SewageOccurDetailProps 타입을 여기에 정의
export type SewageOccurDetailProps = {
cnt : number,
sum : number,
yr:string,
usage:number, // 일평균 유입량
sunnyCnt : number,
sunnyInflAmnt : number,
sunnyAvgInflAmnt : number, // 청천시 일평균 유입량
cntWtrUsg : number, // 물사용량 일자수
sumWtrUsg : number, // 물사용량 합
avgWtrUsg:number, // 일평균 물사용량
cnt: number,
sum: number,
yr: string,
usage: number, // 일평균 유입량
sunnyCnt: number,
sunnyInflAmnt: number,
sunnyAvgInflAmnt: number, // 청천시 일평균 유입량
cntWtrUsg: number, // 물사용량 일자수
sumWtrUsg: number, // 물사용량 합
avgWtrUsg: number, // 일평균 물사용량
}
/**====================================
* Store - 타입
@@ -35,145 +36,145 @@ export type SewageOccurDetailProps = {
/**
* (1) 메인페이지
*/
*/
// 검색단
const LabelArray:string[] = ['구분', '시도', '시군구','용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
const LabelArray: string[] = ['구분', '시도', '시군구', '용량별', '시설명', '조회기간', '시설상태', '권역', '단위유역', '중권역', '환경청별'];
// 리스트 헤더
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: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 8 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 8 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 8 },
{ id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 8 },
const 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: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 8 },
];
const upHeadList2:TableUpperProps[] = [
{ id: "A", title: "유역", row:0, colSpan:3 },
{ id: "rvbsn", title: "권역", row:1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", row:1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", row:1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row:0, rowSpan:2, widthPercent: 8 },
{ id: "daddr", title: "주소", row:0, rowSpan:2 },
{ id: "fctCpc", title: "시설용량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 8 },
{ id: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 8 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 8 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 8 },
{ id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 8 },
const upHeadList2: TableUpperProps[] = [
{ id: "A", title: "유역", row: 0, colSpan: 3 },
{ id: "rvbsn", title: "권역", row: 1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", row: 1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "daddr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 8 },
{ id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 8 },
];
const upHeadList3:TableUpperProps[] = [
{ id: "A", title: "유역", row:0, colSpan:3 },
{ id: "rvbsn", title: "권역", upName:"upChangeRe1", upSequnce:1, row:1, widthPercent: 5 },
{ id: "lgbsn", title: "단위유역", upName:"upChangeRe1", upSequnce:2, row:1, widthPercent: 5 },
{ id: "mdmbsn", title: "중권역", upName:"upChangeRe1", upSequnce:3, row:1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row:0, rowSpan:2, widthPercent: 8 },
{ id: "B", title: "행정구역", row:0, colSpan:2 },
{ id: "sidoNm", title: "시도", 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: "inflAmnt", title: "연평균유입하수량(m³/일)", align:"right", row:0, rowSpan:2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align:"right", row:0, colSpan:3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align:"right", row:1, widthPercent: 6},
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align:"right", row:1, widthPercent: 6 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align:"right", row:1, widthPercent: 6 },
{ id: "properYn", title: "적정여부", row:0, rowSpan:2, widthPercent: 6 },
const upHeadList3: TableUpperProps[] = [
{ id: "A", title: "유역", 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: "행정구역", 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: "inflAmnt", title: "연평균유입하수량(m³/일)", align: "right", row: 0, rowSpan: 2, widthPercent: 10 },
{ id: "C", title: "지하수 유입량 추정", align: "right", row: 0, colSpan: 3 },
{ id: "underWaterInputYear", title: "연간\n(m³/일)", align: "right", row: 1, widthPercent: 6 },
{ id: "underWaterInputSummer", title: "하절기\n(m³/일)", align: "right", row: 1, widthPercent: 6 },
{ id: "underWaterInputWinter", title: "동절기\n(m³/일)", align: "right", row: 1, widthPercent: 6 },
{ id: "properYn", title: "적정여부", row: 0, rowSpan: 2, widthPercent: 6 },
];
// 모달
const upHeadListUnderWaterDetail:TableUpperProps[] = [
const upHeadListUnderWaterDetail: TableUpperProps[] = [
{ id: "msrDt", title: "날짜" },
{ id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)", align:"right" },
{ id: "sewageOccur", title: "오수발생량\n(m³/일)", align:"right" },
{ id: "underWaterInput", title: "지하수 유입량\n(m³/일)", align:"right" },
{ id: "realSewageInput", title: "청천시 실제 하수유입량\n(m³/일)", align: "right" },
{ id: "sewageOccur", title: "오수발생량\n(m³/일)", align: "right" },
{ id: "underWaterInput", title: "지하수 유입량\n(m³/일)", align: "right" },
];
const underWaterList:UnderWaterProps[] = [
const underWaterList: UnderWaterProps[] = [
]
const underWaterDetailList:UnderWaterInputModalProps[] = [
const underWaterDetailList: UnderWaterInputModalProps[] = [
{
msrDt : "2024-01",
realSewageInput : 178007,
sewageOccur : 10.5,
underWaterInput : 80.6,
msrDt: "2024-01",
realSewageInput: 178007,
sewageOccur: 10.5,
underWaterInput: 80.6,
},
{
msrDt : "2024-02",
realSewageInput : 123007,
sewageOccur : 10.7,
underWaterInput : 80.6,
msrDt: "2024-02",
realSewageInput: 123007,
sewageOccur: 10.7,
underWaterInput: 80.6,
},
{
msrDt : "2024-03",
realSewageInput : 213007,
sewageOccur : 10.1,
underWaterInput : 80.6,
msrDt: "2024-03",
realSewageInput: 213007,
sewageOccur: 10.1,
underWaterInput: 80.6,
},
{
msrDt : "2024-04",
realSewageInput : 83007,
sewageOccur : 9.57,
underWaterInput : 80.6,
msrDt: "2024-04",
realSewageInput: 83007,
sewageOccur: 9.57,
underWaterInput: 80.6,
},
{
msrDt : "2024-05",
realSewageInput : 15007,
sewageOccur : 3.57,
underWaterInput : 80.6,
msrDt: "2024-05",
realSewageInput: 15007,
sewageOccur: 3.57,
underWaterInput: 80.6,
},
{
msrDt : "2024-06",
realSewageInput : 123007,
sewageOccur : '',
underWaterInput : 80.6,
msrDt: "2024-06",
realSewageInput: 123007,
sewageOccur: '',
underWaterInput: 80.6,
},
{
msrDt : "2024-07",
realSewageInput : 101007,
sewageOccur : 1,
underWaterInput : 80.6,
msrDt: "2024-07",
realSewageInput: 101007,
sewageOccur: 1,
underWaterInput: 80.6,
},
{
msrDt : "2024-08",
realSewageInput : 103807,
sewageOccur : 10.57,
underWaterInput : '',
msrDt: "2024-08",
realSewageInput: 103807,
sewageOccur: 10.57,
underWaterInput: '',
},
{
msrDt : "2024-09",
realSewageInput : 9007,
sewageOccur : 10.57,
underWaterInput : 80.6,
msrDt: "2024-09",
realSewageInput: 9007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
{
msrDt : "2024-10",
realSewageInput : 163007,
sewageOccur : 10.57,
underWaterInput : 80.6,
msrDt: "2024-10",
realSewageInput: 163007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
{
msrDt : "2024-11",
realSewageInput : 123007,
sewageOccur : 10.57,
underWaterInput : 80.6,
msrDt: "2024-11",
realSewageInput: 123007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
{
msrDt : "2024-12",
realSewageInput : 1007,
sewageOccur : 10.57,
underWaterInput : 80.6,
msrDt: "2024-12",
realSewageInput: 1007,
sewageOccur: 10.57,
underWaterInput: 80.6,
},
]
/**====================================
@@ -185,8 +186,8 @@ export interface FlowDataItem {
inflAmnt: number | string;
infoRnDay: number;
msrDt: string;
rainEffectDay? : number;
sumFlow? : number | string | '';
rainEffectDay?: number;
sumFlow?: number | string | '';
}
export interface ApiResponse {
@@ -216,9 +217,9 @@ const fetchUnderWaterList = async (pageNo: number, pageSize: number, searchYear:
// }
// 시설들 유량 정보 조회
export const fetchDetailListFlow = async (searchYear: string|undefined, fcltCdList: string[]): Promise<UnderWaterProps | null> => {
export const fetchDetailListFlow = async (searchYear: string | undefined, fcltCdList: string[]): Promise<UnderWaterProps | null> => {
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);
@@ -226,9 +227,9 @@ export const fetchDetailListFlow = async (searchYear: string|undefined, fcltCdLi
}
};
// 시설들 월별 물사용량 정보 조회
export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList: string[]): Promise<WtrUsgYmProps | null> => {
export const fetchWtrUsgYmList = async (searchYear: string | undefined, fcltCdList: string[]): Promise<WtrUsgYmProps | null> => {
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);
@@ -241,16 +242,16 @@ export const fetchWtrUsgYmList = async (searchYear: string|undefined, fcltCdList
====================================*/
export type UnderWaterActions = {
searchUnderWaterList: (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => void;
unserWaterModal:(bscFctCd:string, searchYear:string, startYm:string, endYm:string)=>void
underWaterModal: (bscFctCd: string, searchYear: string, startYm: string, endYm: string) => void
}
export type UnderWaterType = {
UnderWaterSearch: {
isInit: boolean;
labelArray:string[];
labelArray: string[];
},
UnderWater : {
UnderWater: {
isInit: boolean;
upHeadList1: TableUpperProps[];
upHeadList2: TableUpperProps[];
@@ -261,7 +262,7 @@ export type UnderWaterType = {
isLoading: boolean;
},
UnderWaterDetail : {
UnderWaterDetail: {
isInit: boolean;
upHeadListUnderWaterDetail: TableUpperProps[];
gridListUnderWaterDetail: UnderWaterInputModalProps[];
@@ -274,30 +275,30 @@ export const underWaterInitState: UnderWaterType = {
labelArray: LabelArray,
},
UnderWater : {
isInit : false,
upHeadList1 : upHeadList1,
upHeadList2 : upHeadList2,
upHeadList3 : upHeadList3,
underWaterList : underWaterList,
underWaterCount : 4,
excelList : [],
isLoading : true,
UnderWater: {
isInit: false,
upHeadList1: upHeadList1,
upHeadList2: upHeadList2,
upHeadList3: upHeadList3,
underWaterList: underWaterList,
underWaterCount: 4,
excelList: [],
isLoading: true,
},
UnderWaterDetail : {
UnderWaterDetail: {
isInit: false,
upHeadListUnderWaterDetail: upHeadListUnderWaterDetail,
gridListUnderWaterDetail: underWaterDetailList,
}
}
const dataFormSetting=(item : UnderWaterProps)=> {
const dataFormSetting = (item: UnderWaterProps) => {
DataForm({ type: 'float0', column: 'fctCpc', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'inflAmnt', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'underWaterInputYear', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'underWaterInputSummer', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'underWaterInputWinter', item: item as unknown as Record<string, unknown>});
DataForm({ type: 'float0', column: 'underWaterInputYear', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'underWaterInputSummer', item: item as unknown as Record<string, unknown> });
DataForm({ type: 'float0', column: 'underWaterInputWinter', item: item as unknown as Record<string, unknown> });
}
// 병렬 처리 제한용 헬퍼
@@ -310,47 +311,26 @@ const dataFormSetting=(item : UnderWaterProps)=> {
// }
// return results;
// }
/**
* yyyymm 형태의 문자열을 받아 해당 월의 일수를 반환
* @param {string} yyyymm - 예: "202502", "202412"
* @returns {number} 해당 월의 일수 (예: 28, 29, 30, 31)
*/
function getDaysInMonth(yyyymm) {
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
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();
}
export type UnderWaterStore = UnderWaterType & UnderWaterActions;
export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterType) => void)=>UnderWaterActions=(set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => {
export const underWaterReducer: (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => UnderWaterActions = (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => {
return {
searchUnderWaterList: 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: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
underWaterList : facilityInitData.data,
underWaterCount : facilityInitData.count,
isInit : true,
underWaterList: facilityInitData.data,
underWaterCount: facilityInitData.count,
isInit: true,
isLoading: true,
},
}));
}else{
} else {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
@@ -359,43 +339,43 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
},
}));
}
const fcltylist = facilityInitData.data;
const fcltCdList : string[] = []; // 시설코드목록
const underWaterPropsList : UnderWaterProps[] = []; // 오수발생량시설목록
const fcltCdList: string[] = []; // 시설코드목록
const underWaterPropsList: UnderWaterProps[] = []; // 오수발생량시설목록
fcltylist.forEach(item => {
fcltCdList.push(item.bscFctCd);
underWaterPropsList.push({
bscFctCd : item.bscFctCd,
sidoNm : item.sido,
sggNm : item.gugun,
lclgvrnmntNm : '',
bscFctNm : item.bscFctNm,
daddr : item.daddr,
fctCpc : parseFloat(item.fctCpc.toString().replace(/,/g, '')),
inflAmnt : 0,
waterUsage : 0,
underWaterInputYear : 0,
underWaterInputSummer : 0,
underWaterInputWinter : 0,
properYn : '',
infoRnDay : 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, '')),
inflAmnt: 0,
waterUsage: 0,
underWaterInputYear: 0,
underWaterInputSummer: 0,
underWaterInputWinter: 0,
properYn: '',
infoRnDay: 0,
rgnNm: item.rgnNm,
rvbsn: item.rvbsn,
lgbsn: item.lgbsn,
mdmbsn: item.mdmbsn,
msrDt: '',
});
});
const soccurDetailRes : any = await fetchDetailListFlow(searchYear, fcltCdList);
const wtrUsgYmRes : any = await fetchWtrUsgYmList(searchYear, fcltCdList);
const soccurDetailRes: any = await fetchDetailListFlow(searchYear, fcltCdList);
const wtrUsgYmRes: any = await fetchWtrUsgYmList(searchYear, fcltCdList);
for (const item of underWaterPropsList) {
const detailList = soccurDetailRes?.data[item.bscFctCd];
const wtrUsgYmList = wtrUsgYmRes?.data[item.bscFctCd];
let chungcunSumFlow = 0; // 청천유입량
let sumChungcunDay = 0; // 청천일수
let sumSummerChungcunDay = 0; // 하절기 청천일수
@@ -407,39 +387,39 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
let totWinterUsage = 0; // 동절기 하수유입량
let totSummerDays = 0; // 하절기 일수
let totWinterDays = 0; // 동절기 일수
const summerMonth = ['06', '07', '08'];
const winterMonth = ['01', '02'];
let rainEffectDay = 0;
detailList?.forEach(item2 => {
if (item2.infoRnDay == null || item2.infoRnDay.trim() == 'x') item2.infoRnDay = 0;
if(Number(item2.infoRnDay) >= 3) {
if (Number(item2.infoRnDay) >= 3) {
rainEffectDay = 2;
}else{
} else {
rainEffectDay--;
}
if(rainEffectDay<0){ //청천시
if (rainEffectDay < 0) { //청천시
chungcunSumFlow += Number(item2.inflAmnt);
sumChungcunDay += 1;
if(item2.msrDt.substring(4,6) ==='06' || item2.msrDt.substring(4,6) ==='07' || item2.msrDt.substring(4,6) ==='08'){
if (item2.msrDt.substring(4, 6) === '06' || item2.msrDt.substring(4, 6) === '07' || item2.msrDt.substring(4, 6) === '08') {
// 하절기 6,7,8월
sumSummerChungcunDay += 1;
sumSummerChungcunFlow += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}else if(item2.msrDt.substring(4,6) ==='01' || item2.msrDt.substring(4,6) ==='02'){
} else if (item2.msrDt.substring(4, 6) === '01' || item2.msrDt.substring(4, 6) === '02') {
// 동절기 1,2월
sumWinterChungcunDay += 1;
sumWinterChungcunFlow += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
}
totWaterUsage += Number(item2.inflAmnt);
if(item2.msrDt.substring(4,6) ==='06' || item2.msrDt.substring(4,6) ==='07' || item2.msrDt.substring(4,6) ==='08'){
if (item2.msrDt.substring(4, 6) === '06' || item2.msrDt.substring(4, 6) === '07' || item2.msrDt.substring(4, 6) === '08') {
// 하절기 6,7,8월
totSummerDays += 1;
totSummerUsage += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}else if(item2.msrDt.substring(4,6) ==='01' || item2.msrDt.substring(4,6) ==='02'){
} else if (item2.msrDt.substring(4, 6) === '01' || item2.msrDt.substring(4, 6) === '02') {
// 동절기 1,2월
totWinterDays += 1;
totWinterUsage += Number(item2.inflAmnt); //item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
@@ -447,8 +427,8 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
});
const count = detailList ? detailList.length : 0;
const avg = count == 0 ? 0 : totWaterUsage / count; // 일평균 유입량
const avg = count == 0 ? 0 : totWaterUsage / count; // 연간 일평균 유입량
let wtrUsgYearTotal = 0; // 연간 물사용량
let summerWtrUsgTot = 0; // 하절기 물사용량
let winterWtrUsgTot = 0; // 동절기 물사용량
@@ -459,52 +439,52 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
const days = getDaysInMonth(item3.levyYm);
wtrUsgYearTotal += Number(item3.wtrUsg);
wtrUsgYearDays += days;
if(summerMonth.includes(item3.levyYm.slice(-2))){
if (summerMonth.includes(item3.levyYm.slice(-2))) {
summerWtrUsgTot += Number(item3.wtrUsg);
summerWtrUsgDays += days;
}else if(winterMonth.includes(item3.levyYm.slice(-2))){
} else if (winterMonth.includes(item3.levyYm.slice(-2))) {
winterWtrUsgTot += Number(item3.wtrUsg);
winterWtrUsgDays += days;
}
});
if (wtrUsgYearTotal > 0) { // 물사용량이 있는 경우
const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0; // 청천시 일평균 유입량
const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; // 하절기 청천시 일평균 유입량
const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; // 동절기 청천시 일평균 유입량
const wtrUsg = wtrUsgYearDays>0? wtrUsgYearTotal / wtrUsgYearDays: 0; // 일평균 물사용량
const summerWtrUsg = summerWtrUsgTot?summerWtrUsgTot / summerWtrUsgDays:0; // 하절기 일평균 물사용량
const winterWtrUsg = winterWtrUsgTot?winterWtrUsgTot / winterWtrUsgDays:0; // 동절기 일평균 물사용량
const usage = chungcunSumFlow && chungcunSumFlow > 0 ? chungcunSumFlow / sumChungcunDay : 0; // 청천시 일평균 유입량
const summerUsage = sumSummerChungcunFlow ? sumSummerChungcunFlow / sumSummerChungcunDay : 0; // 하절기 청천시 일평균 유입량
const winterUsage = sumWinterChungcunFlow ? sumWinterChungcunFlow / sumWinterChungcunDay : 0; // 동절기 청천시 일평균 유입량
const wtrUsg = wtrUsgYearDays > 0 ? wtrUsgYearTotal / wtrUsgYearDays : 0; // 일평균 물사용량
const summerWtrUsg = summerWtrUsgTot ? summerWtrUsgTot / summerWtrUsgDays : 0; // 하절기 일평균 물사용량
const winterWtrUsg = winterWtrUsgTot ? winterWtrUsgTot / winterWtrUsgDays : 0; // 동절기 일평균 물사용량
item.inflAmnt = roundNumber(avg, 0);
item.underWaterInputYear = Math.round((usage-(wtrUsg*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputSummer = Math.round((summerUsage-(summerWtrUsg*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일)
item.underWaterInputWinter = Math.round((winterUsage-(winterWtrUsg*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일)
item.properYn = Math.round( (Number(usage-(wtrUsg*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부
item.underWaterInputYear = Math.round((usage - (wtrUsg * OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputSummer = Math.round((summerUsage - (summerWtrUsg * OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일)
item.underWaterInputWinter = Math.round((winterUsage - (winterWtrUsg * OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일)
item.properYn = Math.round((Number(usage - (wtrUsg * OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1) / 1 > 20 ? '초과유입' : '적정'; // 적정여부
} else { // 물사용량이 없는 경우, 일평균 유입량으로 물사용량 추정(물사용량 = 유입량*0.65)
const usage = chungcunSumFlow&&chungcunSumFlow>0?chungcunSumFlow / sumChungcunDay:0; // 청천시 일평균 유입량
const summerUsage = sumSummerChungcunFlow?sumSummerChungcunFlow / sumSummerChungcunDay:0; // 하절기 청천시 일평균 유입량
const winterUsage = sumWinterChungcunFlow?sumWinterChungcunFlow / sumWinterChungcunDay:0; // 동절기 청천시 일평균 유입량
const usage = chungcunSumFlow && chungcunSumFlow > 0 ? chungcunSumFlow / sumChungcunDay : 0; // 청천시 일평균 유입량
const summerUsage = sumSummerChungcunFlow ? sumSummerChungcunFlow / sumSummerChungcunDay : 0; // 하절기 청천시 일평균 유입량
const winterUsage = sumWinterChungcunFlow ? sumWinterChungcunFlow / sumWinterChungcunDay : 0; // 동절기 청천시 일평균 유입량
const wtrUsg = avg * 0.65; // 일평균 물사용량
const summerWtrUsg = totSummerDays>0? (totSummerUsage / totSummerDays)*0.65:0; // 하절기 일평균 물사용량
const winterWtrUsg = totWinterDays>0? (totWinterUsage / totWinterDays)*0.65:0; // 동절기 일평균 물사용량
const summerWtrUsg = totSummerDays > 0 ? (totSummerUsage / totSummerDays) * 0.65 : 0; // 하절기 일평균 물사용량
const winterWtrUsg = totWinterDays > 0 ? (totWinterUsage / totWinterDays) * 0.65 : 0; // 동절기 일평균 물사용량
item.inflAmnt = roundNumber(avg, 0);
//item.underWaterInputYear = Math.round((usage-(usage*0.65*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일)
item.underWaterInputYear = Math.round((usage-(wtrUsg*OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputSummer = Math.round((summerUsage-(summerWtrUsg*OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputWinter = Math.round((winterUsage-(winterWtrUsg*OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.properYn = Math.round( (Number(usage-(wtrUsg*OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1 ) / 1 > 20?'초과유입':'적정'; // 적정여부
// 반올림 처리
// ["fctCpc", "inflAmnt", "underWaterInputYear", "underWaterInputSummer", "underWaterInputWinter"].forEach(
// (key) => (item[key] = roundNumber(item[key], 0))
// );
item.underWaterInputYear = Math.round((usage - (wtrUsg * OSU_PERCENT)) * 1) / 1; // 연간지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputSummer = Math.round((summerUsage - (summerWtrUsg * OSU_PERCENT)) * 1) / 1; // 하절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.underWaterInputWinter = Math.round((winterUsage - (winterWtrUsg * OSU_PERCENT)) * 1) / 1; // 동절기지하수유입량(m³/일) = 청천시 실제유입량 - (물사용량 × 오수전환율)
item.properYn = Math.round((Number(usage - (wtrUsg * OSU_PERCENT)) / Number(item.inflAmnt)) * 100 * 1) / 1 > 20 ? '초과유입' : '적정'; // 적정여부
// 반올림 처리
// ["fctCpc", "inflAmnt", "underWaterInputYear", "underWaterInputSummer", "underWaterInputWinter"].forEach(
// (key) => (item[key] = roundNumber(item[key], 0))
// );
}
}
if(pageSize>= 5000){
if (pageSize >= 5000) {
const excelDownList: ExcelType[] = [];
underWaterPropsList.forEach((item : any) => {
underWaterPropsList.forEach((item: any) => {
dataFormSetting(item)
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
excelDownList.push({
@@ -530,10 +510,10 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
UnderWater: {
...state.UnderWater,
excelList: excelDownList,
isLoading : false,
isLoading: false,
},
}));
}else{
} else {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
@@ -541,21 +521,21 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
underWaterList: underWaterPropsList,
underWaterCount: facilityInitData.count,
excelList: [],
isLoading : false,
isLoading: false,
},
}));
}
},
unserWaterModal:async (bscFctCd, searchYear, startYm, endYm)=>{
underWaterModal: async (bscFctCd, searchYear, startYm, endYm) => {
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 sunnyTot = 0, sunnyCnt = 0;
if(startYm) {
if (startYm) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month >= startYm;
@@ -567,7 +547,7 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
});
}
}
if(endYm) {
if (endYm) {
res.data = res.data.filter((item: FlowDataItem) => {
const month = item.msrDt?.substring(0, 6);
return month <= endYm;
@@ -582,36 +562,40 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
let rainEffectDay = 0;
res.data?.forEach(item2 => {
if (item2.infoRnDay == null || item2.infoRnDay.trim() == 'x') item2.infoRnDay = 0;
if(Number(item2.infoRnDay) >= 3) {
if (Number(item2.infoRnDay) >= 3) {
rainEffectDay = 2;
}else{
} else {
rainEffectDay--;
}
const month = item2.msrDt?.substring(4, 6);
const monthIdx = month ? Number(month) - 1 : -1;
if (monthIdx >= 0 && (monthIdx>=Number(startYm.substring(4,6))-1 && monthIdx <= Number(endYm.substring(4, 6))-1)) {
if (monthIdx >= 0 && (monthIdx >= Number(startYm.substring(4, 6)) - 1 && monthIdx <= Number(endYm.substring(4, 6)) - 1)) {
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sum += Number(item2.inflAmnt); // 유입량 합
monthData[monthIdx].cnt++;
} else {
monthData[monthIdx] = {cnt:1, sum:Number(item2.inflAmnt), yr:item2.msrDt.substring(0,4)
, usage:0, sunnyCnt:0, sunnyInflAmnt:0, sunnyAvgInflAmnt: 0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0};
monthData[monthIdx] = {
cnt: 1, sum: Number(item2.inflAmnt), yr: item2.msrDt.substring(0, 4)
, usage: 0, sunnyCnt: 0, sunnyInflAmnt: 0, sunnyAvgInflAmnt: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0
};
}
}
if(month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)){
}
if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)) {
cnt++;
tot += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
if(rainEffectDay<0) { // 청천시
if (rainEffectDay < 0) { // 청천시
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sunnyInflAmnt += Number(item2.inflAmnt); // 청천 유입량 합
monthData[monthIdx].sunnyCnt++;
}else {
monthData[monthIdx] = {cnt:1, sum:Number(item2.inflAmnt), yr:item2.msrDt.substring(0,4)
, usage:0, sunnyCnt:0, sunnyInflAmnt:0, sunnyAvgInflAmnt: 0, cntWtrUsg:0, sumWtrUsg:0, avgWtrUsg:0};
} else {
monthData[monthIdx] = {
cnt: 1, sum: Number(item2.inflAmnt), yr: item2.msrDt.substring(0, 4)
, usage: 0, sunnyCnt: 0, sunnyInflAmnt: 0, sunnyAvgInflAmnt: 0, cntWtrUsg: 0, sumWtrUsg: 0, avgWtrUsg: 0
};
}
if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)){
if (month >= startYm.substring(4, 6) && month <= endYm.substring(4, 6)) {
sunnyCnt++;
sunnyTot += item2.inflAmnt && item2.inflAmnt !== 'x' ? Number(item2.inflAmnt.toString().trim()) : 0;
}
@@ -630,75 +614,76 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
if (typeof monthData[monthIdx] === 'object') {
monthData[monthIdx].sumWtrUsg += Number(item.wtrUsg);
monthData[monthIdx].cntWtrUsg += days;
}
}
}
totWtrUsg += Number(item.wtrUsg);
cntWtrUsg += days;
});
}
const tableData:UnderWaterInputModalProps[] = []
let maxWaterUsage = 0;
let minWaterUsage = 9999999999;
let avgWaterUsage = 0;
let maxSunnyInflAmnt = 0;
let minSunnyInflAmnt = 9999999999;
let avgSunnyInflAmnt = 0;
const tableData: UnderWaterInputModalProps[] = []
let maxWaterUsage = 0, minWaterUsage = 9999999999, avgWaterUsage = 0; // 물사용량
let maxSunnyInflAmnt = 0, minSunnyInflAmnt = 9999999999, avgSunnyInflAmnt = 0; // 청천 유입량
let maxUnderWaterInput = 0, minUnderWaterInput = 9999999999; // 지하수 유입량
monthData.forEach((item, index) => {
item.usage = item.sum/item.cnt; // 일평균 유입량
item.avgWtrUsg = item.sum/item.cnt * 0.65; // 일평균 물사용량
if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg; // 일평균 물사용량
item.usage = item.sum / item.cnt; // 일평균 유입량
item.avgWtrUsg = item.sum / item.cnt * 0.65; // 일평균 물사용량 : 수용가 물사용량이 없는 경우
// 일평균 물사용량 : 수용가 물사용량이 있는 경우
if (item.sumWtrUsg > 0 && item.cntWtrUsg > 0) item.avgWtrUsg = item.sumWtrUsg / item.cntWtrUsg;
item.sunnyAvgInflAmnt = item.sunnyInflAmnt / item.sunnyCnt; // 청천 일평균 유입량
const underWtrInput = Math.round((item.sunnyAvgInflAmnt - (item.avgWtrUsg * OSU_PERCENT)) * 1) / 1; // 지하수 유입량 평균
tableData.push({
msrDt: item.yr+'-'+(index+1>=10?String(index+1):'0'+(index+1)),
realSewageInput:Math.round(item.sunnyAvgInflAmnt*1) /1, // 청천 실제 하수유입량
sewageOccur:Math.round(item.avgWtrUsg*OSU_PERCENT * 1) / 1,// 오수발생량
underWaterInput:Math.round((item.sunnyAvgInflAmnt-(item.avgWtrUsg*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
msrDt: item.yr + '-' + (index + 1 >= 10 ? String(index + 1) : '0' + (index + 1)),
realSewageInput: Math.round(item.sunnyAvgInflAmnt * 1) / 1, // 청천 실제 하수유입량
sewageOccur: Math.round(item.avgWtrUsg * OSU_PERCENT * 1) / 1,// 오수발생량
underWaterInput: underWtrInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
})
if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg;
if (item.avgWtrUsg > maxWaterUsage) maxWaterUsage = item.avgWtrUsg;
if (item.sunnyAvgInflAmnt > maxSunnyInflAmnt) maxSunnyInflAmnt = item.sunnyAvgInflAmnt;
if (item.avgWtrUsg < minWaterUsage) minWaterUsage = item.avgWtrUsg;
if (item.sunnyAvgInflAmnt < minSunnyInflAmnt) minSunnyInflAmnt = item.sunnyAvgInflAmnt;
if (underWtrInput > maxUnderWaterInput) maxUnderWaterInput = underWtrInput;
if (underWtrInput < minUnderWaterInput) minUnderWaterInput = underWtrInput;
});
if(monthData.length == 0){
maxWaterUsage = 0; minWaterUsage = 0; avgWaterUsage = 0;
if (monthData.length == 0) {
maxWaterUsage = 0; minWaterUsage = 0; avgWaterUsage = 0;
maxSunnyInflAmnt = 0; minSunnyInflAmnt = 0; avgSunnyInflAmnt = 0;
}
avgWaterUsage = cnt>0? tot/cnt * 0.65:0; // 일평균 물사용량
if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; // 일평균 물사용량
avgSunnyInflAmnt = (sunnyCnt>0)?sunnyTot/sunnyCnt:0; // 청천 일평균 유입량
const newData= [
{
msrDt: '평균',
realSewageInput:Math.round(avgSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량
sewageOccur:Math.round(avgWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((avgSunnyInflAmnt-(avgWaterUsage*OSU_PERCENT)) * 1) / 1 // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
//underWaterInput:Math.round((avgWaterUsage-(avgWaterUsage*0.65*0.8)) * 100) / 100,
},
{
msrDt: '최대',
realSewageInput: Math.round(maxSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량
sewageOccur: Math.round(maxWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((maxSunnyInflAmnt-(maxWaterUsage*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
{
msrDt: '최소',
realSewageInput: Math.round(minSunnyInflAmnt*1) /1, // 청천시 실제 하수유입량
sewageOccur: Math.round(minWaterUsage*OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((minSunnyInflAmnt-(minWaterUsage*OSU_PERCENT)) * 1) / 1, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
...tableData
avgWaterUsage = cnt > 0 ? tot / cnt * 0.65 : 0; // 일평균 물사용량
if (totWtrUsg > 0 && cntWtrUsg > 0) avgWaterUsage = totWtrUsg / cntWtrUsg; // 일평균 물사용량
avgSunnyInflAmnt = (sunnyCnt > 0) ? sunnyTot / sunnyCnt : 0; // 청천 일평균 유입량
const newData = [
{
msrDt: '평균',
realSewageInput: Math.round(avgSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량
sewageOccur: Math.round(avgWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: Math.round((avgSunnyInflAmnt - (avgWaterUsage * OSU_PERCENT)) * 1) / 1 // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
//underWaterInput:Math.round((avgWaterUsage-(avgWaterUsage*0.65*0.8)) * 100) / 100,
},
{
msrDt: '최대',
realSewageInput: Math.round(maxSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량
sewageOccur: Math.round(maxWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: maxUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
{
msrDt: '최소',
realSewageInput: Math.round(minSunnyInflAmnt * 1) / 1, // 청천시 실제 하수유입량
sewageOccur: Math.round(minWaterUsage * OSU_PERCENT * 1) / 1, // 오수발생량
underWaterInput: minUnderWaterInput, // 지하수 유입량 : 하수처리장 청천시 실제유입량 - (물사용량 × 오수전환율)
},
...tableData
]
set((state: UnderWaterType) => ({
...state,
UnderWaterDetail: {
...state.UnderWaterDetail,
gridListUnderWaterDetail:newData
gridListUnderWaterDetail: newData
}
}))
}
@@ -125,91 +125,91 @@ const SearchModal: React.FC = () => {
{/* 📋 결과 리스트 */}
{/* 기본정보 탭 */}
{activeTab === 'basic' && (
<div className="h-[79vh] w-full overflow-x-hidden overflow-y-auto rounded-lg border mt-4">
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isLoading} />
<UiTable
headName={(() => {
const label = BASIC_TYPES.find((type) => type.val === basicType)?.text
return (<>{label} 조회 결과 ({tableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={tableData}
headlist={dynamicHeadlist}
pageSize={10}
total={tableCount}
cellClick={handleBasicCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
curPage={curPage}
headButton={
<div className='flex'>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium primary" size="sm" onClick={viewMultipleFeature}>지도에서 보기</Button>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium green" size="sm" onClick={basicExcelDownload}>파일 다운로드</Button>
</div>
}
/>
</div>
<div className="h-[79dvh] w-full rounded-lg border mt-4">
{/* <div className="flex-1 px-2 pb-2"> */}
<LoadingOverlay isLoading={isLoading} />
<UiTable
headName={(() => {
const label = BASIC_TYPES.find((type) => type.val === basicType)?.text
return (<>{label} 조회 결과 ({tableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={tableData}
headlist={dynamicHeadlist}
pageSize={10}
total={tableCount}
cellClick={handleBasicCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
curPage={curPage}
headButton={
<div className='flex'>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium primary" size="sm" onClick={viewMultipleFeature}>지도에서 보기</Button>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium green" size="sm" onClick={basicExcelDownload}>파일 다운로드</Button>
</div>
}
/>
{/* </div> */}
</div>
)}
{/* 유지관리 정보 탭 */}
{activeTab === 'operation' && (
<>
<div className="h-[39vh] w-full overflow-hidden rounded-lg border mt-4">
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isLoading} />
<UiTable
headName={
(() => {
const label = WORK_TYPES.find((type) => type.val === workType)?.text
return (<>{label} 사업 현황 ({tableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={tableData}
headlist={dynamicHeadlist}
pageSize={OPERATION_TABLE_SIZE}
total={tableCount}
cellClick={handleOperationCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
curPage={curPage}
headButton={
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-sm font-medium green" size="sm" onClick={operationExcelDownload}>파일 다운로드</Button>
}
/>
</div>
<div className="h-[39dvh] w-full overflow-x-hidden overflow-y-auto rounded-lg border mt-4">
{/* <div className="flex-1 px-2 pb-2"> */}
<LoadingOverlay isLoading={isLoading} />
<UiTable
headName={
(() => {
const label = WORK_TYPES.find((type) => type.val === workType)?.text
return (<>{label} 사업 현황 ({tableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={tableData}
headlist={dynamicHeadlist}
pageSize={OPERATION_TABLE_SIZE}
total={tableCount}
cellClick={handleOperationCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
curPage={curPage}
headButton={
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-sm font-medium green" size="sm" onClick={operationExcelDownload}>파일 다운로드</Button>
}
/>
{/* </div> */}
</div>
<div className="h-[39vh] w-full overflow-hidden rounded-lg border">
<div className="h-[39dvh] w-full overflow-x-hidden overflow-y-auto rounded-lg border">
{/* 테이블2 영역 */}
<div className="flex-1 px-2 pb-2">
<LoadingOverlay isLoading={isDetailLoading} />
<UiTable
headName={
(() => {
const label = WORK_TYPES.find((type) => type.val === workType)?.text
return (<>{label} 결과표 ({detailTableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={detailTableData}
headlist={dynamicHeadlist2}
pageSize={OPERATION_TABLE_SIZE}
total={detailTableCount}
cellClick={handleOperationResultCellClick}
onPageChange={setDetailCurPage}
resetPageNo={isResetDetailPage}
resetSelection={isResetDetailSelection}
curPage={detailCurPage}
headButton={
<div className='flex'>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium primary" size="sm" onClick={viewMultipleFeature}>지도에서 보기</Button>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium green" size="sm" onClick={operationResultExcelDownload}>파일 다운로드</Button>
</div>
}
/>
</div>
{/* <div className="flex-1 px-2 pb-2"> */}
<LoadingOverlay isLoading={isDetailLoading} />
<UiTable
headName={
(() => {
const label = WORK_TYPES.find((type) => type.val === workType)?.text
return (<>{label} 결과표 ({detailTableCount.toLocaleString('ko-KR')})건</>);
})()
}
tableData={detailTableData}
headlist={dynamicHeadlist2}
pageSize={OPERATION_TABLE_SIZE}
total={detailTableCount}
cellClick={handleOperationResultCellClick}
onPageChange={setDetailCurPage}
resetPageNo={isResetDetailPage}
resetSelection={isResetDetailSelection}
curPage={detailCurPage}
headButton={
<div className='flex'>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium primary" size="sm" onClick={viewMultipleFeature}>지도에서 보기</Button>
<Button className="px-4 py-2 !mr-[1.2rem] text-white rounded-sm text-lg font-medium green" size="sm" onClick={operationResultExcelDownload}>파일 다운로드</Button>
</div>
}
/>
{/* </div> */}
</div>
</>
)}
@@ -224,8 +224,8 @@ const SearchModal: React.FC = () => {
bodyClass={`
h-[100dvh]
w-[90dvw]
max-w-[1200px]
max-h-[100dvh]
max-w-[1220px]
max-h-[970px]
overflow-y-hidden
z-[101]
`}
+113 -115
View File
@@ -21,7 +21,7 @@ import WrOverLay from "@/components/ui/map/wrOverLay/wrOverLay";
const Map = () => {
const {code, comMap ,rainMapDetile ,rswtMapDetile,getRuseMaplListReturn,pbnMapDetaile,ldrmntMapDetile,htdfMapDetile,coSttnMapDetail} = useWrStore((state) => state);
const { code, comMap, rainMapDetile, rswtMapDetile, getRuseMaplListReturn, pbnMapDetaile, ldrmntMapDetile, htdfMapDetile, coSttnMapDetail } = useWrStore((state) => state);
const { isFeatured } = comMap;
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
const gisMaps = useRef<any | null>(null);
@@ -93,7 +93,6 @@ const Map = () => {
return;
}
// 항상 같은 select 객체 사용
const select = GisApp.Module.select as any;
if (!select) return;
@@ -109,7 +108,6 @@ const Map = () => {
const layerName = getWrLayerNm(data);
const featurePk = getWrFeaturePk(layerName ?? "");
// 재이용시설
if (featurePk) {
const lastPk =
@@ -254,139 +252,139 @@ const Map = () => {
const OVERLAY_MIN_ZOOM = 16;
const OVERLAY_COORD_PRECISION = 5;
const OVERLAY_MAX_PER_VIEW = 800;
const OVERLAY_COORD_PRECISION = 5;
const OVERLAY_MAX_PER_VIEW = 800;
const overlayManagersRef = useRef<any[]>([]);
const overlayActiveRef = useRef(false);
const moveEndDebounceRef = useRef<number | null>(null);
const overlayManagersRef = useRef<any[]>([]);
const overlayActiveRef = useRef(false);
const moveEndDebounceRef = useRef<number | null>(null);
// 반환: Promise<HTMLDivElement | null>
const overlayFormatter = async (feature: any, props: any) => {
const p = props || {};
const featureId =
feature.getId?.() ?? p?.id ?? p?.fid ?? p?.ftrIdn ?? '';
if (!featureId) return null;
// 반환: Promise<HTMLDivElement | null>
const overlayFormatter = async (feature: any, props: any) => {
const p = props || {};
const featureId =
feature.getId?.() ?? p?.id ?? p?.fid ?? p?.ftrIdn ?? '';
if (!featureId) return null;
const tableId = String(featureId).split('.')[0]??'';
const fcltCd = getFeatureCd(props, tableId);
const tableId = String(featureId).split('.')[0] ?? '';
const fcltCd = getFeatureCd(props, tableId);
if (!fcltCd) return null;
if (!fcltCd) return null;
let data: any = null;
let title = '';
let data: any = null;
let title = '';
if (tableId === 'tb_il_swage_prcs_fclt') { data = await pbnMapDetaile(fcltCd); title = '하수처리시설'; }
else if (tableId === 'tb_wr_bdst_ruse_fclt') { data = await getRuseMaplListReturn(fcltCd); title = '하수재이용시설'; }
else if (tableId === 'tb_wr_rnwtr_utztn_fclt'){ data = await rainMapDetile(fcltCd); title = '빗물이용시설'; }
else if (tableId === 'tb_wr_rswtr_fclt') { data = await rswtMapDetile(fcltCd); title = '중수도시설'; }
else if (tableId === 'tb_wr_htdfl_fclt') { data = await htdfMapDetile(fcltCd); title = '온배수시설'; }
else if (tableId === 'tb_wr_ruse_fclt_dmd_co'){ data = await coSttnMapDetail(fcltCd); title = '수요처'; }
else if (tableId === 'tb_wr_tmpr_dmd_co') { data = await ldrmntMapDetile(fcltCd); title = '잠재수요처'; }
if (tableId === 'tb_il_swage_prcs_fclt') { data = await pbnMapDetaile(fcltCd); title = '하수처리시설'; }
else if (tableId === 'tb_wr_bdst_ruse_fclt') { data = await getRuseMaplListReturn(fcltCd); title = '하수재이용시설'; }
else if (tableId === 'tb_wr_rnwtr_utztn_fclt') { data = await rainMapDetile(fcltCd); title = '빗물이용시설'; }
else if (tableId === 'tb_wr_rswtr_fclt') { data = await rswtMapDetile(fcltCd); title = '중수도시설'; }
else if (tableId === 'tb_wr_htdfl_fclt') { data = await htdfMapDetile(fcltCd); title = '온배수시설'; }
else if (tableId === 'tb_wr_ruse_fclt_dmd_co') { data = await coSttnMapDetail(fcltCd); title = '수요처'; }
else if (tableId === 'tb_wr_tmpr_dmd_co') { data = await ldrmntMapDetile(fcltCd); title = '잠재수요처'; }
const empty =
data == null ||
(Array.isArray(data) && data.length === 0) ||
(typeof data === 'object' && !Array.isArray(data) && Object.keys(data).length === 0);
const empty =
data == null ||
(Array.isArray(data) && data.length === 0) ||
(typeof data === 'object' && !Array.isArray(data) && Object.keys(data).length === 0);
if (empty) return null;
if (empty) return null;
const div = document.createElement('div');
const root = createRoot(div);
(div as any).__dispose = () => { try { root.unmount(); } catch {} };
root.render(<WrOverLay title={title} data={data} code={code} />);
return div; // ← 데이터 있을 때만 HTMLElement 반환
};
const destroyAllManagers = () => {
overlayManagersRef.current.forEach(m => { try { m.destroy(); } catch {} });
overlayManagersRef.current = [];
overlayActiveRef.current = false;
};
const div = document.createElement('div');
const root = createRoot(div);
(div as any).__dispose = () => { try { root.unmount(); } catch { } };
root.render(<WrOverLay title={title} data={data} code={code} />);
return div; // ← 데이터 있을 때만 HTMLElement 반환
};
const destroyAllManagers = () => {
overlayManagersRef.current.forEach(m => { try { m.destroy(); } catch { } });
overlayManagersRef.current = [];
overlayActiveRef.current = false;
};
const mountOverlayManagers = () => {
const map = gisMaps.current;
if (!map) return;
const mountOverlayManagers = () => {
const map = gisMaps.current;
if (!map) return;
// 이전 것 정리
destroyAllManagers();
// 이전 것 정리
destroyAllManagers();
// 체크된 벡터 레이어만 골라 매니저 생성
const checkedSet = new Set(checkedLayers.map(String));
const layers: any[] = map.getLayers().getArray();
const targets = layers.filter((layer: any) => {
const src = layer.getSource?.();
const isVector = src && typeof src.getFeatures === "function";
const id = String(layer.get?.("lyrSn") ?? layer.get?.("id") ?? "");
return isVector && layer.getVisible?.() && checkedSet.has(id);
});
targets.forEach((layer: any) => {
const mgr = createOverlayManager(map, layer, overlayFormatter, {
coordPrecision: OVERLAY_COORD_PRECISION,
maxOverlaysPerViewport: OVERLAY_MAX_PER_VIEW,
// 체크된 벡터 레이어만 골라 매니저 생성
const checkedSet = new Set(checkedLayers.map(String));
const layers: any[] = map.getLayers().getArray();
const targets = layers.filter((layer: any) => {
const src = layer.getSource?.();
const isVector = src && typeof src.getFeatures === "function";
const id = String(layer.get?.("lyrSn") ?? layer.get?.("id") ?? "");
return isVector && layer.getVisible?.() && checkedSet.has(id);
});
mgr.mount(); // 리스너 1회 등록
mgr.enable(); // 표시 + 1회 sync
overlayManagersRef.current.push(mgr);
});
overlayActiveRef.current = overlayManagersRef.current.length > 0;
};
targets.forEach((layer: any) => {
const mgr = createOverlayManager(map, layer, overlayFormatter, {
coordPrecision: OVERLAY_COORD_PRECISION,
maxOverlaysPerViewport: OVERLAY_MAX_PER_VIEW,
});
mgr.mount(); // 리스너 1회 등록
mgr.enable(); // 표시 + 1회 sync
overlayManagersRef.current.push(mgr);
});
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const z = map.getView()?.getZoom?.() ?? 0;
if (z < OVERLAY_MIN_ZOOM) {
// 저줌에선 그냥 안 보이게만
overlayManagersRef.current.forEach(m => { try { m.disable({ clear:true, delayed:true }); } catch {} });
return;
}
mountOverlayManagers();
return () => { destroyAllManagers(); };
}, [checkedLayers]);
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const onMoveStart = () => {
// 숨기기만 (리스너/DOM 대량 제거 X)
overlayManagersRef.current.forEach(m => { try { m.disable({ clear:false }); } catch {} });
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
overlayActiveRef.current = overlayManagersRef.current.length > 0;
};
const onMoveEnd = () => {
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const z = map.getView()?.getZoom?.() ?? 0;
const active = overlayActiveRef.current;
if (z < OVERLAY_MIN_ZOOM) {
// 저줌에선 그냥 안 보이게만
overlayManagersRef.current.forEach(m => { try { m.disable({ clear: true, delayed: true }); } catch { } });
return;
}
mountOverlayManagers();
if (moveEndDebounceRef.current) clearTimeout(moveEndDebounceRef.current);
moveEndDebounceRef.current = window.setTimeout(() => {
if (z < OVERLAY_MIN_ZOOM) {
if (active) overlayManagersRef.current.forEach(m => { try { m.disable({ clear:true, delayed:true }); } catch {} });
return;
}
if (!active) {
mountOverlayManagers();
} else {
// 다시 보이고 1회만 동기화
overlayManagersRef.current.forEach(m => { try { m.enable(); m.syncOverlays(); } catch {} });
}
}, 180) as unknown as number;
};
return () => { destroyAllManagers(); };
}, [checkedLayers]);
map.on("movestart", onMoveStart);
map.on("moveend", onMoveEnd);
return () => {
map.un("movestart", onMoveStart);
map.un("moveend", onMoveEnd);
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
};
}, [checkedLayers]);
useEffect(() => {
const map = gisMaps.current;
if (!map) return;
const onMoveStart = () => {
// 숨기기만 (리스너/DOM 대량 제거 X)
overlayManagersRef.current.forEach(m => { try { m.disable({ clear: false }); } catch { } });
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
};
const onMoveEnd = () => {
const z = map.getView()?.getZoom?.() ?? 0;
const active = overlayActiveRef.current;
if (moveEndDebounceRef.current) clearTimeout(moveEndDebounceRef.current);
moveEndDebounceRef.current = window.setTimeout(() => {
if (z < OVERLAY_MIN_ZOOM) {
if (active) overlayManagersRef.current.forEach(m => { try { m.disable({ clear: true, delayed: true }); } catch { } });
return;
}
if (!active) {
mountOverlayManagers();
} else {
// 다시 보이고 1회만 동기화
overlayManagersRef.current.forEach(m => { try { m.enable(); m.syncOverlays(); } catch { } });
}
}, 180) as unknown as number;
};
map.on("movestart", onMoveStart);
map.on("moveend", onMoveEnd);
return () => {
map.un("movestart", onMoveStart);
map.un("moveend", onMoveEnd);
if (moveEndDebounceRef.current) { clearTimeout(moveEndDebounceRef.current); moveEndDebounceRef.current = null; }
};
}, [checkedLayers]);
return (
<div className="bg-container">
<Gis
@@ -24,6 +24,7 @@ import { Button, Label } from "@common/components/ui";
import { useEffect, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import * as XLSX from "xlsx";
export default function RuseCaseMng() {
const { code, ruseCaseMng, selectRuseCaseMng, ruseCaseMngInit } = useWrStore(
@@ -76,7 +77,9 @@ export default function RuseCaseMng() {
};
useEffect(() => {
if (excelList !== undefined && excelList.length === 0) {
if (!excelList) return;
if (excelList.length === 0) {
toast.error(t("excelDownErrMsg"));
return;
}
@@ -86,74 +89,93 @@ export default function RuseCaseMng() {
}
// 받은 파일 바인너리 처리
const blobRet = await response.arrayBuffer();
if (excelList) {
const excelData1 = excelList.map((item) => {
return [
item.ruseBizNm,
item.bizBgngDate,
item.bizEndDate,
item.splyFcltKnd,
item.splyFcltNm,
item.splyFcltCpct,
item.dmdFcltNm,
item.dmdFcltAddr,
item.ruseFcltCpct,
item.ruseFcltPplLen,
item.ruseFcltUsg,
item.ruseFcltSplyCpct,
item.ruseFcltPrcsMsrc,
item.grnteWqUsg,
item.grnteWqGrssClfg,
item.grnteWqCombResdch,
item.grnteWqTrbt,
item.grnteWqBod,
item.grnteWqSmll,
item.grnteWqCrmty,
item.grnteWqTn,
item.grnteWqTp,
item.grnteWqPh,
item.grnteWqClIonQnt,
item.grnteWqCndctStat,
item.grnteWqRmrk,
item.reqBizGrssCst,
item.reqBizReuseFcltCst,
item.reqBizPplCst,
item.reqBizArchCst,
item.reqBizMchnCst,
item.reqBizMtrngCst,
item.reqBizGisCst,
item.reqBizCctvCst,
item.reqBizCmcnCst,
item.reqBizWstCst,
item.reqBizDesignCst,
item.reqBizSpvsCst,
item.reqBizSbsdCst,
item.reqBizEtc,
item.prcmPlanGrssCst,
item.prcmPlanNlep,
item.prcmPlanLcep,
item.prcmPlanBrdnCst,
item.prcmPlanEcqrRt,
item.clclnGrssCst,
item.clclnNlep,
item.clclnLcep,
item.clclnBrdnCst,
item.clclnEcqrRt,
];
});
const sheetParameter: SheetParameter[] = [
{
data: excelData1,
headerNum: 2,
headerRange: "A1:AX1",
sheetName: "물재이용사례",
startCol: "A",
},
const replaceHeaderText = (text: string) =>
text
.replaceAll("사업시작일", "사업시작년")
.replaceAll("사업종료일", "사업종료년");
const wb = XLSX.read(blobRet, { type: "array" });
wb.SheetNames.forEach((sheetName) => {
const sheet = wb.Sheets[sheetName];
if (!sheet) return;
Object.keys(sheet).forEach((addr) => {
if (addr.startsWith("!")) return;
const cell = sheet[addr] as XLSX.CellObject | undefined;
if (!cell || typeof cell.v !== "string") return;
const next = replaceHeaderText(cell.v);
if (next !== cell.v) cell.v = next;
});
});
const updatedBlob = XLSX.write(wb, { bookType: "xlsx", type: "array" });
const excelData1 = excelList.map((item) => {
return [
item.ruseBizNm,
item.bizBgngDate,
item.bizEndDate,
item.splyFcltKnd,
item.splyFcltNm,
item.splyFcltCpct,
item.dmdFcltNm,
item.dmdFcltAddr,
item.ruseFcltCpct,
item.ruseFcltPplLen,
item.ruseFcltUsg,
item.ruseFcltSplyCpct,
item.ruseFcltPrcsMsrc,
item.grnteWqUsg,
item.grnteWqGrssClfg,
item.grnteWqCombResdch,
item.grnteWqTrbt,
item.grnteWqBod,
item.grnteWqSmll,
item.grnteWqCrmty,
item.grnteWqTn,
item.grnteWqTp,
item.grnteWqPh,
item.grnteWqClIonQnt,
item.grnteWqCndctStat,
item.grnteWqRmrk,
item.reqBizGrssCst,
item.reqBizReuseFcltCst,
item.reqBizPplCst,
item.reqBizArchCst,
item.reqBizMchnCst,
item.reqBizMtrngCst,
item.reqBizGisCst,
item.reqBizCctvCst,
item.reqBizCmcnCst,
item.reqBizWstCst,
item.reqBizDesignCst,
item.reqBizSpvsCst,
item.reqBizSbsdCst,
item.reqBizEtc,
item.prcmPlanGrssCst,
item.prcmPlanNlep,
item.prcmPlanLcep,
item.prcmPlanBrdnCst,
item.prcmPlanEcqrRt,
item.clclnGrssCst,
item.clclnNlep,
item.clclnLcep,
item.clclnBrdnCst,
item.clclnEcqrRt,
];
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
await filePickedBlobArray(blobRet, "물재이용사례현황", sheetParameter);
}
});
const sheetParameter: SheetParameter[] = [
{
data: excelData1,
headerNum: 2,
headerRange: "A1:AX1",
sheetName: "물재이용사례",
startCol: "A",
},
];
// 버퍼에 있는 엑셀데이터 전달 후 json으로 변환
await filePickedBlobArray(updatedBlob, "물재이용사례현황", sheetParameter);
});
}, [excelList]);
@@ -299,8 +321,12 @@ export default function RuseCaseMng() {
}}
resetPageNo={resetPage}
/>
<span className="text-2xl font-bold text-gray-500">
☞ 본 사례의 사업비는 재원협의 단계의 정보이므로, 최종확정된 비용이 아닙니다.
</span>
</div>
</ListDiv>
</div>
</div>
</ContentsDiv>
@@ -1,3 +1,19 @@
/**
* 재이용시설 등록 - 하수재이용 시설등록
*
* - layout.tsx에 의해 공통 레이아웃이 적용됨
* - with-layout 적용
* - 하수처리시설에 하수재이용 시설을 등록 한다.
* - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다
* indexMng: 시설정보
* indexBiz: 차수별 정보
* 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다.
* 🔗 사용 API
* 하수재이용시설을 등록 /reuseFc/pubFc
* 첨부파일 삭제 /attach-service/api/v1/atfl/attachments/atflCd//
* 첨부파일 다운로드 /attach-service/api/v1/atflcd/download/
* */
"use client";
import {
ContentsDiv,
@@ -35,18 +51,6 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { createDefaultPbnstItem } from "./utilsZod";
import { useTranslation } from "react-i18next";
/**
* 재이용시설 등록 - 하수재이용 시설등록
*
* - layout.tsx에 의해 공통 레이아웃이 적용됨
* - with-layout 적용
* - 하수처리시설에 하수재이용 시설을 등록 한다.
* - form으로 시설정보 및 차수별 정보의 컴포넌트 데이터를 관리한다
* indexMng: 시설정보
* indexBiz: 차수별 정보
* 로 하수재이용 시설에 등록된 시설 및 차수별 정보를 관리한다.
* */
export default function PublicReuseFaciltyInsert() {
const {
auth,
@@ -104,7 +108,7 @@ export default function PublicReuseFaciltyInsert() {
useEffect(() => {
if (useInitRef.current == true && laeSeCd !== undefined) {
pubHasuInit("1", laeSeCd);
pubHasuInit("1", laeSeCd); //page: string, sggOrCity: string
}
}, [useInitRef.current, laeSeCd]);
@@ -1,5 +1,7 @@
/**
* 온배수시설 현황
*/
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type {
@@ -34,11 +36,9 @@ import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
export default function HtdflSttn() {
const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore(
(state) => state
);
const { auth, code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
const { laeSeCd } = auth; // 지자체구분코드
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
const isDownloadTriggered = useRef(false);
const { t } = useTranslation('base');
const [pageNation, setPageNation] = useState(1);
@@ -57,6 +57,7 @@ export default function HtdflSttn() {
// }>({ isOpen: false, chBuilding: [] });
const [fcltNm, setFcltNm] = useState<string>("");
console.log("laeSeCd : ", laeSeCd);
useEffect(() => {
htdflSttnSearch(false, pageNation, htdflSttnSize, String(getConValue()), fcltNm, code.cityCd, code.sggCd);
isResetPage(false)
@@ -1,3 +1,12 @@
/**
* 하수재이용 시설 현황
* 재이용시설 현황 - 하수재이용시설 현황
* - layout.tsx에 의해 공통 레이아웃이 적용됨
* - with-layout 적용
* 하수처리시설. 하수재이용시설 , 하수재이용시설 실적에 대한 정보를 확인한다.
* 모달 : 테이블의 헤더를 원하는대로 조절해서 볼수 있다.
* 클릭시 해당 재이용ㅇ
* */
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
@@ -24,15 +33,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
/**
* 하수재이용 시설 현황
* 재이용시설 현황 - 하수재이용시설 현황
* - layout.tsx에 의해 공통 레이아웃이 적용됨
* - with-layout 적용
* 하수처리시설. 하수재이용시설 , 하수재이용시설 실적에 대한 정보를 확인한다.
* 모달 : 테이블의 헤더를 원하는대로 조절해서 볼수 있다.
* 클릭시 해당 재이용ㅇ
* */
export default function PbnstSttn() {
const {
code,
@@ -1,3 +1,6 @@
/**
* 빗물재이용시설 현황
*/
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
@@ -1,3 +1,6 @@
/**
* 중수도시설 현황
*/
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
@@ -20,20 +20,20 @@ export default function HasuStatPage() {
const data = await res.json();
const ip: string = data?.ip || "";
if (didCancel) return;
//alert("Client IP:" + ip);
console.log("Client IP:" + ip);
const is10 = /^10\./.test(ip);
const is172 = /^172\./.test(ip);
setStatus(is10||is172 ? "redirect-internal" : "redirect-root");
setStatus(is10 || is172 ? "redirect-internal" : "redirect-root");
// Use location.replace so user can't go back to this page
if (is10||is172) {
if (is10 || is172) {
// redirect to internal IP
// alert(process.env.NEXT_PUBLIC_HASUDOINFO_IN +'/cms/lay1/WS10000014/program.do');
window.open(process.env.NEXT_PUBLIC_HASUDOINFO_IN +'/cms/lay1/WS10000014/program.do', '_blank');
window.open(process.env.NEXT_PUBLIC_HASUDOINFO_IN + '/cms/lay1/WS10000014/program.do', '_blank');
} else {
// alert(process.env.NEXT_PUBLIC_HASUDOINFO +'/cms/lay1/WS10000014/program.do');
window.open(process.env.NEXT_PUBLIC_HASUDOINFO +'/cms/lay1/WS10000014/program.do', '_blank');
window.open(process.env.NEXT_PUBLIC_HASUDOINFO + '/cms/lay1/WS10000014/program.do', '_blank');
}
window.history.back();
} catch {
@@ -53,13 +53,13 @@ export default function HasuStatPage() {
}, []);
return (
<div style={{padding:20,fontFamily:'Noto Sans KR, sans-serif'}}>
<div style={{ padding: 20, fontFamily: 'Noto Sans KR, sans-serif' }}>
{status === "checking" && <div>접속 IP 확인 중...</div>}
{status === "redirect-internal" && <div>내부망으로 이동합니다...</div>}
{status === "redirect-root" && <div>외부에서 접속하여 루트로 이동합니다...</div>}
{status === "error-fallback" && (
<div>
문제가 발생하여 루트로 이동합니다. 이동하지 않으면 <Link href="/">여기</Link>를 클릭하세요.
문제가 발생하여 루트로 이동합니다. 이동하지 않으면 <Link href="/">여기</Link>를 클릭하세요.
</div>
)}
</div>
+2 -1
View File
@@ -10,7 +10,7 @@ export type authState = {
regAuthrtYn: string;
mdfcnAuthrtYn: string;
delAuthrtYn: string;
laeSeCd: string;
laeSeCd: string; // 지자체구분코드
myUUID?: string;
};
};
@@ -72,6 +72,7 @@ export const authActionsExport: (set: any, get: any) => authActions = (
return;
}
const infoMe = await getUserInfo();
console.log(infoMe);
const isLaeSeCd =
infoMe.laeSeCd.slice(0, 2) === "G3" ? infoMe.laeSeCd.slice(2) : "0";
@@ -11,14 +11,14 @@ export const ruseCaseHeadListExport: TableUpperProps[] = [
},
{
id: "bizBgngDate",
title: "사업시작일",
title: "사업시작년",
visible: true,
row: 0,
rowSpan: 2,
},
{
id: "bizEndDate",
title: "사업종료일",
title: "사업종료년",
visible: true,
row: 0,
rowSpan: 2,
@@ -118,7 +118,7 @@ const hasuListFetch = async (
if (searchTxt) {
url = url + `/${searchTxt}`;
}
const rainRes = await postFectch(url, data, fetchType.COMMON);
const rainRes = await postFectch(url, data, fetchType.COMMON); // fo
const hasuList = rainRes.data.map((item: any) => {
return {
@@ -176,7 +176,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
// 하수처리시설을 조회한다(운영실태)
pubHasuInit: async (page: string, sggOrCity: string) => {
try {
const pbnstHasuRes = await hasuListFetch(page, sggOrCity);
const pbnstHasuRes = await hasuListFetch(page, sggOrCity); // /prcsFclt/ruseInfo
return set((state: pubFacState) => ({
...state,
pbnst: {
+44 -44
View File
@@ -1,22 +1,22 @@
import { formatCommaNumber, formatPhoneNumber } from "./commom";
const wrLayerList = [
{ text: "tb_il_swage_prcs_fclt", val: "bscFctCd" },
{ text: "tb_wr_bdst_ruse_fclt", val: "pbnstRuseFcltId" },
{ text: "tb_wr_rnwtr_utztn_fclt", val: "rainyObj" },
{ text: "tb_wr_rswtr_fclt", val: "rswtrObj" },
{ text: "tb_wr_htdfl_fclt", val: "htdflObj" },
{ text: "tb_wr_ruse_fclt_dmd_co", val: "dmdInfoId" },
{ text: "tb_wr_tmpr_dmd_co", val: "fctryMngSn" },
{ text: "tb_il_swage_prcs_fclt", val: "bscFctCd" }, //하수처리시설
{ text: "tb_wr_bdst_ruse_fclt", val: "pbnstRuseFcltId" }, //하수재이용시설
{ text: "tb_wr_rnwtr_utztn_fclt", val: "rainyObj" }, //빗물이용시설
{ text: "tb_wr_rswtr_fclt", val: "rswtrObj" }, //중수도시설
{ text: "tb_wr_htdfl_fclt", val: "htdflObj" }, //온배수시설
{ text: "tb_wr_ruse_fclt_dmd_co", val: "dmdInfoId" }, //수요처
{ text: "tb_wr_tmpr_dmd_co", val: "fctryMngSn" }, //잠재수요처
];
const wrFeaturePK = [
{ text: "bscFctCd", val: "tb_il_swage_prcs_fclt" },
{ text: "searchPk", val: "tb_wr_bdst_ruse_fclt" },
{ text: "bdstInfoSn", val: "tb_wr_rnwtr_utztn_fclt" },
{ text: "bdstInfoSn", val: "tb_wr_rswtr_fclt" },
{ text: "bdstInfoSn", val: "tb_wr_htdfl_fclt" },
{ text: "dmdInfoId", val: "tb_wr_ruse_fclt_dmd_co" },
{ text: "fctryMngSn", val: "tb_wr_tmpr_dmd_co" },
{ text: "bscFctCd", val: "tb_il_swage_prcs_fclt" }, //하수처리시설
{ text: "searchPk", val: "tb_wr_bdst_ruse_fclt" }, //하수재이용시설
{ text: "bdstInfoSn", val: "tb_wr_rnwtr_utztn_fclt" }, //빗물이용시설
{ text: "bdstInfoSn", val: "tb_wr_rswtr_fclt" }, //중수도시설
{ text: "bdstInfoSn", val: "tb_wr_htdfl_fclt" }, //온배수시설
{ text: "dmdInfoId", val: "tb_wr_ruse_fclt_dmd_co" }, //수요처
{ text: "fctryMngSn", val: "tb_wr_tmpr_dmd_co" }, //잠재수요처
];
// { text: "하수처리시설", val: "tb_il_swage_prcs_fclt" },
@@ -29,18 +29,18 @@ const wrFeaturePK = [
export const getFeatureCd = (featurePropertise: any, layerNm: string) => {
const featureCd =
layerNm === "tb_wr_bdst_ruse_fclt"
layerNm === "tb_wr_bdst_ruse_fclt" //하수재이용시설
? featurePropertise?.swtrmt_fclt_cd
: [
"tb_wr_rswtr_fclt",
"tb_wr_htdfl_fclt",
"tb_wr_rnwtr_utztn_fclt",
"tb_wr_tmpr_dmd_co",
].includes(layerNm)
"tb_wr_rswtr_fclt", // 중수도시설
"tb_wr_htdfl_fclt", // 온배수시설
"tb_wr_rnwtr_utztn_fclt", // 빗물이용시설
"tb_wr_tmpr_dmd_co", // 잠재수요처
].includes(layerNm)
? featurePropertise?.bdst_nm
: layerNm === "tb_il_swage_prcs_fclt"
: layerNm === "tb_il_swage_prcs_fclt" //하수처리시설
? featurePropertise?.swtrmt_fclt_cd
: layerNm === "tb_wr_ruse_fclt_dmd_co"
: layerNm === "tb_wr_ruse_fclt_dmd_co" //수요처
? featurePropertise?.bdst_info_sn
: null;
@@ -71,9 +71,9 @@ export const getSelectedLayers = (isFeature: any, gisMaps: any) => {
let result = null;
const layers = map
? map
.getLayers()
.getArray()
.filter((l: any) => l.getVisible())
.getLayers()
.getArray()
.filter((l: any) => l.getVisible())
: []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: () => null };
@@ -119,12 +119,12 @@ export const getClickFeatureId = (data: any) => {
} else if (layerName == "수요처") {
//수요처
featureId = `${layerName}.${data.dmdInfoId.replaceAll("-", "")}`;
}else if (layerName == "잠재수요처") {
} else if (layerName == "잠재수요처") {
//잠재수요처
featureId = data.id_
} else {
} else {
featureId = data.id_
}
@@ -160,7 +160,7 @@ export function featurePopUpOpen(
);
}
export const getOverLayObj = (fclType: string, data: any,code?:any) => {
export const getOverLayObj = (fclType: string, data: any, code?: any) => {
let newObj = {};
let title = "";
@@ -169,11 +169,11 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => {
if (fclType === "하수재이용시설") {
newObj = {
"시설용량(톤/일)": formatCommaNumber(data?.fcltCpct) ??'확인불가',
"재이용률(%)": (data?.fcltCpct / data?.bscFctCpc)||0,
"시설용량(톤/일)": formatCommaNumber(data?.fcltCpct) ?? '확인불가',
"재이용률(%)": (data?.fcltCpct / data?.bscFctCpc) || 0,
"장내용수(m³/년)": formatCommaNumber(data?.inUsage) ?? '확인불가',
"장외용수(m3/년)":formatCommaNumber(data?.outUsage) ?? '확인불가',
// 수요처: data?.reuseBuilding[0]?.rainyObj.pntfColArea ?? '확인불가',
"장외용수(m3/년)": formatCommaNumber(data?.outUsage) ?? '확인불가',
// 수요처: data?.reuseBuilding[0]?.rainyObj.pntfColArea ?? '확인불가',
};
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "하수처리시설") {
@@ -184,9 +184,9 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => {
"재이용시설 등록여부": data?.ruse ?? '확인불가',
};
title = data?.bscFctNm ?? '확인불가';
} else if (fclType === "빗물이용시설" ) {
} else if (fclType === "빗물이용시설") {
newObj = {
건물용도: code?.bdstUsgCd.find((item) => item.val=== String(data?.reuseBuilding[0].bdstUsgCd) )?.text ?? '확인불가',
건물용도: code?.bdstUsgCd.find((item) => item.val === String(data?.reuseBuilding[0].bdstUsgCd))?.text ?? '확인불가',
설치완료일: data?.reuseBuilding[0]?.instlCmptnDt ?? '확인불가',
처리시설유무: data?.reuseBuilding[0]?.rainyObj.filtrTrtmfctYn ?? '확인불가',
"처리시설용량(m³/일)": formatCommaNumber(data?.reuseBuilding[0]?.rainyObj.filtrTrtmfctCpct) ?? '확인불가',
@@ -195,25 +195,25 @@ export const getOverLayObj = (fclType: string, data: any,code?:any) => {
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "중수도시설") {
newObj = {
건물용도: code?.bdstUsgCd.find((item) => item.val===String(data?.reuseBuilding[0].bdstUsgCd) )?.text ?? '확인불가',
건물용도: code?.bdstUsgCd.find((item) => item.val === String(data?.reuseBuilding[0].bdstUsgCd))?.text ?? '확인불가',
설치완료일: data?.reuseBuilding[0]?.instlCmptnDt ?? '확인불가',
"주요 처리공정": data?.reuseBuilding[0]?.rswtrObj.filtrTrtmfctProcs ?? '확인불가',
원수종류: code?.orgwtKndCd.find((item) => item.val === data?.reuseBuilding[0]?.rswtrObj.orgwtKndCd)?.text ?? '확인불가',
"주요 처리공정": data?.reuseBuilding[0]?.rswtrObj.filtrTrtmfctProcs ?? '확인불가',
원수종류: code?.orgwtKndCd.find((item) => item.val === data?.reuseBuilding[0]?.rswtrObj.orgwtKndCd)?.text ?? '확인불가',
//이용용도: isCode.filtrTrtmfctUsgCd data?.reuseBuilding[0]?.rswtrObj.altUswtrKndCd ?? '확인불가',
};
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "온배수시설") {
newObj = {
'발전유형': data?.reuseBuilding[0]?.htdflObj.etgtType??'',
'설비용량': data?.reuseBuilding[0]?.htdflObj.fclCpct??'',
'담수화 여부': data?.reuseBuilding[0]?.htdflObj.plwtYn??'',
'발전유형': data?.reuseBuilding[0]?.htdflObj.etgtType ?? '',
'설비용량': data?.reuseBuilding[0]?.htdflObj.fclCpct ?? '',
'담수화 여부': data?.reuseBuilding[0]?.htdflObj.plwtYn ?? '',
};
title = data?.bdstNm ?? '확인불가';
} else if (fclType === "수요처") {
newObj = {
'사업자등록번호': data?.dmdInfoId??'',
'주소': data?.daddr??'',
'전화번호': formatPhoneNumber(data?.telno)??'',
'사업자등록번호': data?.dmdInfoId ?? '',
'주소': data?.daddr ?? '',
'전화번호': formatPhoneNumber(data?.telno) ?? '',
};
title = data?.dmdCoNm ?? '확인불가';
@@ -35,10 +35,11 @@ export type FilesType = {
file: File;
};
const diagramFileTypes = ".pdf,.jpg,.jpeg,.png,.bmp";
/**
* 재이용시설 등록 - 하수재이용 시설등록
* 재이용시설 등록 - 하수재이용 시설현황
* 재이용시설 등록 - 하수재이용 시설현황
* - layout.tsx에 의해 공통 레이아웃이 적용됨
* - with-layout 적용
* - 하수처리시설에 하수재이용 시설 시설 정보를 등록한다.
@@ -459,7 +460,7 @@ export function PbnstMngForm({
setFiles={(files: File[] | null) => {
if (files) fileHandler(files, "relation");
}}
fileTypes=".pdf"
fileTypes={diagramFileTypes}
onFileClick={(index) => {
fileDownLoad(
relationfiles?.find(
@@ -497,7 +498,7 @@ export function PbnstMngForm({
setFiles={(files: File[] | null) => {
if (files) fileHandler(files, "plan");
}}
fileTypes=".pdf"
fileTypes={diagramFileTypes}
onFileClick={(index) => {
fileDownLoad(
planFiles?.find(
@@ -2,5 +2,5 @@ import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
return twMerge(clsx(inputs)); //clsx 결과 (단순 합치기):twMerge 결과 (Tailwind 충돌 제거)
}
@@ -6,6 +6,7 @@ type ExcelDownloadProps = {
fileName: string;
sheetNameArray: string[];
headerRange?: string;
headers?: readonly string[]|undefined;
decimalArray0? : number[];
decimalArray1? : number[];
decimalArray2? : number[];
@@ -19,6 +20,15 @@ export const downloadExcel = ({ data, fileName = new Date().getTime().toString()
excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName);
};
export const downloadExcelHeaders = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3', headers}: ExcelDownloadProps) => {
const dataArray = Array.isArray(data) ? data : [data];
// headers가 제공되면 열 순서를 강제함
const worksheet = XLSX.utils.json_to_sheet(dataArray, headers ? { header: [...headers] } : undefined);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]);
excelStyle(XLSX.write(workbook, { bookType: "xlsx", type: "buffer" }), headerRange, fileName);
};
export const downloadExcelFormat = ({ data, fileName = new Date().getTime().toString() + '.xlsx', sheetNameArray = ["Sheet1"], headerRange='A1:V3', decimalArray0=[], decimalArray1=[], decimalArray2=[], decimalArray3=[]}: ExcelDownloadProps) => {
const worksheet = XLSX.utils.json_to_sheet(Array.isArray(data) ? data : [data]);
const workbook = XLSX.utils.book_new();
@@ -93,6 +93,7 @@ export const FileUploader = forwardRef<
".jpeg": "image/jpeg",
".png": "image/png",
".gif": "image/gif",
".bmp": "image/bmp",
".doc": "application/msword",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".xls": "application/vnd.ms-excel",
@@ -15,6 +15,7 @@ export * from "./search_form_right";
export * from "./search_input";
export * from "./search_input_select";
// export * from "./search_input_address";
export * from "./search_address";
export * from "./select";
export * from "./tab";
export * from "./table";
@@ -24,4 +25,4 @@ export * from "./sdmInsertForm";
export * from "./popover_ui";
export * from "./date_month_picker";
export * from "./date_picker_range"
export * from "./map/GisOverlay";
export * from "./map/GisOverlay";
@@ -1,4 +1,4 @@
import { Button, Input, Label } from "@common/components";
import { Button, Input } from "@common/components";
import { AsYouType } from "libphonenumber-js";
import React, { useCallback, useEffect, useState } from "react";
import type { ControllerRenderProps, UseFormReturn } from "react-hook-form";
@@ -6,10 +6,7 @@ import { FormField } from "../form";
import { FormUi } from "../form_ui";
import { SelectBox } from "../select";
import { SdmSearchForm } from "./sdmNameBox";
import { UiModal, UiTable } from '../../ui';
import type { Zip, ZipSearchParams } from "../search_input_address/zipService";
import { findAddress } from "../search_input_address/findAddress";
import { cn } from "@common/components";
import { SearchAddressModal } from "../search_address/SearchAddressModal";
// 수요처 정보
export type DemandCompType = {
@@ -91,7 +88,6 @@ export function SdmRegForm({
readOnly,
openNetwork,
}: SdmRegFormProps) {
const PAGE_SIZE = 10;
const [sidoValue, setSidoValue] = useState<string>("");
const [sigunValue, setSigunValue] = useState<string>("");
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([
@@ -104,30 +100,6 @@ export function SdmRegForm({
const [zipId, setZipId] = useState<number | undefined>(undefined);
const [address, setAddress] = useState<string | undefined>("");
const [detailedAddress, setDetailedAddress] = useState<string>("");
const [curPage, setCurPage] = useState<number>(1);
// 우편번호 검색 관련 상태
const [zipSearchResults, setZipSearchResults] = useState<Zip[]>([]);
const [zipTotalElements, setZipTotalElements] = useState<number>(-1);
const [searchQuery, setSearchQuery] = useState<ZipSearchParams>({
roadNm: "",
bldgNoMno: null,
bldgNoSno: null,
page: curPage,
size: PAGE_SIZE
});
const [isResetPage, setIsResetPage] = useState<boolean>(false);
const [isResetSelection, setIsResetSelection] = useState<boolean>(false);
const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined);
const [selectedZip, setSelectedZip] = useState<Zip>();
const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false);
const handleCellClick = (index: any, headId: any) => {
console.log('index', index);
console.log('headId', headId);
setSelectedZip(zipSearchResults[index]);
setIsSelectedZip(true);
console.log('selectedZip', zipSearchResults[index]);
};
const formatPhoneNumber = (value: string) => {
const input = value;
@@ -293,17 +265,6 @@ export function SdmRegForm({
[orgBznmNo, setIsDuplicate],
);
// 우편번호 선택 함수
const handleSelectAddress = () => {
setZipId(selectedZip?.zipId);
setAddress(selectedZip?.zipAddr || "");
setDetailedAddress("");
setIsZipModalOpen(false);
setSelectedZip(undefined);
setIsSelectedZip(false);
setSelectedRowIndex(undefined);
};
useEffect(() => {
if (updateList?.dmdInfoId) {
form.reset(updateList);
@@ -325,16 +286,6 @@ export function SdmRegForm({
console.log("form.formState.errors ", form.formState.errors);
}, [form.formState.errors]);
useEffect(() => {
console.log("curPage ", curPage);
searchQuery.page = curPage - 1;
const fetchAddress = async () => {
const result = await findAddress(searchQuery);
setZipSearchResults(result?.content);
};
fetchAddress();
}, [curPage]);
// 폼 제출 전에 주소 합치기
useEffect(() => {
// address와 detailedAddress를 합쳐서 daddr에 설정
@@ -344,105 +295,6 @@ export function SdmRegForm({
}
}, [address, detailedAddress, form]);
const renderBody = () => (
<>
<form
onSubmit={async (e) => {
e.preventDefault();
e.stopPropagation();
const result = await findAddress(searchQuery);
setZipSearchResults(result?.content);
setZipTotalElements(result?.totalElements);
}}
className="mb-4 space-y-2"
>
{/* 검색 조건 부분 */}
<div className="card card-border !m-0 flex flex-col gap-4 p-4">
<div className="grid grid-cols-3 gap-4">
<div className="flex flex-col">
<Label className="mb-1 font-bold text-base">도로명</Label>
<Input
value={searchQuery.roadNm || ""}
onChange={(e) =>
setSearchQuery({
...searchQuery,
roadNm: e.target.value,
})
}
placeholder="예: 테헤란로"
className="!text-[1.3rem]"
/>
</div>
<div className="flex flex-col">
<Label className="mb-1 text-base">건물본번</Label>
<Input
type="number"
value={searchQuery.bldgNoMno ?? ""}
onChange={(e) => {
const value = e.target.value
? parseInt(e.target.value)
: null;
setSearchQuery({
...searchQuery,
bldgNoMno: value,
});
}}
placeholder="예: 123"
className="!text-[1.3rem]"
/>
</div>
<div className="flex flex-col">
<Label className="mb-1 text-base">건물부번</Label>
<Input
type="number"
value={searchQuery.bldgNoSno ?? ""}
onChange={(e) => {
const value = e.target.value
? parseInt(e.target.value)
: null;
setSearchQuery({
...searchQuery,
bldgNoSno: value,
});
}}
placeholder="예: 45"
className="!text-[1.3rem]"
/>
</div>
</div>
<div className="flex justify-end">
<Button className="rounded-md" type="submit">검색</Button>
</div>
</div>
</form>
{/* 검색 결과 부분 */}
{zipTotalElements > 0 && (
<UiTable
headName=''
tableData={zipSearchResults}
headlist={[{ id: 'zoneNo', title: '우편번호' }, { id: 'zipAddr', title: '주소' }]}
pageSize={PAGE_SIZE}
total={zipTotalElements}
cellClick={handleCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
index={selectedRowIndex}
/>
)}
{zipTotalElements === 0 && (
<div className={cn("flex h-96 flex-col items-center justify-center gap-4")}>
<i className="diveicon di-info-circle text-3xl" />
조회된 데이터가 없습니다.
</div>
)}
</>
);
const formFields: Array<{
name: keyof FormSchema;
@@ -725,35 +577,14 @@ export function SdmRegForm({
/>
);
})}
<UiModal
headerTitle="주소 검색"
headerTitleClass="text-2xl font-bold text-gray-900"
<SearchAddressModal
open={isZipModalOpen}
onOpenChange={setIsZipModalOpen}
bodyClass={`
${zipTotalElements > -1 ? 'h-[80vh]' : 'h-[30vh]'}
w-[30vw]
min-w-[500px]
max-w-[90vw]
max-h-[85vh]
overflow-y-auto
!fixed
!top-[50%]
!left-[50%]
!-translate-x-1/2
!-translate-y-1/2
z-[101]
flex
flex-col
`}
body={renderBody()}
footerContent={
<div className="w-full flex justify-center items-center gap-4">
<Button className="rounded-md" size="lg" onClick={handleSelectAddress} disabled={!isSelectedZip}>선택</Button>
<Button className="rounded-md" size="lg" onClick={() => setIsZipModalOpen(false)}>취소</Button>
</div>
}
useDirectRender={true}
onSelect={(zip) => {
setZipId(zip.zipId);
setAddress(zip.zipAddr || "");
setDetailedAddress("");
}}
/>
</>
);
@@ -0,0 +1,221 @@
import { Button, Input, Label, cn } from "@common/components";
import React, { useState, useEffect } from "react";
import { UiModal } from "../dialog_ui";
import { UiTable } from "../table";
import type { Zip, ZipSearchParams } from "./zipService";
import { findAddress } from "./findAddress";
interface SearchAddressModalProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSelect: (zip: Zip) => void;
}
export function SearchAddressModal({ open, onOpenChange, onSelect }: SearchAddressModalProps) {
const PAGE_SIZE = 10;
const [curPage, setCurPage] = useState<number>(1);
const [zipSearchResults, setZipSearchResults] = useState<Zip[]>([]);
const [zipTotalElements, setZipTotalElements] = useState<number>(-1);
const [searchQuery, setSearchQuery] = useState<ZipSearchParams>({
roadNm: "",
bldgNoMno: null,
bldgNoSno: null,
page: 1,
size: PAGE_SIZE
});
const [isResetPage, setIsResetPage] = useState<boolean>(false);
const [isResetSelection] = useState<boolean>(false);
const [selectedRowIndex, setSelectedRowIndex] = useState<number | undefined>(undefined);
const [selectedZip, setSelectedZip] = useState<Zip>();
const [isSelectedZip, setIsSelectedZip] = useState<boolean>(false);
// Initialize/Reset state when modal opens
useEffect(() => {
if (open) {
setCurPage(1);
setZipSearchResults([]);
setZipTotalElements(-1);
setSearchQuery({
roadNm: "",
bldgNoMno: null,
bldgNoSno: null,
page: 0,
size: PAGE_SIZE
});
setSelectedZip(undefined);
setIsSelectedZip(false);
setSelectedRowIndex(undefined);
setIsResetPage(true);
setTimeout(() => setIsResetPage(false), 100);
}
}, [open]);
// Pagination Effect
useEffect(() => {
if (!open || zipTotalElements === -1) return;
// Correctly update query for pagination without mutation
const nextPage = curPage - 1;
if (searchQuery.page !== nextPage) {
const newQuery = { ...searchQuery, page: nextPage };
setSearchQuery(newQuery);
const fetchAddress = async () => {
const result = await findAddress(newQuery);
setZipSearchResults(result?.content || []);
};
fetchAddress();
}
}, [curPage, open, zipTotalElements]);
const handleCellClick = (index: any) => {
setSelectedZip(zipSearchResults[index]);
setIsSelectedZip(true);
setSelectedRowIndex(index);
};
const handleSearch = async (e: React.FormEvent) => {
e.preventDefault();
e.stopPropagation();
const query = { ...searchQuery, page: 0 };
setSearchQuery(query);
setCurPage(1);
setIsResetPage(true);
const result = await findAddress(query);
setZipSearchResults(result?.content || []);
setZipTotalElements(result?.totalElements || 0);
setTimeout(() => setIsResetPage(false), 100);
};
const handleConfirm = () => {
if (selectedZip) {
onSelect(selectedZip);
onOpenChange(false);
}
};
return (
<UiModal
headerTitle="주소 검색"
headerTitleClass="text-2xl font-bold text-gray-900"
open={open}
onOpenChange={onOpenChange}
bodyClass={`
${zipTotalElements > -1 ? 'h-[80vh]' : 'h-[30vh]'}
w-[30vw]
min-w-[500px]
max-w-[90vw]
min-h-[235px]
overflow-y-auto
!fixed
!top-[50%]
!left-[50%]
!-translate-x-1/2
!-translate-y-1/2
z-[101]
flex
flex-col
`}
body={
<>
<form
onSubmit={handleSearch}
className="mb-4 space-y-2"
>
<div className="card card-border !m-0 flex flex-col gap-4 p-4">
<div className="grid grid-cols-3 gap-4">
<div className="flex flex-col">
<Label className="mb-1 font-bold text-base">도로명</Label>
<Input
value={searchQuery.roadNm || ""}
onChange={(e) =>
setSearchQuery({
...searchQuery,
roadNm: e.target.value,
})
}
placeholder="예: 테헤란로"
className="!text-[1.3rem]"
/>
</div>
<div className="flex flex-col">
<Label className="mb-1 text-base">건물본번</Label>
<Input
type="number"
value={searchQuery.bldgNoMno ?? ""}
onChange={(e) => {
const value = e.target.value
? parseInt(e.target.value)
: null;
setSearchQuery({
...searchQuery,
bldgNoMno: value,
});
}}
placeholder="예: 123"
className="!text-[1.3rem]"
/>
</div>
<div className="flex flex-col">
<Label className="mb-1 text-base">건물부번</Label>
<Input
type="number"
value={searchQuery.bldgNoSno ?? ""}
onChange={(e) => {
const value = e.target.value
? parseInt(e.target.value)
: null;
setSearchQuery({
...searchQuery,
bldgNoSno: value,
});
}}
placeholder="예: 45"
className="!text-[1.3rem]"
/>
</div>
</div>
<div className="flex justify-end">
<Button className="rounded-md" type="submit">검색</Button>
</div>
</div>
</form>
{zipTotalElements > 0 && (
<UiTable
headName=''
tableData={zipSearchResults}
headlist={[{ id: 'zoneNo', title: '우편번호' }, { id: 'zipAddr', title: '주소' }]}
pageSize={PAGE_SIZE}
total={zipTotalElements}
cellClick={handleCellClick}
onPageChange={setCurPage}
resetPageNo={isResetPage}
resetSelection={isResetSelection}
index={selectedRowIndex}
/>
)}
{zipTotalElements === 0 && (
<div className={cn("flex h-96 flex-col items-center justify-center gap-4")}>
<i className="diveicon di-info-circle text-3xl" />
조회된 데이터가 없습니다.
</div>
)}
</>
}
footerContent={
<div className="w-full flex justify-center items-center gap-4">
<Button className="rounded-md" size="lg" onClick={handleConfirm} disabled={!isSelectedZip}>선택</Button>
<Button className="rounded-md" size="lg" onClick={() => onOpenChange(false)}>취소</Button>
</div>
}
useDirectRender={true}
/>
);
}
@@ -0,0 +1,118 @@
// const Key = 'U01TX0FVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA'
// const addresssKey = 'devU01TX0FVVEgyMDI1MDgyNTEwMzkwNDExNjEwNTM='; //인증키 만료일은 2025-11-23
import type { Zip, ZipSearchParams } from "./zipService";
/**
* 주소 API 응답 타입
* https://business.juso.go.kr/addrlink/main.do 해당 사이트 참조
*/
export type AddressApiResponse = {
results: {
common: {
errorMessage: string;
countPerPage: string;
totalCount: string;
errorCode: string;
currentPage: string;
};
juso: addressType[];
};
}
export type addressType = {
detBdNmList: string;
engAddr: string;
rn: string;
emdNm: string;
zipNo: string;
roadAddrPart2: string;
emdNo: string;
sggNm: string;
jibunAddr: string;
siNm: string;
roadAddrPart1: string;
bdNm: string;
admCd: string;
udrtYn: string;
lnbrMnnm: string;
roadAddr: string;
lnbrSlno: string;
buldMnnm: string;
bdKdcd: string;
liNm: string;
rnMgtSn: string;
mtYn: string;
bdMgtSn: string;
buldSlno: string;
}
/**
* 주소에 따른 검색
* @param search : 검색어
* @returns addressType[] 주소 배열
*/
export const findAddress = async (searchQuery: ZipSearchParams): Promise<any> => {
if (!searchQuery) return [];
// 쿼리 파라미터 생성
const params = new URLSearchParams();
if (searchQuery.roadNm) params.append('roadNm', searchQuery.roadNm);
if (searchQuery.bldgNoMno != null) params.append('bldgNoMno', searchQuery.bldgNoMno.toString());
if (searchQuery.bldgNoSno != null) params.append('bldgNoSno', searchQuery.bldgNoSno.toString());
if (searchQuery.page != null) params.append('page', searchQuery.page.toString());
if (searchQuery.size != null) params.append('size', searchQuery.size.toString());
const url = `/cms-service/api/v1/zips?${params.toString()}`;
try {
const response = await fetch(url);
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
if (data) return data
else return [];
} catch (error) {
console.error('Error fetching address data:', error);
return [];
}
}
export const searchFilter = (search: string) => {
if (search.length > 0) {
//특수문자 제거
const expText = /[%=><]/;
if (expText.test(search) == true) {
alert("특수문자를 입력 할수 없습니다.");
search = search.split(expText).join("");
return false;
}
//특정문자열(sql예약어의 앞뒤공백포함) 제거
const sqlArray = [
//sql 예약어
"OR", "SELECT", "INSERT", "DELETE", "UPDATE", "CREATE", "DROP", "EXEC",
"UNION", "FETCH", "DECLARE", "TRUNCATE"
]
let regex;
for (let i = 0; i < sqlArray.length; i++) {
regex = new RegExp(sqlArray[i] as string, "gi");
if (regex.test(search)) {
alert("\"" + sqlArray[i] + "\"와(과) 같은 특정문자로 검색할 수 없습니다.");
search = search.replace(regex, "");
return false;
}
}
}
return true;
}
@@ -0,0 +1,3 @@
export * from "./SearchAddressModal";
export * from "./findAddress";
export * from "./zipService";
@@ -0,0 +1,66 @@
interface SortConfig {
empty: boolean;
sorted: boolean;
unsorted: boolean;
}
interface PageableConfig {
sort: SortConfig;
offset: number;
pageNumber: number;
pageSize: number;
paged: boolean;
unpaged: boolean;
}
export interface PageableList<T> {
content: T[];
pageable: PageableConfig;
sort: SortConfig;
totalPages: number;
totalElements: number;
number: number;
numberOfElements: number;
size: number;
first: boolean;
last: boolean;
empty: boolean;
}
export interface PageableParams {
page?: number;
size?: number;
sort?: string;
}
export interface ZipSearchParams extends PageableParams {
zoneNo?: string; // 구역번호
ctpvNm?: string; // 시도명
sggNm?: string; // 시군구명
emdNm?: string; // 읍면동명
roadNm?: string; // 도로명
stdgNm?: string; // 법정동명
dongNm?: string; // 행정동명
bldgNoMno?: number | null; // 빌딩본번
bldgNoSno?: number | null; // 빌딩딩부번
lotnoMno?: number | null; // 지번본번
lotnoSno?: number | null; // 지번부번
}
export interface Zip {
zipId: number;
zoneNo: string;
ctpvNm: string;
sggNm: string;
emdNm: string;
roadNm: string;
bldgNoMno: number;
bldgNoSno: number;
lotnoMno: number;
lotnoSno: number;
lotno: string;
zipAddr: string;
}
export type ZipList = PageableList<Zip>;
@@ -119,7 +119,6 @@ export function UiTable({
};
const leafCols = getLeafCols(headlist);
return (
<>
{headName ? (
@@ -263,7 +262,11 @@ export function UiTable({
<TableCell
colSpan={
headlist.filter((item) => item.visible != false).length -
headlist.filter((item) => item.visible != false && item.colSpan).length
headlist.filter(
(item) =>
item.visible != false &&
(item.colSpan || ["A", "B", "C"].includes(item.id)),
).length
}
className="h-24 text-center text-gray-500"
>
@@ -274,10 +274,10 @@ export function Header({ viewOnly }: { viewOnly?: boolean }) {
<SidebarTrigger className="size-12 !bg-transparent p-2 hover:!bg-accent [&>svg]:!size-full [&>svg]:text-foreground" />
<h1 className="flex flex-col items-center gap-2">
{mounted ? (
<img
<img
ref={logoRef}
src={getLogoImage()}
className="h-[3rem]"
src={getLogoImage()}
className="h-[3rem]"
alt="logo"
onLoad={() => {
if (logoRef.current) {
@@ -288,7 +288,7 @@ export function Header({ viewOnly }: { viewOnly?: boolean }) {
) : (
<Skeleton className="h-[3rem] w-[15rem]" />
)}
<span
<span
className="text-[1.2rem] font-semibold text-foreground"
style={{
letterSpacing: logoWidth > 0 ? `${(logoWidth - 120) / (siteInfo?.siteNm?.length || 1)}px` : '0.05em'