This commit is contained in:
@@ -2,11 +2,12 @@
|
||||
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { type customLdrmntBdst } from "@/app/store/matDmd/ldrmntCoSttn";
|
||||
import { ldrmntNodeListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList";
|
||||
import { type customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn";
|
||||
import { ldrmntHeadListExport, ldrmntNodeListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList";
|
||||
import {
|
||||
excelDownload,
|
||||
getCity,
|
||||
getCityOrSgg,
|
||||
tableData
|
||||
} from "@/components/lib/func/commom";
|
||||
import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcelModal";
|
||||
@@ -34,23 +35,20 @@ export default function LdrmntCoSttn() {
|
||||
(state) => state
|
||||
);
|
||||
const { ldrmntRes } = ldrmnt;
|
||||
const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customLdrmntBdst | undefined }>({ data: undefined, isOpen: false })
|
||||
const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customLdrmnt | undefined }>({ data: undefined, isOpen: false })
|
||||
const [pageNation, setPageNation] = useState(1);
|
||||
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
|
||||
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
|
||||
const ref = useRef<ReturnType>({} as ReturnType);
|
||||
const [bdstTable, setBdstTable] = useState<customLdrmntBdst[]>();
|
||||
const [codeData, setCodeData] = useState<string>();
|
||||
const [bdstTable, setBdstTable] = useState<customLdrmnt[]>();
|
||||
const [searchTxt, setSearchTxt] = useState<string>();
|
||||
const [bdstChgProps, setBdstChgProps] = useState<{
|
||||
isOpen: boolean;
|
||||
data: customLdrmntBdst[];
|
||||
}>({ isOpen: false, data: [] });
|
||||
const ref = useRef<ReturnType>({} as ReturnType);
|
||||
const codeData = getCityOrSgg(ref);
|
||||
|
||||
const excelClick = useCallback(() => {
|
||||
excelDownload(
|
||||
[[]],
|
||||
"잠재수요처 관리",
|
||||
"sample_ldrmnt.xlsx",
|
||||
"sample_ldrmntCoSttn.xlsx",
|
||||
"A1:AL1",
|
||||
2
|
||||
);
|
||||
@@ -80,17 +78,19 @@ export default function LdrmntCoSttn() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!ldrmnt.isInit) {
|
||||
ldrmntInit();
|
||||
ldrmntInit(codeData ?? "0");
|
||||
}
|
||||
}, [ldrmnt.isInit, ldrmntInit]);
|
||||
|
||||
useEffect(() => {
|
||||
const data = tableData(ldrmntRes, { code });
|
||||
const transData = Array.isArray(ldrmntRes) ? ldrmntRes : [ldrmntRes];
|
||||
const data = tableData(transData, { code });
|
||||
const tbData = Array.isArray(data)
|
||||
? data.map((item: customLdrmntBdst) => ({
|
||||
? data.map((item: customLdrmnt) => ({
|
||||
...item,
|
||||
ctpvCd: item.fctryAddr.split(" ")[0] || "",
|
||||
ctpvCd: item.fctryAddr.split(" ")[0] || "",
|
||||
sggCd: item.fctryAddr.split(" ")[1] || ""
|
||||
|
||||
}))
|
||||
: [];
|
||||
|
||||
@@ -202,7 +202,7 @@ export default function LdrmntCoSttn() {
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={bdstTable || []}
|
||||
headlist={ldrmntNodeListExport}
|
||||
headlist={ldrmntHeadListExport}
|
||||
pageSize={20}
|
||||
total={10000}
|
||||
cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }}
|
||||
|
||||
@@ -1,81 +1,264 @@
|
||||
"use client";
|
||||
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { yearOptions } from "@/components/lib/func/commom";
|
||||
import type { RainStatProps } from "@/app/store/stats/rainStat";
|
||||
import { excelDownload, tableData, yearOptions } from "@/components/lib/func/commom";
|
||||
import { downloadExcel } from "@common/business_components";
|
||||
|
||||
import {
|
||||
ContentsDiv,
|
||||
ScrollArea,
|
||||
SearchDiv,
|
||||
SearchFormLeft,
|
||||
SelectBox,
|
||||
Title,
|
||||
UiTable,
|
||||
UiTable
|
||||
} from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Button } from "@common/components/ui";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function RainStat() {
|
||||
const { code, rainStat, searchRainStatList } = useWrStore((state) => state);
|
||||
const { rainStatList, excelList, rainDetailList } = rainStat;
|
||||
|
||||
export default function rainStat() {
|
||||
const { code, rainStat } = useWrStore((state) => {
|
||||
return state;
|
||||
});
|
||||
const [pageNation, setPageNation] = useState(1);
|
||||
const [searchYear, setSearchYear] = useState<string>(
|
||||
String(new Date().getFullYear())
|
||||
);
|
||||
const [exData, setExData] = useState<Array<Record<string, string | number>>>();
|
||||
const [bdstTable, setBdstTable] = useState<RainStatProps[]>();
|
||||
|
||||
useEffect(() => {
|
||||
searchRainStatList(searchYear);
|
||||
}, [code.cityCd, code.sggCd, searchRainStatList, searchYear])
|
||||
|
||||
const excelDetailDownLoad=() =>{
|
||||
const sidoList = new Set<string>();
|
||||
const sidoDataMap = new Map<string, (string | number)[]>(); // 시도별 데이터를 저장할 Map
|
||||
const sidoDetailMap = new Map<string, (string | number)[][]>(); // 시도별 상세 데이터를 저장할 Map
|
||||
|
||||
// 먼저 시도별 상세 데이터를 그룹화
|
||||
rainDetailList.forEach((item: RainStatProps[]) => {
|
||||
const sidoVal = item.at(0)?.toString().trim();
|
||||
const sigunVal = item.at(1)?.toString().trim();
|
||||
|
||||
let sidoText = '';
|
||||
let sigunText = '';
|
||||
|
||||
const sido = code.cityCd.find((city) => city.val === sidoVal);
|
||||
const sigun = code.sggCd.find((sgg) => sgg.val === sigunVal);
|
||||
|
||||
sidoText = sido?.text || '';
|
||||
sigunText = sigun?.text || '';
|
||||
|
||||
// 시도, 시군구 코드를 텍스트로 변환하여 데이터에 할당
|
||||
if (item.length > 0) {
|
||||
item[0] = sidoText as unknown as RainStatProps;
|
||||
}
|
||||
if (item.length > 1) {
|
||||
item[1] = sigunText as unknown as RainStatProps;
|
||||
}
|
||||
if (item.length > 2) {
|
||||
item[2] = sidoText+' '+sigunText as unknown as RainStatProps;
|
||||
}
|
||||
|
||||
// 시도별 상세 데이터 수집
|
||||
if (sidoText) {
|
||||
if (!sidoDetailMap.has(sidoText)) {
|
||||
sidoDetailMap.set(sidoText, []);
|
||||
}
|
||||
sidoDetailMap.get(sidoText)!.push(item as unknown as (string | number)[]);
|
||||
}
|
||||
|
||||
// 시도별 합계 데이터 수집
|
||||
if (sidoText && !sidoList.has(sidoText)) {
|
||||
sidoList.add(sidoText);
|
||||
// 시도별 초기 데이터 구조 생성 (예: [시도명, 0, 0, 0, ...])
|
||||
const initialData: (string | number)[] = [sidoText];
|
||||
// 데이터의 나머지 컬럼들을 0으로 초기화 (실제 컬럼 수에 맞게 조정 필요)
|
||||
for (let i = 1; i < item.length; i++) {
|
||||
initialData.push(0);
|
||||
}
|
||||
sidoDataMap.set(sidoText, initialData);
|
||||
}
|
||||
});
|
||||
|
||||
// 시도별 합계 계산
|
||||
rainDetailList.forEach((item: RainStatProps[]) => {
|
||||
const sidoText = item[0]?.toString();
|
||||
if (sidoText && sidoDataMap.has(sidoText)) {
|
||||
const sidoData = sidoDataMap.get(sidoText)!;
|
||||
// 각 컬럼의 값을 합계에 더하기 (1번 인덱스부터 시작)
|
||||
for (let i = 1; i < item.length && i < sidoData.length; i++) {
|
||||
if(i == 2){
|
||||
sidoData[i] = '합계';
|
||||
} else if(i == 3){
|
||||
// 해당 시도의 데이터 개수를 계산
|
||||
const sidoDataCount = rainDetailList.filter((data: unknown[]) =>
|
||||
Array.isArray(data) && data.length > 0 && String(data[0]) === sidoText
|
||||
).length;
|
||||
sidoData[i] = sidoDataCount;
|
||||
} else if( i == 4){
|
||||
sidoData[i] = '';
|
||||
} else if(i == 6){
|
||||
// 법정 대상 건축물 개수 (인덱스 6이 'Y'인 경우)
|
||||
const bumCnt = rainDetailList.filter((data: unknown[]) =>
|
||||
Array.isArray(data) && data.length > 6 && String(data[0]) === sidoText
|
||||
).filter((data: unknown[]) => String(data[6]) === '대상').length;
|
||||
sidoData[i] = bumCnt;
|
||||
} else if(i==8){
|
||||
const value = Number(item[8]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==11){
|
||||
const value = Number(item[11]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==12){
|
||||
const value = Number(item[12]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==14){
|
||||
const value = Number(item[14]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
}
|
||||
else {
|
||||
sidoData[i] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 시도별로 합계와 상세 데이터를 순서대로 배치
|
||||
const summaryExcelData: (string | number)[][] = [];
|
||||
|
||||
// 시도별로 순회하면서 합계와 상세 데이터를 추가
|
||||
Array.from(sidoList).forEach((sidoText) => {
|
||||
const sidoSummary = sidoDataMap.get(sidoText);
|
||||
const sidoDetails = sidoDetailMap.get(sidoText) || [];
|
||||
|
||||
if (sidoSummary) {
|
||||
// 시도 합계 데이터 추가
|
||||
summaryExcelData.push(sidoSummary);
|
||||
// 해당 시도의 상세 데이터들 추가
|
||||
sidoDetails.forEach(detail => {
|
||||
summaryExcelData.push(detail);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const sidoSummaryList = Array.from(sidoDataMap.values());
|
||||
// sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성
|
||||
const excelData = [...sidoSummaryList, ...summaryExcelData];
|
||||
|
||||
excelDownload(
|
||||
excelData as unknown as [][],
|
||||
"빗물이용시설 통계",
|
||||
"sample_rainStats.xlsx",
|
||||
"A1:V3",
|
||||
4
|
||||
);
|
||||
}
|
||||
|
||||
const excelClick = () => {
|
||||
downloadExcel({
|
||||
data: (exData as unknown as JSON[]) ?? [],
|
||||
fileName: "재이용통계",
|
||||
sheetNameArray: ["Sheet1"],
|
||||
headerRange: "A1:M1"
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const transExcel = Array.isArray(excelList) ? excelList : [excelList];
|
||||
const excelData = tableData(transExcel, { code });
|
||||
const tbData = Array.isArray(excelData)
|
||||
? excelData.map((item: RainStatProps) => {
|
||||
return {
|
||||
"시도": item.ctpvCd,
|
||||
"개소": item.tmp,
|
||||
"설치비(백만원)": item.instlCst,
|
||||
"저류조용량(m³/년)": item.dtfcltCpct,
|
||||
"연간사용량(m³/년)": item.wtrUsqty,
|
||||
"조경용수": item.lndwtr,
|
||||
"청소화장실용수": item.cleanToilUswtr,
|
||||
"세척살수용수": item.resn,
|
||||
"농업용수": item.farmUswtr,
|
||||
"공업용수": item.indstUswtr,
|
||||
"친수용수": item.hydUswtr,
|
||||
"기타": item.ithlEtcUswtr,
|
||||
"연간운영비(백만원/년)": item.anlOperCst,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
setExData(tbData);
|
||||
}, [code, excelList])
|
||||
|
||||
useEffect(() => {
|
||||
const transData = Array.isArray(rainStatList) ? rainStatList : [rainStatList];
|
||||
const data = tableData(transData, { code });
|
||||
const tbData = Array.isArray(data)
|
||||
? data.map((item: RainStatProps) => {
|
||||
return {
|
||||
...item,
|
||||
ctpvCd: item.ctpvCd
|
||||
};
|
||||
})
|
||||
: [];
|
||||
setBdstTable(tbData);
|
||||
}, [code, rainStatList]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"재이용 통계"} />
|
||||
<Title title={"빗물이용시설 통계"} />
|
||||
<SearchDiv>
|
||||
<SearchFormLeft>
|
||||
<SelectBox
|
||||
className="w-full h-full text-2xl"
|
||||
label="통계년도"
|
||||
selectClass={""}
|
||||
selectArray={yearOptions}
|
||||
value={searchYear}
|
||||
onSelectValue={(val: string | number) =>
|
||||
setSearchYear(String(val))
|
||||
}
|
||||
/>
|
||||
<div className="grid grid-cols-12 gap-5 m-4">
|
||||
<div className="col-span-2">
|
||||
<SelectBox
|
||||
className="w-full h-full text-2xl"
|
||||
label="통계년도"
|
||||
selectClass={""}
|
||||
selectArray={yearOptions}
|
||||
value={searchYear}
|
||||
onSelectValue={(val: string | number) =>
|
||||
setSearchYear(String(val))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row space-x-2 items-center">
|
||||
<Button className="" size={"sm"} onClick={(e) => {}}>
|
||||
<Button className="" size={"sm"} onClick={() => { }}>
|
||||
조회
|
||||
</Button>
|
||||
<Button className="" size={"sm"} onClick={(e) => {}}>
|
||||
<Button className="" size={"sm"} onClick={() => excelClick()}>
|
||||
다운로드
|
||||
</Button>
|
||||
<Button className="" size={"sm"} onClick={(e) => {}}>
|
||||
<Button className="" size={"sm"} onClick={() => excelDetailDownLoad()}>
|
||||
전체통계다운로드
|
||||
</Button>
|
||||
</div>
|
||||
</SearchFormLeft>
|
||||
{/* <SearchFormRight>
|
||||
|
||||
</SearchFormRight> */}
|
||||
</div>
|
||||
</SearchDiv>
|
||||
{/* <SearchFormRight>
|
||||
</SearchFormRight> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-6 gap-4">
|
||||
<div className="col-span-6 h-full min-h-0">
|
||||
<ListDiv className="min-h-0">
|
||||
{/* <ScrollArea className="h-[60vh]"> */}
|
||||
<UiTable
|
||||
tableData={[]}
|
||||
headlist={rainStat.rainStatHeadList}
|
||||
pageSize={20}
|
||||
total={10000}
|
||||
headName={"건축물 목록"}
|
||||
cellClick={(val, headId) => {}}
|
||||
onPageChange={setPageNation}
|
||||
></UiTable>
|
||||
{/* </ScrollArea> */}
|
||||
<ListDiv className="">
|
||||
<ScrollArea className="h-[67vh]">
|
||||
<UiTable
|
||||
tableData={bdstTable || []}
|
||||
headlist={rainStat.rainStatHeadList}
|
||||
pageSize={10}
|
||||
total={0}
|
||||
headName={""}
|
||||
cellClick={undefined}
|
||||
onPageChange={() => {}}
|
||||
></UiTable>
|
||||
</ScrollArea>
|
||||
</ListDiv>
|
||||
</div>
|
||||
</div>
|
||||
</ContentsDiv>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,75 +1,278 @@
|
||||
'use client'
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { yearOptions } from "@/components/lib/func/commom";
|
||||
import { ContentsDiv, SearchDiv, SearchFormLeft, SelectBox, Title, UiTable } from "@common/business_components/ui";
|
||||
import type { RswtStatProps } from "@/app/store/stats/rswtStat";
|
||||
import { excelDownload, tableData, yearOptions } from "@/components/lib/func/commom";
|
||||
import {
|
||||
ContentsDiv,
|
||||
downloadExcel,
|
||||
ScrollArea,
|
||||
SearchDiv,
|
||||
SelectBox,
|
||||
Title,
|
||||
UiTable
|
||||
} from "@common/business_components/ui";
|
||||
import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Button } from "@common/components/ui";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function RswtStat() {
|
||||
const { code, rswtStat } = useWrStore((state) => {
|
||||
return state;
|
||||
});
|
||||
const [pageNation, setPageNation] = useState(1);
|
||||
const { code, rswtStat, searchRswtStatList } = useWrStore((state) => state);
|
||||
const { rswtStatList, excelList, rswtDetailList } = rswtStat;
|
||||
const [rswtTable, setRswtTable] = useState<RswtStatProps[]>();
|
||||
const [searchYear, setSearchYear] = useState<string>(
|
||||
String(new Date().getFullYear())
|
||||
);
|
||||
const [excelData, setExceData] = useState<Record<string, string | number>[]>();
|
||||
|
||||
return(
|
||||
<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title={"재이용 통계"} />
|
||||
<SearchDiv>
|
||||
<SearchFormLeft>
|
||||
useEffect(() => {
|
||||
searchRswtStatList(searchYear)
|
||||
}, [searchRswtStatList, searchYear])
|
||||
|
||||
const excelClick = () => {
|
||||
downloadExcel({
|
||||
data: (excelData as unknown as JSON[]) ?? [],
|
||||
fileName: "중수도재이용통계",
|
||||
sheetNameArray: ["Sheet1"],
|
||||
headerRange: "A1:O1"
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const transData = Array.isArray(rswtStatList) ? rswtStatList : [rswtStatList];
|
||||
const data = tableData(transData, { code });
|
||||
const tbData = Array.isArray(data)
|
||||
? data.map((item: RswtStatProps) => {
|
||||
return {
|
||||
...item,
|
||||
ctpvCd: item.ctpvCd
|
||||
};
|
||||
})
|
||||
: [];
|
||||
setRswtTable(tbData);
|
||||
}, [code, rswtStatList])
|
||||
|
||||
useEffect(() => {
|
||||
const transExcel = Array.isArray(excelList) ? excelList : [excelList];
|
||||
const exData = tableData(transExcel, { code });
|
||||
const tbData = Array.isArray(exData) ?
|
||||
exData.map((item: RswtStatProps) => {
|
||||
return {
|
||||
"시도": item.ctpvCd,
|
||||
"개소": item.ctpvCnt,
|
||||
"건축연면적(m³)": item.archArea,
|
||||
"처리용량(m³)": item.filtrTrtmfctCpct,
|
||||
"물사용량(m³/년)": item.wtrUsqty,
|
||||
"중수도+대체수이용량(m³/년)": item.rswtAltSum,
|
||||
"중수도이용량(m³/년)": item.rswtrUsqty,
|
||||
"대체수이용량(m³/년)": item.altUswtrUtztnQnt,
|
||||
"조경용수": item.lndwtr,
|
||||
"청소화장실용수": item.cleanToilUswtr,
|
||||
"농업용수": item.farmUswtr,
|
||||
"공업용수": item.indstUswtr,
|
||||
"친수용수": item.hydUswtr,
|
||||
"기타": item.ithlEtcUswtr,
|
||||
"연간운영비(백만원/년)": item.anlOperCst,
|
||||
};
|
||||
}) : [];
|
||||
setExceData(tbData);
|
||||
}, [code, excelList])
|
||||
|
||||
const excelDetailDownLoad=() =>{
|
||||
const sidoList = new Set<string>();
|
||||
const sidoDataMap = new Map<string, (string | number)[]>(); // 시도별 데이터를 저장할 Map
|
||||
const sidoDetailMap = new Map<string, (string | number)[][]>(); // 시도별 상세 데이터를 저장할 Map
|
||||
|
||||
// 먼저 시도별 상세 데이터를 그룹화
|
||||
rswtDetailList.forEach((item: RswtStatProps[]) => {
|
||||
const sidoVal = item.at(0)?.toString().trim();
|
||||
const sigunVal = item.at(1)?.toString().trim();
|
||||
let sidoText = '';
|
||||
let sigunText = '';
|
||||
|
||||
const sido = code.cityCd.find((city) => city.val === sidoVal);
|
||||
const sigun = code.sggCd.find((sgg) => sgg.val === sigunVal);
|
||||
|
||||
sidoText = sido?.text || '';
|
||||
sigunText = sigun?.text || '';
|
||||
|
||||
// 시도, 시군구 코드를 텍스트로 변환하여 데이터에 할당
|
||||
if (item.length > 0) {
|
||||
item[0] = sidoText as unknown as RswtStatProps;
|
||||
}
|
||||
if (item.length > 1) {
|
||||
item[1] = sigunText as unknown as RswtStatProps;
|
||||
}
|
||||
if (item.length > 2) {
|
||||
item[2] = sidoText+' '+sigunText as unknown as RswtStatProps;
|
||||
}
|
||||
|
||||
// 시도별 상세 데이터 수집
|
||||
if (sidoText) {
|
||||
if (!sidoDetailMap.has(sidoText)) {
|
||||
sidoDetailMap.set(sidoText, []);
|
||||
}
|
||||
sidoDetailMap.get(sidoText)!.push(item as unknown as (string | number)[]);
|
||||
}
|
||||
|
||||
// 시도별 합계 데이터 수집
|
||||
if (sidoText && !sidoList.has(sidoText)) {
|
||||
sidoList.add(sidoText);
|
||||
// 시도별 초기 데이터 구조 생성 (예: [시도명, 0, 0, 0, ...])
|
||||
const initialData: (string | number)[] = [sidoText];
|
||||
// 데이터의 나머지 컬럼들을 0으로 초기화 (실제 컬럼 수에 맞게 조정 필요)
|
||||
for (let i = 1; i < item.length; i++) {
|
||||
initialData.push(0);
|
||||
}
|
||||
sidoDataMap.set(sidoText, initialData);
|
||||
}
|
||||
});
|
||||
|
||||
// 시도별 합계 계산
|
||||
rswtDetailList.forEach((item: RswtStatProps[]) => {
|
||||
const sidoText = item[0]?.toString();
|
||||
if (sidoText && sidoDataMap.has(sidoText)) {
|
||||
const sidoData = sidoDataMap.get(sidoText)!;
|
||||
// 각 컬럼의 값을 합계에 더하기 (1번 인덱스부터 시작)
|
||||
for (let i = 1; i < item.length && i < sidoData.length; i++) {
|
||||
if(i == 2){
|
||||
sidoData[i] = '합계';
|
||||
} else if(i == 3){
|
||||
// 해당 시도의 데이터 개수를 계산
|
||||
const sidoDataCount = rswtDetailList.filter((data: unknown[]) =>
|
||||
Array.isArray(data) && data.length > 0 && String(data[0]) === sidoText
|
||||
).length;
|
||||
sidoData[i] = sidoDataCount;
|
||||
} else if( i == 4){
|
||||
sidoData[i] = '';
|
||||
} else if(i == 6){
|
||||
// 법정 대상 건축물 개수 (인덱스 6이 'Y'인 경우)
|
||||
const bumCnt = rswtDetailList.filter((data: unknown[]) =>
|
||||
Array.isArray(data) && data.length > 6 && String(data[0]) === sidoText
|
||||
).filter((data: unknown[]) => String(data[6]) === '대상').length;
|
||||
sidoData[i] = bumCnt;
|
||||
} else if(i==9){
|
||||
const value = Number(item[9]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==10){
|
||||
const value = Number(item[10]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==11){
|
||||
const value = Number(item[11]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==12){
|
||||
const value = Number(item[12]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
}else if(i==13){
|
||||
const value = Number(item[13]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==14){
|
||||
const value = Number(item[14]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else if(i==16){
|
||||
const value = Number(item[16]) || 0;
|
||||
sidoData[i] = (Number(sidoData[i]) + value) as string | number;
|
||||
} else {
|
||||
sidoData[i] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 시도별로 합계와 상세 데이터를 순서대로 배치
|
||||
const summaryExcelData: (string | number)[][] = [];
|
||||
|
||||
// 시도별로 순회하면서 합계와 상세 데이터를 추가
|
||||
Array.from(sidoList).forEach((sidoText) => {
|
||||
const sidoSummary = sidoDataMap.get(sidoText);
|
||||
const sidoDetails = sidoDetailMap.get(sidoText) || [];
|
||||
|
||||
if (sidoSummary) {
|
||||
// 시도 합계 데이터 추가
|
||||
summaryExcelData.push(sidoSummary);
|
||||
// 해당 시도의 상세 데이터들 추가
|
||||
sidoDetails.forEach(detail => {
|
||||
summaryExcelData.push(detail);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const sidoSummaryList = Array.from(sidoDataMap.values());
|
||||
// sidoSummaryList와 rainDetailList를 합쳐서 엑셀 데이터 생성
|
||||
const excelData = [...sidoSummaryList, ...summaryExcelData];
|
||||
|
||||
excelDownload(
|
||||
excelData as unknown as [][],
|
||||
"중수도시설 통계",
|
||||
"sample_rswtStats.xlsx",
|
||||
"A1:Q3",
|
||||
4
|
||||
);
|
||||
}
|
||||
|
||||
return (<>
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<Title title="중수도시설 통계" />
|
||||
<SearchDiv>
|
||||
<div className="grid grid-cols-12 gap-5 m-4">
|
||||
<div className="col-span-2">
|
||||
<SelectBox
|
||||
className="w-full h-full text-2xl"
|
||||
label="통계년도"
|
||||
selectClass={""}
|
||||
selectClass=""
|
||||
selectArray={yearOptions}
|
||||
value={searchYear}
|
||||
onSelectValue={(val: string | number) =>
|
||||
setSearchYear(String(val))
|
||||
}
|
||||
onSelectValue={(val: string | number) => setSearchYear(String(val))}
|
||||
/>
|
||||
<div className="flex flex-row space-x-2 items-center">
|
||||
<Button className="" size={"sm"} onClick={(e) => {}}>
|
||||
조회
|
||||
</Button>
|
||||
<Button className="" size={"sm"} onClick={(e) => {}}>
|
||||
다운로드
|
||||
</Button>
|
||||
<Button className="" size={"sm"} onClick={(e) => {}}>
|
||||
전체통계다운로드
|
||||
</Button>
|
||||
</div>
|
||||
</SearchFormLeft>
|
||||
{/* <SearchFormRight>
|
||||
|
||||
</SearchFormRight> */}
|
||||
</SearchDiv>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row space-x-2 items-center">
|
||||
<Button
|
||||
className=""
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
searchRswtStatList(searchYear)
|
||||
}}
|
||||
>
|
||||
조회
|
||||
</Button>
|
||||
<Button
|
||||
className=""
|
||||
size="sm"
|
||||
onClick={() => excelClick()}
|
||||
>
|
||||
다운로드
|
||||
</Button>
|
||||
<Button
|
||||
className=""
|
||||
size="sm"
|
||||
onClick={() => { excelDetailDownLoad() }}
|
||||
>
|
||||
전체통계다운로드
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SearchDiv>
|
||||
</div>
|
||||
<div className="grid grid-cols-6 gap-4">
|
||||
<div className="col-span-6 h-full min-h-0">
|
||||
<ListDiv className="min-h-0">
|
||||
{/* <ScrollArea className="h-[60vh]"> */}
|
||||
</div>
|
||||
<div className="grid grid-cols-6 gap-4">
|
||||
<div className="col-span-6 h-full min-h-0">
|
||||
<ListDiv className="">
|
||||
<ScrollArea className="h-[67vh]">
|
||||
<UiTable
|
||||
tableData={[]}
|
||||
tableData={rswtTable || []}
|
||||
headlist={rswtStat.rswtStatHeadList}
|
||||
pageSize={20}
|
||||
total={10000}
|
||||
headName={"건축물 목록"}
|
||||
cellClick={(val, headId) => {}}
|
||||
onPageChange={setPageNation}
|
||||
></UiTable>
|
||||
{/* </ScrollArea> */}
|
||||
</ListDiv>
|
||||
</div>
|
||||
pageSize={10}
|
||||
total={0}
|
||||
headName=""
|
||||
cellClick={undefined}
|
||||
onPageChange={() => { }}
|
||||
/>
|
||||
</ScrollArea>
|
||||
</ListDiv>
|
||||
</div>
|
||||
</ContentsDiv>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
</div>
|
||||
</ContentsDiv>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -46,16 +46,30 @@ export const names: nameMap = {
|
||||
}
|
||||
|
||||
|
||||
export const excelToLdrmntData = (excelData: File[],) => {
|
||||
export const excelPbnstSttnParsing = (data: any[]): string[][] => {
|
||||
|
||||
const ldrmntData = Object.values(excelData);
|
||||
const data = ldrmntData.map((item) => {
|
||||
const excelExportData: string[][] = [];
|
||||
|
||||
return ({
|
||||
...(item as object),
|
||||
rgtr: TEST_UUID,
|
||||
mdfr: TEST_UUID,
|
||||
})
|
||||
data.forEach((item) => {
|
||||
excelExportData.push([
|
||||
item.rvbsn,
|
||||
String(item.lgbsn),
|
||||
item.mdmbsn ?? "",
|
||||
item.rgnNm ?? "",
|
||||
String(item.sido ?? ""),
|
||||
String(item.gugun ?? ""),
|
||||
String(item.bscFctNm ?? ""),
|
||||
String(item.efflWqltStndrdNm ?? ""),
|
||||
String(item.fctCpc ?? ""),
|
||||
String(item.tel ?? ""),
|
||||
String(item.ruseUtztnFcltNm ?? ""),
|
||||
String(item.fcltCpct ?? ""),
|
||||
String(item.splyExtraCpct ?? ""),
|
||||
String(item.ruseCpct ?? ""),
|
||||
String(item.usageTotal ?? ""),
|
||||
String(item.inUsage ?? ""),
|
||||
String(item.outUsage ?? ""),
|
||||
])
|
||||
})
|
||||
return data;
|
||||
return excelExportData;
|
||||
};
|
||||
@@ -1,10 +1,12 @@
|
||||
import { z } from "zod";
|
||||
import type { CommonTableProps } from "../../common/type/header";
|
||||
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
|
||||
|
||||
export const ldrmntZod = z.object({
|
||||
fctryMngSn: z.string().default(''),
|
||||
ctpvCd: z.string().default(''),
|
||||
sggCd: z.string().default(''),
|
||||
mngInst: z.string().default('').nullish(),
|
||||
mngInstNm: z.string().default('').nullish(),
|
||||
dmdCoNm: z.string().default(''),
|
||||
fctrySe: z.string().default(''),
|
||||
cmpxNm: z.string().default(''),
|
||||
@@ -40,6 +42,7 @@ export const ldrmntZod = z.object({
|
||||
fctryAddr: z.string().default(''),
|
||||
fctryLotnoAddr: z.string().default(''),
|
||||
fctryMngNo: z.string().default(''),
|
||||
rgtr:z.string().default(TEST_UUID).nullish()
|
||||
})
|
||||
|
||||
export const ldrmntHeadListExport: CommonTableProps[] = [
|
||||
@@ -111,7 +114,7 @@ export const ldrmntNodeListExport: CommonTableProps[] = [
|
||||
colSpan: 1,
|
||||
},
|
||||
{
|
||||
id: "mngInst",
|
||||
id: "mngInstNm",
|
||||
title: "관리기관",
|
||||
visible: true,
|
||||
row: 1,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { CommonTableProps } from "@/app/store/common/type/header";
|
||||
import { fetchType, getFetch, postFectch, putFectch } from "@/components/lib/api";
|
||||
import { deleteFectch, fetchType, getFetch, postFectch, putFectch } from "@/components/lib/api";
|
||||
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
|
||||
import { z } from "zod";
|
||||
import { ldrmntHeadListExport, ldrmntNodeListExport, ldrmntZod } from "./headList";
|
||||
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
|
||||
|
||||
|
||||
|
||||
@@ -10,9 +11,9 @@ import { ldrmntHeadListExport, ldrmntNodeListExport, ldrmntZod } from "./headLis
|
||||
const ldrmntHeadList = ldrmntHeadListExport;
|
||||
const ldrmntNodeList = ldrmntNodeListExport;
|
||||
|
||||
export type customLdrmntBdst = z.infer<typeof ldrmntZod>;
|
||||
export type customLdrmnt = z.infer<typeof ldrmntZod>;
|
||||
|
||||
const ldrmntRes: customLdrmntBdst[] = [];
|
||||
const ldrmntRes: customLdrmnt[] = [];
|
||||
|
||||
export type ldrmntState = {
|
||||
ldrmnt: {
|
||||
@@ -20,14 +21,16 @@ export type ldrmntState = {
|
||||
ldrmntNodeList: CommonTableProps[];
|
||||
excelList: [];
|
||||
isInit: boolean;
|
||||
ldrmntRes: customLdrmntBdst[];
|
||||
ldrmntRes: customLdrmnt[];
|
||||
};
|
||||
};
|
||||
|
||||
type ldrmntActions = {
|
||||
ldrmntRegData: (data: any[]) => void,
|
||||
ldrmntInit: () => void;
|
||||
ldrmntInit: (con: string) => void
|
||||
ldrmntSearch: (sggCd: string, coNm: string) => void;
|
||||
ldrmntUpdate: (ldrmntRes: customLdrmnt) => void;
|
||||
ldrmntDelete: () => void;
|
||||
};
|
||||
|
||||
export type ldrmntType = ldrmntState & ldrmntActions;
|
||||
@@ -46,20 +49,24 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
|
||||
set: any
|
||||
) => {
|
||||
return {
|
||||
ldrmntInit: async () => {
|
||||
ldrmntInit: async (con: string) => {
|
||||
try {
|
||||
console.log("con", con)
|
||||
const ldrmntRes = await getFetch(
|
||||
fetchType.WR,
|
||||
`/reuseFc/request/temp/1/20/0`
|
||||
`/reuseFc/request/temp/1/20/${con}`
|
||||
);
|
||||
return set((state: ldrmntState) => ({
|
||||
...state,
|
||||
rain: {
|
||||
...state.ldrmnt,
|
||||
ldrmntRes: ldrmntRes,
|
||||
isInit: false,
|
||||
},
|
||||
}));
|
||||
console.log("initres", ldrmntRes)
|
||||
set((state: ldrmntState) => {
|
||||
return {
|
||||
...state,
|
||||
ldrmnt: {
|
||||
...state.ldrmnt,
|
||||
ldrmntRes: ldrmntRes,
|
||||
isInit: false,
|
||||
},
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
@@ -124,17 +131,36 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
ldrmntUpdate: async (ldrmntRes: customLdrmntBdst[]) => {
|
||||
ldrmntUpdate: async (ldrmntRes: customLdrmnt) => {
|
||||
try {
|
||||
|
||||
ldrmntRes.rgtr = TEST_UUID;
|
||||
console.log("ldrmntRes", ldrmntRes);
|
||||
const response = await putFectch(
|
||||
`/reuseFc/request/temp`,
|
||||
ldrmntRes
|
||||
);
|
||||
|
||||
return set((state: ldrmntState) => ({
|
||||
...state,
|
||||
ldrmnt: {
|
||||
...state.ldrmnt,
|
||||
ldrmntRes: ldrmntRes,
|
||||
},
|
||||
}));
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error ldrmntUpdate:", error);
|
||||
}
|
||||
},
|
||||
ldrmntDelete: async () => {
|
||||
try {
|
||||
const response = await deleteFectch(
|
||||
`/reuseFc/request/temp`,
|
||||
);
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error ldrmntDelete:", error);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { RainStatProps } from ".";
|
||||
|
||||
export const excelRainStat = (excelList:RainStatProps[]) : (string | number)[][] => {
|
||||
const excelData: (string | number)[][] = [];
|
||||
excelList.forEach((item) => {
|
||||
excelData.push([
|
||||
//시도
|
||||
item.ctpvCd ?? "",
|
||||
//시군구
|
||||
item.sggCd ?? "",
|
||||
//행정구역명
|
||||
String(item.areaNm) ?? "",
|
||||
//시설명
|
||||
String(item.bdstNm) ?? "",
|
||||
//건축물용도코드 (값 없음)
|
||||
//String(item.bdstUsgCd) ?? "",
|
||||
"",
|
||||
//주소
|
||||
String(item.daddr) ?? "",
|
||||
//법적의무대상여부
|
||||
String(item.lawTrgtYn)==="Y" ? "대상" : "미대상",
|
||||
//설치완료일자
|
||||
String(item.instlCmptnDt).substring(0, 10) ?? "",
|
||||
//설치비용
|
||||
item.instlCst ?? "",
|
||||
//접수면종류
|
||||
String(item.pntfColKnd) ?? "",
|
||||
//여과등처리시설유무
|
||||
String(item.filtrTrtmfctYn) ?? "",
|
||||
//처리용량(저류조용량)
|
||||
item.dtfcltCpct ?? "",
|
||||
//연간사용량
|
||||
item.wtrUsqty ?? "",
|
||||
//이용용도코드
|
||||
item.utztnUsgCd ?? "",
|
||||
//연간운영비
|
||||
item.anlOperCst ?? "",
|
||||
]);
|
||||
});
|
||||
return excelData;
|
||||
}
|
||||
@@ -2,34 +2,110 @@ import type { TableUpperProps } from "../../common/type/header";
|
||||
|
||||
export const rainStatHeadListExport: TableUpperProps[] = [
|
||||
{
|
||||
id: "시도",
|
||||
id: "ctpvCd",
|
||||
title: "시도",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "개소",
|
||||
id: "tmp",
|
||||
title: "개소",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "설치비",
|
||||
id: "instlCst",
|
||||
title: "설치비(백만원)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "저류조용량",
|
||||
id: "dtfcltCpct",
|
||||
title: "저류조용량(m³/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "wtrUsqty",
|
||||
title: "연간사용량(㎥/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "a",
|
||||
title: "이용용도",
|
||||
row:0,
|
||||
colSpan:7
|
||||
},
|
||||
{
|
||||
id: "lndwtr",
|
||||
title: "조경용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "cleanToilUswtr",
|
||||
title: "청소화장실용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id:"resn",
|
||||
title:"세척살수용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "farmUswtr",
|
||||
title: "농업용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "indstUswtr",
|
||||
title: "공업용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "hydUswtr",
|
||||
title: "친수용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "ithlEtcUswtr",
|
||||
title: "기타",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "anlOperCst",
|
||||
title: "연간운영비(백만원/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
];
|
||||
|
||||
export const rainStatDetailHeadListExport: TableUpperProps[] = [
|
||||
{
|
||||
id: "ctpvCd",
|
||||
title: "시도",
|
||||
row:0,
|
||||
},
|
||||
{
|
||||
id: "sggCd",
|
||||
title: "시군구",
|
||||
row:0,
|
||||
},
|
||||
{
|
||||
id: "areaNm",
|
||||
title: "행정구역명",
|
||||
row:0,
|
||||
},
|
||||
{
|
||||
id: "",
|
||||
title: "시설명",
|
||||
row:0,
|
||||
},
|
||||
{
|
||||
id: "이용용도",
|
||||
title: "이용용도",
|
||||
row:0,
|
||||
colSpan:6
|
||||
colSpan:7
|
||||
},
|
||||
{
|
||||
id: "조경용수",
|
||||
@@ -41,6 +117,11 @@ export const rainStatHeadListExport: TableUpperProps[] = [
|
||||
title: "청소화장실용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id:"세척살수용수",
|
||||
title:"세척살수용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "농업용수",
|
||||
title: "농업용수",
|
||||
@@ -67,4 +148,4 @@ export const rainStatHeadListExport: TableUpperProps[] = [
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
];
|
||||
];
|
||||
@@ -1,13 +1,66 @@
|
||||
import { fetchType, getFetch } from "@/components/lib/api";
|
||||
import type { TableUpperProps } from "../../common/type/header";
|
||||
import { excelRainStat } from "./excel";
|
||||
import { rainStatHeadListExport } from "./headList";
|
||||
|
||||
type rainStatActions = {
|
||||
export type RainStatProps = {
|
||||
ctpvCd: string //시도
|
||||
sggCd: string //시군구
|
||||
areaNm: string //행정구역명
|
||||
bdstNm: string //시설명
|
||||
bdstUsgCd: string //건축물용도코드
|
||||
daddr: string //주소
|
||||
lawTrgtYn: string //법적의무대상여부
|
||||
instlCmptnDt: string //설치완료일자
|
||||
instlCst: number //설치비용
|
||||
pntfColKnd: string //접수면종류
|
||||
filtrTrtmfctYn: string //여과등처리시설유무
|
||||
archArea: number //건축연면적
|
||||
dtfcltCpct: number //처리용량(저류조용량)
|
||||
wtrUsqty: number //연간사용량
|
||||
utztnUsgCd: string //이용용도코드
|
||||
anlOperCst: number //연간운영비
|
||||
annRnwtQty: number //물사용량
|
||||
jungsudo: number //중수도이용량
|
||||
dachae: number //대체수이용량
|
||||
lndwtr: number //조경용수
|
||||
cleanToilUswtr: number //청소화장실용수
|
||||
resn: number //세척살수용수
|
||||
farmUswtr: number //농업용수
|
||||
indstUswtr: number //공업용수
|
||||
hydUswtr: number //친수용수
|
||||
ithlEtcUswtr: number //기타
|
||||
tmp: number //개소
|
||||
guideStats: GuideStatProps[]
|
||||
}
|
||||
|
||||
export type GuideStatProps = {
|
||||
utztnUsgCd: string
|
||||
splyUswtrUtztnQnt : number,
|
||||
ruseFcltUtztnQnt: number
|
||||
}
|
||||
|
||||
type ExcelType = {
|
||||
[key: string]: string | number | undefined;
|
||||
};
|
||||
|
||||
const excelDownList: ExcelType[] = [];
|
||||
|
||||
const fetchRainStatList = async (year: string) => {
|
||||
const res = await getFetch(fetchType.WR, `/reuseChk/rainy/stat/${year}`)
|
||||
return res;
|
||||
}
|
||||
|
||||
type rainStatActions = {
|
||||
searchRainStatList: (year: string) => void
|
||||
}
|
||||
|
||||
export type rainStatState = {
|
||||
rainStat: {
|
||||
rainStatHeadList:TableUpperProps[]
|
||||
rainStatHeadList: TableUpperProps[],
|
||||
rainStatList: RainStatProps[],
|
||||
excelList: ExcelType[]
|
||||
rainDetailList : [][]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +68,117 @@ export type rainStatType = rainStatState & rainStatActions;
|
||||
|
||||
export const rainStatExport: rainStatState = {
|
||||
rainStat: {
|
||||
rainStatHeadList:rainStatHeadListExport
|
||||
rainStatHeadList: rainStatHeadListExport,
|
||||
rainStatList: [],
|
||||
excelList: [],
|
||||
rainDetailList : []
|
||||
}
|
||||
}
|
||||
|
||||
export const rainStatActionsExport: (set: any) => rainStatActions = (
|
||||
set: any
|
||||
export const rainStatActionsExport = (
|
||||
set: (fn: (state: rainStatState) => rainStatState) => void
|
||||
) => {
|
||||
return {
|
||||
|
||||
searchRainStatList: async (year: string) => {
|
||||
const res = await fetchRainStatList(year);
|
||||
const cityArr: any[] = [];
|
||||
res.forEach((item: RainStatProps) => {
|
||||
|
||||
let obj = cityArr.find((e) => {
|
||||
return e.ctpvCd == item.ctpvCd
|
||||
})
|
||||
|
||||
if (obj) {
|
||||
obj.instlCst += item.instlCst
|
||||
obj.dtfcltCpct += item.dtfcltCpct
|
||||
obj.wtrUsqty += item.wtrUsqty
|
||||
obj.anlOperCst += item.anlOperCst
|
||||
obj.tmp += 1
|
||||
} else {
|
||||
obj = {};
|
||||
obj.ctpvCd = item.ctpvCd
|
||||
obj.instlCst = item.instlCst
|
||||
obj.tmp = 1
|
||||
obj.dtfcltCpct = item.dtfcltCpct
|
||||
obj.wtrUsqty = item.wtrUsqty
|
||||
obj.anlOperCst = item.anlOperCst
|
||||
|
||||
cityArr.push(obj)
|
||||
}
|
||||
|
||||
if (item.guideStats && item.guideStats.length > 0) {
|
||||
item.guideStats.forEach((guide: GuideStatProps) => {
|
||||
rainStatHeadListExport.forEach((headItem: TableUpperProps) => {
|
||||
|
||||
if (headItem.title == guide.utztnUsgCd) {
|
||||
if (!obj[headItem.id] || typeof obj[headItem.id] !== "number") obj[headItem.id] = 0;
|
||||
if (typeof obj[headItem.id] === "number") {
|
||||
|
||||
obj[headItem.id] += guide.ruseFcltUtztnQnt;
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
cityArr.forEach(item => {
|
||||
excelDownList.push({
|
||||
ctpvCd: item.ctpvCd,
|
||||
tmp: item.tmp,
|
||||
instlCst: item.instlCst, //설치비
|
||||
dtfcltCpct: item.dtfcltCpct, //저류조용량
|
||||
bdstUsgCd: item.bdstUsgCd, //연간사용량
|
||||
lndwtr: item.lndwtr, //조경용수
|
||||
cleanToilUswtr: item.cleanToilUswtr, //청소화장실용수
|
||||
resn: item.resn, //세척살수용수
|
||||
farmUswtr: item.farmUswtr, //농업용수
|
||||
indstUswtr: item.indstUswtr, //공업용수
|
||||
hydUswtr: item.hydUswtr, //친수용수
|
||||
ithlEtcUswtr: item.ithlEtcUswtr, //기타
|
||||
anlOperCst: item.anlOperCst, //연간운영비
|
||||
})
|
||||
})
|
||||
|
||||
//상세
|
||||
const rainDetailList : RainStatProps[] = [];
|
||||
res.forEach((item:RainStatProps) => {
|
||||
const utztnUsgArray = new Array<string>();
|
||||
item.guideStats.forEach((guideStat) => {
|
||||
utztnUsgArray.push(guideStat.utztnUsgCd);
|
||||
})
|
||||
rainDetailList.push({
|
||||
...item,
|
||||
utztnUsgCd : utztnUsgArray.join(', '),
|
||||
})
|
||||
})
|
||||
const excelDetailData = excelRainStat(rainDetailList);
|
||||
/* const rainStatHeadList = data.map((item:RainStatProps) => ({
|
||||
...item,
|
||||
ctpvCd:item.ctpvCd,
|
||||
sggCd:item.sggCd,
|
||||
areaNm:item.areaNm,
|
||||
archArea:item.archArea,
|
||||
dtfcltCpct:item.dtfcltCpct,
|
||||
annRnwtQty:item.annRnwtQty,
|
||||
jungsudo:item.jungsudo,
|
||||
dachae:item.dachae,
|
||||
way1:item.way1,
|
||||
way2:item.way2,
|
||||
way3:item.way3,
|
||||
way4:item.way4,
|
||||
way5:item.way5,
|
||||
way6:item.way6,
|
||||
way7:item.way7,
|
||||
yearMoney:item.yearMoney,
|
||||
})) */
|
||||
set((state: rainStatState) => ({
|
||||
rainStat: {
|
||||
...state.rainStat,
|
||||
rainDetailList: excelDetailData as [][],
|
||||
rainStatList: cityArr,
|
||||
excelList: excelDownList
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import type { RswtStatProps } from ".";
|
||||
|
||||
export const excelRswtStat = (excelList:RswtStatProps[]) : (string | number)[][] => {
|
||||
const excelData: (string | number)[][] = [];
|
||||
excelList.forEach((item) => {
|
||||
excelData.push([
|
||||
//시도
|
||||
String(item.ctpvCd) ?? "",
|
||||
//시군구
|
||||
String(item.sggCd) ?? "",
|
||||
//행정구역명
|
||||
String(item.areaNm) ?? "",
|
||||
//건축물명
|
||||
String(item.bdstNm) ?? "",
|
||||
//건축물용도코드(빈칸)
|
||||
//String(item.bdstUsgCd) ?? "",
|
||||
"",
|
||||
//주소
|
||||
String(item.daddr) ?? "",
|
||||
//법적의무대상여부
|
||||
String(item.lawTrgtYn)==="Y" ? "대상" : "미대상",
|
||||
//설치완료일자
|
||||
item.instlCmptnDt ? String(item.instlCmptnDt).substring(0, 10) : "",
|
||||
//가동개시일(빈칸)
|
||||
//String(item.instlCst) ?? "",
|
||||
"",
|
||||
//건축물면적
|
||||
item.archArea ?? "",
|
||||
//처리용량
|
||||
item.filtrTrtmfctCpct ?? "",
|
||||
//물사용량
|
||||
item.wtrUsqty ?? "",
|
||||
//중수도+대체수이용량
|
||||
item.rswtAltSum ?? "",
|
||||
//중수도이용량
|
||||
item.rswtrUsqty ?? "",
|
||||
//대체수이용량
|
||||
item.altUswtrUtztnQnt ?? "",
|
||||
//중수도용도
|
||||
String(item.utztnUsgCd) ?? "",
|
||||
//연간운영비
|
||||
item.anlOperCst ?? "",
|
||||
]);
|
||||
});
|
||||
return excelData;
|
||||
}
|
||||
@@ -2,96 +2,96 @@ import type { TableUpperProps } from "../../common/type/header";
|
||||
|
||||
export const rswtStatHeadListExport :TableUpperProps[]=[
|
||||
{
|
||||
id: "시도",
|
||||
id: "ctpvCd",
|
||||
title: "시도",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "개소",
|
||||
id: "ctpvCnt",
|
||||
title: "개소",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "시설현황",
|
||||
id: "a",
|
||||
title: "시설현황",
|
||||
row:0,
|
||||
colSpan:2
|
||||
},
|
||||
{
|
||||
id: "건축연면적(m³)",
|
||||
id: "archArea",
|
||||
title: "건축연면적(m³)",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "처리용량",
|
||||
id: "filtrTrtmfctCpct",
|
||||
title: "처리용량(m³)",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "물사용량",
|
||||
id: "wtrUsqty",
|
||||
title: "물사용량(m³/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "청소화장실용수",
|
||||
id: "rswtAltSum",
|
||||
title: "중수도+대체수이용량(m³/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "중수도이용량",
|
||||
id: "rswtrUsqty",
|
||||
title: "중수도이용량(m³/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
{
|
||||
id: "대체수이용량",
|
||||
id: "altUswtrUtztnQnt",
|
||||
title: "대체수이용량(m³/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
},
|
||||
|
||||
{
|
||||
id: "용도",
|
||||
id: "b",
|
||||
title: "용도",
|
||||
row:0,
|
||||
colSpan:6
|
||||
},
|
||||
{
|
||||
id: "조경용수",
|
||||
id: "lndwtr",
|
||||
title: "조경용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "청소화장실용수",
|
||||
id: "cleanToilUswtr",
|
||||
title: "청소화장실용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "농업용수",
|
||||
id: "farmUswtr",
|
||||
title: "농업용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "공업용수",
|
||||
id: "indstUswtr",
|
||||
title: "공업용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "친수용수",
|
||||
id: "hydUswtr",
|
||||
title: "친수용수",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "기타",
|
||||
id: "ithlEtcUswtr",
|
||||
title: "기타",
|
||||
row:1,
|
||||
},
|
||||
{
|
||||
id: "연간운영비",
|
||||
id: "anlOperCst",
|
||||
title: "연간운영비(백만원/년)",
|
||||
row:0,
|
||||
rowSpan:2
|
||||
|
||||
@@ -1,13 +1,57 @@
|
||||
import { fetchType, getFetch } from "@/components/lib/api";
|
||||
import type { TableUpperProps } from "../../common/type/header";
|
||||
import { rswtStatHeadListExport } from "./headList";
|
||||
import { excelRswtStat } from "./excel";
|
||||
|
||||
export type RswtStatProps = {
|
||||
ctpvCd: string //시도
|
||||
sggCd : string //시군구
|
||||
areaNm: string //행정구역명
|
||||
bdstNm: string //시설명
|
||||
daddr: string //주소
|
||||
ctpvCnt: string //개소
|
||||
archArea: number //건축연면적
|
||||
filtrTrtmfctCpct: number //처리용량
|
||||
wtrUsqty: number //물사용량
|
||||
rswtAltSum: number //중수도+대체수이용량
|
||||
rswtrUsqty: number //중수도이용량
|
||||
altUswtrUtztnQnt: number //대체수이용량
|
||||
lndwtr: number //조경용수
|
||||
cleanToilUswtr: number //청소화장실용수
|
||||
resn: number //세척살수용수
|
||||
farmUswtr: number //농업용수
|
||||
indstUswtr: number //공업용수
|
||||
hydUswtr: number //친수용수
|
||||
ithlEtcUswtr: number //기타
|
||||
anlOperCst: number //연간운영비
|
||||
guideStats: GuideStatProps[]
|
||||
utztnUsgCd : string //이용코드
|
||||
lawTrgtYn : string //법적의무대상여부
|
||||
instlCmptnDt : string //설치완료일자
|
||||
}
|
||||
|
||||
export type GuideStatProps = {
|
||||
utztnUsgCd: string
|
||||
ruseFcltUtztnQnt: number
|
||||
}
|
||||
|
||||
type rswtStatActions = {
|
||||
searchRswtStatList: (year: string) => void;
|
||||
}
|
||||
|
||||
export type ExcelType = {
|
||||
[key: string]: string | number | undefined;
|
||||
};
|
||||
|
||||
const excelDownList: ExcelType[] = [];
|
||||
|
||||
|
||||
export type rswtStatState = {
|
||||
rswtStat: {
|
||||
rswtStatHeadList:TableUpperProps[]
|
||||
rswtStatHeadList: TableUpperProps[];
|
||||
rswtStatList: RswtStatProps[];
|
||||
excelList: ExcelType[];
|
||||
rswtDetailList: RswtStatProps[][];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +59,10 @@ export type rswtStatType = rswtStatState & rswtStatActions;
|
||||
|
||||
export const rswtStatExport: rswtStatState = {
|
||||
rswtStat: {
|
||||
rswtStatHeadList:rswtStatHeadListExport
|
||||
rswtStatHeadList: rswtStatHeadListExport,
|
||||
rswtStatList: [],
|
||||
excelList: [],
|
||||
rswtDetailList: []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +70,99 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = (
|
||||
set: any
|
||||
) => {
|
||||
return {
|
||||
|
||||
searchRswtStatList: async (year: string) => {
|
||||
const res = await getFetch(fetchType.WR, `/reuseChk/reuseWater/stat/${year}`)
|
||||
const rswtStatList: RswtStatProps[] = [];
|
||||
|
||||
const cityArr: any[] = [];
|
||||
res.forEach((item: RswtStatProps) => {
|
||||
let obj = cityArr.find((e) => {
|
||||
return e.ctpvCd == item.ctpvCd
|
||||
})
|
||||
|
||||
if (obj) {
|
||||
obj.ctpvCnt += 1
|
||||
obj.archArea += item.archArea
|
||||
obj.filtrTrtmfctCpct += item.filtrTrtmfctCpct
|
||||
obj.wtrUsqty += item.wtrUsqty
|
||||
obj.rswtAltSum += (item.rswtrUsqty + item.altUswtrUtztnQnt)
|
||||
obj.rswtrUsqty += item.rswtrUsqty
|
||||
obj.altUswtrUtztnQnt += item.altUswtrUtztnQnt
|
||||
obj.anlOperCst += item.anlOperCst
|
||||
} else {
|
||||
obj = {};
|
||||
obj.ctpvCd = item.ctpvCd
|
||||
obj.ctpvCnt = 1
|
||||
obj.archArea = item.archArea
|
||||
obj.filtrTrtmfctCpct = item.filtrTrtmfctCpct
|
||||
obj.wtrUsqty = item.wtrUsqty
|
||||
obj.rswtAltSum = item.rswtrUsqty + item.altUswtrUtztnQnt
|
||||
obj.rswtrUsqty = item.rswtrUsqty
|
||||
obj.altUswtrUtztnQnt = item.altUswtrUtztnQnt
|
||||
obj.anlOperCst = item.anlOperCst
|
||||
|
||||
cityArr.push(obj)
|
||||
}
|
||||
|
||||
if (item.guideStats && item.guideStats.length > 0) {
|
||||
item.guideStats.forEach((guide: GuideStatProps) => {
|
||||
rswtStatHeadListExport.forEach((headItem: TableUpperProps) => {
|
||||
|
||||
if (headItem.title == guide.utztnUsgCd) {
|
||||
if (!obj[headItem.id] || typeof obj[headItem.id] !== "number") obj[headItem.id] = 0;
|
||||
if (typeof obj[headItem.id] === "number") {
|
||||
|
||||
obj[headItem.id] += guide.ruseFcltUtztnQnt;
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
cityArr.forEach(item => {
|
||||
excelDownList.push({
|
||||
ctpvCd: item.ctpvCd,
|
||||
ctpvCnt: item.ctpvCnt,
|
||||
archArea: item.archArea,
|
||||
filtrTrtmfctCpct: item.filtrTrtmfctCpct,
|
||||
wtrUsqty: item.wtrUsqty,
|
||||
rswtAltSum: item.rswtAltSum,
|
||||
rswtrUsqty: item.rswtrUsqty,
|
||||
altUswtrUtztnQnt: item.altUswtrUtztnQnt,
|
||||
lndwtr: item.lndwtr,
|
||||
cleanToilUswtr: item.cleanToilUswtr,
|
||||
farmUswtr: item.farmUswtr,
|
||||
indstUswtr: item.indstUswtr,
|
||||
hydUswtr: item.hydUswtr,
|
||||
ithlEtcUswtr: item.ithlEtcUswtr,
|
||||
anlOperCst: item.anlOperCst,
|
||||
})
|
||||
})
|
||||
|
||||
//상세
|
||||
const rswtDetailList : RswtStatProps[] = [];
|
||||
res.forEach((item:RswtStatProps) => {
|
||||
const utztnUsgArray = new Array<string>();
|
||||
item.guideStats.forEach((guideStat) => {
|
||||
utztnUsgArray.push(guideStat.utztnUsgCd);
|
||||
})
|
||||
rswtDetailList.push({
|
||||
...item,
|
||||
rswtAltSum : item.rswtrUsqty + item.altUswtrUtztnQnt,
|
||||
utztnUsgCd : utztnUsgArray.join(', '),
|
||||
})
|
||||
});
|
||||
|
||||
const excelDetailData = excelRswtStat(rswtDetailList);
|
||||
set((state: rswtStatState) => ({
|
||||
rswtStat: {
|
||||
...state.rswtStat,
|
||||
rswtStatList: cityArr,
|
||||
excelList: excelDownList,
|
||||
rswtDetailList: excelDetailData
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { coRegExcel } from "@/app/store/matDmd/coSttn/headList";
|
||||
import type { customLdrmntBdst } from "@/app/store/matDmd/ldrmntCoSttn";
|
||||
import type { customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn";
|
||||
import { excelToLdrmntData, names } from "@/app/store/matDmd/ldrmntCoSttn/excel";
|
||||
import { filePicked, FileUpload, FormUi, Title } from "@common/business_components/ui";
|
||||
import { Form, FormField } from "@common/business_components/ui/form";
|
||||
@@ -16,13 +16,14 @@ export default function CoRegExcel() {
|
||||
const form = useForm<z.infer<typeof coRegExcel>>({
|
||||
resolver: zodResolver(coRegExcel),
|
||||
});
|
||||
const { ldrmntRegData } = useWrStore((state) => state);
|
||||
const [excelData, setExcelData] = useState<customLdrmntBdst[]>();
|
||||
const { ldrmntRegData, ldrmntDelete } = useWrStore((state) => state);
|
||||
const [excelData, setExcelData] = useState<customLdrmnt[]>();
|
||||
|
||||
|
||||
const [file, setFiles] = useState<File | undefined>();
|
||||
|
||||
const onSubmit = (values: z.infer<typeof coRegExcel>) => {
|
||||
ldrmntDelete();
|
||||
if (file) {
|
||||
filePicked(file, 0).then((res) => {
|
||||
try {
|
||||
@@ -50,7 +51,7 @@ export default function CoRegExcel() {
|
||||
}
|
||||
})
|
||||
ldrmntRegData(array);
|
||||
console.log("array22", array)
|
||||
console.log("array끝", array)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn";
|
||||
import { ldrmntZod } from "@/app/store/matDmd/ldrmntCoSttn/headList";
|
||||
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { handleCommaNumberChange } from "@/components/lib/func/commom";
|
||||
@@ -14,21 +16,25 @@ export default function SttnDetailModal({
|
||||
}: {
|
||||
formObj: any;
|
||||
}) {
|
||||
const { ldrmntUpdate } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const defaultValues: z.infer<typeof ldrmntZod> = ldrmntZod.parse({});
|
||||
const form = useForm<z.infer<typeof ldrmntZod>>({
|
||||
resolver: zodResolver(ldrmntZod),
|
||||
defaultValues: defaultValues,
|
||||
});
|
||||
|
||||
const onSubmit = (values: z.infer<typeof ldrmntZod>) => {
|
||||
const onSubmit = (values: customLdrmnt) => {
|
||||
console.log("values", values)
|
||||
if (values)
|
||||
ldrmntUpdate(values)
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (ldrmntZod) form.reset(formObj);
|
||||
|
||||
}, [formObj]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ScrollArea className="h-[85vh]">
|
||||
@@ -43,6 +49,23 @@ export default function SttnDetailModal({
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fctryMngSn"
|
||||
render={({ field }) => (
|
||||
<FormUi label="">
|
||||
<Input
|
||||
className={selectClass}
|
||||
placeholder=""
|
||||
type="hidden"
|
||||
onChange={(e) => {
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
/>
|
||||
</FormUi>
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-4 gap-2 mt-4">
|
||||
<div className="col-span-2">
|
||||
<FormField
|
||||
@@ -66,7 +89,7 @@ export default function SttnDetailModal({
|
||||
<div className="col-span-2">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="mngInst"
|
||||
name="mngInstNm"
|
||||
render={({ field }) => (
|
||||
<FormUi label="관리기관">
|
||||
<Input
|
||||
@@ -83,7 +106,7 @@ export default function SttnDetailModal({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="grid grid-cols-4 gap-2 mt-4">
|
||||
<div className="col-span-2">
|
||||
<FormField
|
||||
@@ -709,7 +732,7 @@ export default function SttnDetailModal({
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fctryMngNo"
|
||||
render={({ field }) => (
|
||||
render={({ field, fieldState }) => (
|
||||
<FormUi label="공장관리번호">
|
||||
<Input
|
||||
className={selectClass}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,20 +1,19 @@
|
||||
import './lib/css/gis.common.css';
|
||||
import React, { createContext, useContext, useEffect, useMemo, useRef, useState, useCallback } from 'react';
|
||||
import { Search } from 'lucide-react';
|
||||
import OlMap from 'ol/Map';
|
||||
import View from 'ol/View';
|
||||
import { defaults as defaultControls, OverviewMap } from 'ol/control';
|
||||
import { defaults } from 'ol/interaction';
|
||||
import * as olProj from 'ol/proj';
|
||||
import proj4 from 'proj4';
|
||||
import { register } from 'ol/proj/proj4';
|
||||
import GisApp from './lib/gis.core';
|
||||
import GisContent from './GisContent';
|
||||
import GisTree from './GisTree';
|
||||
import proj4 from 'proj4';
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import GisLonLat from './GisLonLat';
|
||||
import GisMapToggle from './GisMapToggle';
|
||||
import GisSelect from './GisSelect';
|
||||
import GisToolBar from './GisToolBar';
|
||||
import GisMapToggle from './GisMapToggle';
|
||||
import { Search } from 'lucide-react';
|
||||
import GisTree from './GisTree';
|
||||
import './lib/css/gis.common.css';
|
||||
import GisApp from './lib/gis.core';
|
||||
|
||||
export const GisContext = createContext({ gisCore: null, gisMap: null, treeData: null, checkedLayerIds: null });
|
||||
export const useGisContext = () => useContext(GisContext);
|
||||
|
||||
Reference in New Issue
Block a user