대민 현황 데이터 api 수정 적용

This commit is contained in:
leedj312
2025-09-23 11:10:37 +09:00
parent eac09bde2e
commit c853163d99
8 changed files with 119 additions and 57 deletions
@@ -22,7 +22,10 @@ interface WrStatusChartProps {
export default function WrStatusPage() {
const { dmStatus, getDmStatusData} = useDmStore((state) => state);
const { Common, dmStatus, getDmStatusData,initializeCommonData} = useDmStore((state) => state);
const { statusData,facilityTotals ,chartData} = dmStatus;
const [selectedRegion, setSelectedRegion] = useState<string | null>(null);
const [hoveredRegion, setHoveredRegion] = useState<string | null>(null);
@@ -33,7 +36,6 @@ export default function WrStatusPage() {
{ label: '하수', color: '#FF6B6B', key: 'sewage' },
{ label: '빗물', color: '#4ECDC4', key: 'rainwater' },
{ label: '중수도', color: '#45B7D1', key: 'reclaimed' },
{ label: '온배수', color: '#FED16A', key: 'thermal' },
];
const facilityTotalsColor = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FED16A'];
const defaultYear= '2023'
@@ -47,6 +49,11 @@ export default function WrStatusPage() {
}
};
useEffect(() => {
initializeCommonData();
}, [initializeCommonData]);
const createDonutMarker = useCallback((svg: SVGSVGElement, x: number, y: number, name: string, values: number[]) => {
const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FED16A'];
const radius = 26;
@@ -142,8 +149,9 @@ export default function WrStatusPage() {
useEffect(() => {
getDmStatusData(defaultYear);
},[])
if(Common.selectSidoData&&Common.selectSidoData.length>0)
getDmStatusData(Common.selectSidoData);
},[Common.selectSidoData])
@@ -219,8 +227,8 @@ export default function WrStatusPage() {
chartConfig : chartConfig,
chartData : chartData,
chartTitle : '',
chartClassName : "h-[300px] w-full",
graphSize : 40,
chartClassName : "w-full h-[350px] ",
graphSize : 10,
yFieldText : '시설(개소)',
showLegend : true
}
@@ -321,7 +329,6 @@ export default function WrStatusPage() {
<th className="text-[12px] font-semibold px-4 py-2">하수재이용시설</th>
<th className="text-[12px] font-semibold px-4 py-2">빗물이용시설</th>
<th className="text-[12px] font-semibold px-4 py-2">중수도시설</th>
<th className="text-[12px] font-semibold px-4 py-2">온배수시설</th>
{/* <th className="text-[12px] font-semibold px-4 py-2">하수(이용량,천𝓂³/년)</th>
<th className="text-[12px] font-semibold px-4 py-2">빗물(이용량,천𝓂³/년)</th>
<th className="text-[12px] font-semibold px-4 py-2">중수도(이용량,천𝓂³/년)</th>
@@ -338,7 +345,6 @@ export default function WrStatusPage() {
<td className="text-[12px]">{row.sewage}</td>
<td className="text-[12px]">{row.rainwater}</td>
<td className="text-[12px]">{row.reclaimed}</td>
<td className="text-[12px]">{row.thermal}</td>
</tr>
))}
</tbody>
+3 -12
View File
@@ -1,4 +1,4 @@
import type { DmStatusChartType, DmStatusDataType, RegionData, } from "../store/wrStatus/type";
import type { RegionData, } from "../store/wrStatus/type";
@@ -43,7 +43,7 @@ export const regionIdMap: Record<string, string> = {
};
const makeRegion = (region: string) => {
export const makeRegion = (region: string) => {
if (region === '서울특별시') return '서울'
if (region === '부산광역시') return '부산'
if (region === '대구광역시') return '대구'
@@ -56,19 +56,10 @@ const makeRegion = (region: string) => {
if (region === '강원특별자치도') return '강원'
if (region === '충청북도') return '충북'
if (region === '충청남도') return '충남'
if (region === '전라북도') return '전북'
if (region === '전북특별자치도') return '전북'
if (region === '전라남도') return '전남'
if (region === '경상북도') return '경북'
if (region === '경상남도') return '경남'
if (region === '제주특별자치도') return '제주'
return region;
}
export const changeStatusMapData= (data: DmStatusDataType[]) : DmStatusChartType[]=> {
return data.map((item) => ({
label: makeRegion(item.region??''),
하수: item.sewage.split('(')[0]?.replaceAll(',','') ??'',
빗물: item.rainwater.split('(')[0]?.replaceAll(',','')??'',
중수도: item.reclaimed.split('(')[0]?.replaceAll(',','') ??'',
온배수: item.thermal.split('(')[0]?.replaceAll(',','') ??'',
}));
}
+3 -5
View File
@@ -1,4 +1,4 @@
"use client"
"use client";
import "./globals.css";
export default function RootLayout({
@@ -6,15 +6,13 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ko">
<head>
<title>물재이용 대민</title>
</head>
<body>
{children}
</body>
<body>{children}</body>
</html>
);
}
+6 -6
View File
@@ -214,7 +214,7 @@ const selectMiddleRegionData: SelectDataType[] = [
// 시도 API 호출 함수 추가
const fetchSidoData = async (): Promise<SelectDataType[]> => {
try {
const res = await getFetch(fetchType.COMMON, '/addr/city');
const res = await getFetch(fetchType.FO, '/addr/city');
const data = res.data;
selectSidoData = [
{ text: "전체", val: '0'},
@@ -233,7 +233,7 @@ const fetchSidoData = async (): Promise<SelectDataType[]> => {
// 시군구 API 호출 함수 추가
const fetchSigunData = async (): Promise<SelectDataType[]> => {
try {
const res = await getFetch(fetchType.COMMON, '/addr/sgg');
const res = await getFetch(fetchType.FO, '/addr/sgg');
const data = res.data;
selectSigunData = [
{ text: "전체", val: '0' },
@@ -253,7 +253,7 @@ const fetchSigunData = async (): Promise<SelectDataType[]> => {
// 권역 API 호출 함수 추가
const fetchRegionData = async (): Promise<SelectDataType[]> => {
try {
const res = await getFetch(fetchType.COMMON, '/addr/sarea');
const res = await getFetch(fetchType.FO, '/addr/sarea');
const data = res.data;
return [
{ text: "전체", val: '0'},
@@ -271,7 +271,7 @@ const fetchRegionData = async (): Promise<SelectDataType[]> => {
// 중권역 API 호출 함수 추가
const fetchMiddleRegionData = async (): Promise<SelectDataType[]> => {
try {
const res = await getFetch(fetchType.COMMON, '/addr/midArea');
const res = await getFetch(fetchType.FO, '/addr/midArea');
const data = res.data;
return [
{ text: "전체", val: '0' },
@@ -290,7 +290,7 @@ const fetchMiddleRegionData = async (): Promise<SelectDataType[]> => {
// 단위유역 API 호출 함수 추가
const fetchUnitWaterShedData = async (): Promise<SelectDataType[]> => {
try {
const res = await getFetch(fetchType.COMMON, '/addr/largeArea');
const res = await getFetch(fetchType.FO, '/addr/largeArea');
const data = res.data;
return [
{ text: "전체", val: '0' },
@@ -309,7 +309,7 @@ const fetchUnitWaterShedData = async (): Promise<SelectDataType[]> => {
// 환경청 데이터
const fetchEnvPartData = async (): Promise<envPartSelectDataType[]> => {
try {
const res = await getFetch(fetchType.COMMON, '/addr/govArea');
const res = await getFetch(fetchType.FO, '/addr/govArea');
const data = res.data;
selectEnvPartData = [
{ text: "전체", val: '0', adstDliStrCd: '' },
+2 -2
View File
@@ -1,9 +1,9 @@
import { getFetch } from "@/components/ui/api";
import { fetchType, getFetch } from "@/components/ui/api";
import { DEV_URL_FO } from "@/components/ui/config";
import type { FacilityInfo, SubsInfo } from "./type";
const checkWrRegList = async () => {
const wrRegList = await getFetch("wr", `/reuseFc/pubFc`);
const wrRegList = await getFetch(fetchType.WR, `/reuseFc/pubFc`);
return wrRegList;
};
+79 -20
View File
@@ -1,12 +1,14 @@
import { changeStatusMapData } from "@/app/common/comFunction";
import { fetchType, getFetch } from "@/components/ui/api";
import type {
DmStatusDataType,
DmStatusChartType,
DmStatusBoardType,
} from "./type";
import type { SelectDataType } from "../common";
import { makeRegion } from "@/app/common/comFunction";
export type DmStatusActions = {
getDmStatusData(year: string): void;
getDmStatusData(cityCd: SelectDataType[]): void;
};
export type DmStatusType = {
@@ -28,32 +30,89 @@ export type DmStatusStore = DmStatusType & DmStatusActions;
export const DmStatusReducer = (set: any): DmStatusActions => {
return {
getDmStatusData: async (year: string) => {
const data = await getFetch(fetchType.WR, "/daemin/" + year);
let isData:DmStatusDataType[] =[]
if(data.data&&data.data.length>0){
isData=data.data
}else{
fetch(`data/wrStatusData.json`).then((res) => res.json()).then((json) => isData=json)//만약 백엔드에서 못가져올경우 방어책
}
getDmStatusData: async (cityCd: SelectDataType[]) => {
const data = await getFetch(fetchType.FO, "/dashBoard/daemin");
const orgin: DmStatusDataType[] = isData;
const chartData = changeStatusMapData(orgin);
const dataSum = data.data.reduce(
(acc: DmStatusDataType, item: DmStatusDataType) => {
acc.sewage = (
parseInt(acc.sewage.replaceAll(",", "")) +
parseInt(item.sewage.replaceAll(",", ""))
).toLocaleString();
acc.rainwater = (
parseInt(acc.rainwater.replaceAll(",", "")) +
parseInt(item.rainwater.replaceAll(",", ""))
).toLocaleString();
acc.reclaimed = (
parseInt(acc.reclaimed.replaceAll(",", "")) +
parseInt(item.reclaimed.replaceAll(",", ""))
).toLocaleString();
acc.sewageCnt = (
parseInt(acc.sewageCnt.replaceAll(",", "")) +
parseInt(item.sewageCnt.replaceAll(",", ""))
).toLocaleString();
acc.rainwaterCnt = (
parseInt(acc.rainwaterCnt.replaceAll(",", "")) +
parseInt(item.rainwaterCnt.replaceAll(",", ""))
).toLocaleString();
acc.reclaimedCnt = (
parseInt(acc.reclaimedCnt.replaceAll(",", "")) +
parseInt(item.reclaimedCnt.replaceAll(",", ""))
).toLocaleString();
return acc;
},
{
region: "합계",
sewage: "0",
rainwater: "0",
reclaimed: "0",
sewageCnt: "0",
rainwaterCnt: "0",
reclaimedCnt: "0",
}
);
data.data.unshift(dataSum);
console.log("dataSum ", dataSum);
const facilityTotals = [
"하수재이용시설" + "(총" + orgin[0]?.sewage.split("(")[0] + "개소)",
"빗물재이용시설" + "(총" + orgin[0]?.rainwater.split("(")[0] + "개소)",
"중수도재이용시설" +
"(총" +
orgin[0]?.reclaimed.split("(")[0] +
"개소)",
"온배수재이용시설" + "(총" + orgin[0]?.thermal.split("(")[0] + "개소)",
"하수재이용시설" + "(총" + dataSum?.sewageCnt + "개소)",
"빗물재이용시설" + "(총" + dataSum?.rainwaterCnt + "개소)",
"중수도재이용시설" + "(총" + dataSum?.reclaimedCnt + "개소)",
];
const boardData: DmStatusBoardType[] = data.data.map(
(item: DmStatusDataType) => {
const regionText = cityCd.find((city) => item.region === city.val);
const sewage = item.sewage;
const rainwater = item.rainwater;
const reclaimed = item.reclaimed;
const sewageCnt = item.sewageCnt;
const rainwaterCnt = item.rainwaterCnt;
const reclaimedCnt = item.reclaimedCnt;
return {
region: regionText ? regionText.text : item.region,
sewage: sewageCnt + "(" + sewage + ")",
rainwater: rainwaterCnt + "(" + rainwater + ")",
reclaimed: reclaimedCnt + "(" + reclaimed + ")",
};
}
);
const chartData = data.data.map((item) => ({
label: makeRegion(
cityCd.find((city) => item.region === city.val)?.text ?? ""
),
하수: item.sewage,
빗물: item.rainwater,
중수도: item.reclaimed,
}));
set((state: DmStatusType) => ({
...state,
dmStatus: {
...state.dmStatus,
statusData: data.data,
statusData: boardData,
chartData: chartData,
facilityTotals: facilityTotals,
},
+9 -2
View File
@@ -3,9 +3,17 @@ export type DmStatusDataType = {
sewage: string;
rainwater: string;
reclaimed: string;
thermal: string;
sewageCnt:string
rainwaterCnt:string
reclaimedCnt:string
};
export type DmStatusBoardType = {
region: string;
sewage: string;
rainwater: string;
reclaimed: string;
};
export type DmStatusFcltType = {
sewageFclt: string;
@@ -21,7 +29,6 @@ export type DmStatusChartType = {
하수: string,
빗물: string,
중수도: string,
온배수: string,
}
export type RegionData = {
+3 -2
View File
@@ -3,7 +3,8 @@ import { DEV_URL_FO, DEV_URL_WR } from "../config";
export const fetchType = {
COMMON: "common",
WR: "wr"
WR: "wr",
FO:'fo'
};
interface RequestParams {
@@ -11,7 +12,7 @@ interface RequestParams {
}
export const getFetch = async (type: string, url: string) => {
const baseUrl = type === fetchType.COMMON ? DEV_URL_FO : DEV_URL_WR;
const baseUrl = type === fetchType.FO ? DEV_URL_FO : DEV_URL_WR;
const response = await fetch(baseUrl + url, {
method: "GET",
headers: {