Merge branch 'iipbs/wr/dev'

This commit is contained in:
yschoi
2025-07-15 13:06:35 +09:00
148 changed files with 5477 additions and 7985 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ NEXT_PUBLIC_PORT = 11301
NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11301
NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
NEXT_PUBLIC_TEMP_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver #TODO 운영에서 바꿔야 함
NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver
NEXT_PUBLIC_CLAIM_NAME = Authorization
NEXT_PUBLIC_AUTH_USER_ID = token-id
NEXT_PUBLIC_ACCESS_TOKEN = access-token
+2 -2
View File
@@ -3,12 +3,12 @@ NEXT_PUBLIC_PORT = 3001
NEXT_PUBLIC_PROXY_HOST = http://localhost:3001
NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
NEXT_PUBLIC_TEMP_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver #TODO 운영에서 바꿔야 함
NEXT_PUBLIC_LX_GEOSERVER_URL = http://con.mind-one.co.kr:11306/geoserver
NEXT_PUBLIC_CLAIM_NAME = Authorization
NEXT_PUBLIC_AUTH_USER_ID = token-id
NEXT_PUBLIC_ACCESS_TOKEN = access-token
NEXT_PUBLIC_REFRESH_TOKEN = refresh-token
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/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 # 박이정
+12
View File
@@ -0,0 +1,12 @@
NEXT_PUBLIC_SITE_ID = WR
NEXT_PUBLIC_PORT = 11301
NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11301
NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
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_CLAIM_NAME = Authorization
NEXT_PUBLIC_AUTH_USER_ID = token-id
NEXT_PUBLIC_ACCESS_TOKEN = access-token
NEXT_PUBLIC_REFRESH_TOKEN = refresh-token
NEXT_PUBLIC_SEWERAGE_API_URL=http://con.mind-one.co.kr:11083/sewerage-service/api # 개발 서버 API
+18 -3
View File
@@ -3,23 +3,38 @@ import { BaseLayout } from "@common/components";
import "./globals.css";
import { StoreProvider } from "./store";
import { MainDiv } from "@common/business_components";
import koBase from '../public/locales/ko/message.json';
import i18next from "i18next";
import { I18nextProvider } from "react-i18next";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
i18next.init({
lng: 'ko',
fallbackLng: 'ko',
resources: {
ko: {
base: koBase,
},
}
});
return (
<html lang="en">
<body>
<I18nextProvider i18n={i18next}>
<StoreProvider>
<BaseLayout>
<MainDiv>
<MainDiv>
{children}
</MainDiv>
</MainDiv>
</BaseLayout>
</StoreProvider>
</I18nextProvider>
</body>
</html>
</html >
);
}
-201
View File
@@ -1,201 +0,0 @@
'use client'
import { getData, putData } from "../../../sn/app/components/lib/api";
import Modal from "../../../sn/app/components/ui/modal";
import { VerticalTable } from "../../../sn/app/components/ui/verticalTable";
import { useGisContext } from "@common/business_components/ui/map/Gis";
import { Button } from "@common/components/ui";
import { useEffect, useRef, useState } from "react";
import { getLayerContentComponent } from "../../../sn/app/map/components/common";
// TODO:
const FeatureClickEventPopup = ({ onClose, featureData }: { onClose: () => void, featureData: any }) => {
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
// const featureId = featureData.getId(); // 피처의 id 가져오기
const featureId = typeof featureData.getId === 'function'
? featureData.getId()
: featureData.fid;
const [layerNm, setLayerNm] = useState<string>(""); // 레이어 이름 상태
const [tableData, setTableData] = useState<any>(null); // 피처 데이터
const [mntrngsData, setMntrngsData] = useState(false); // 수량/수질 측정 정보
const [headlist, setHeadlist] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태
const [headlist2, setHeadlist2] = useState<{ id: string; title: string; }[]>([]); // 컬럼리스트 변경상태
const [buttonChk, setButtonChk] = useState(true)
const [fetchData, setfetchData] = useState<any>(); // api 호출여부
const contentRef = useRef<HTMLDivElement>(null);
const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열기 상태
const [chkMainSsc, setChkMainSsc] = useState(false); // 중점우수토실 여부
// 피쳐데이터의 현재 레이어 이름 가져오는 함수
const getSelectedLayers = () => {
let result = null;
const layers = gisMap.getLayers().getArray(); // gisMap에서 모든 레이어 가져오기
let featureLayer: { get: (key: string) => any } = { get: (key: string) => null }; // 피처가 속한 레이어를 찾기 위한 변수
layers.forEach((layer: any) => {
const source = layer.getSource();
if (source && source.hasFeature && featureData
&& typeof featureData.getId === 'function' && source.hasFeature(featureData)) {
featureLayer = layer; // 피처가 속한 레이어 찾기
}
});
// SearchModal 클릭 이벤트와 Gis 클릭 이벤트 구분하기
if (featureLayer.get('lyrNm') === null) {
if (featureData.lyrTypeNm === 'tb_il_swage_prcs_fclt') result = '하수처리시설';
else if (featureData.lyrTypeNm === 'tb_ms_swage_prcs_zone') result = '하수처리구역';
else if (featureData.lyrTypeNm === 'om_dt_untrt_swg_rain') result = '중점우수토실';
}
else result = featureLayer.get('lyrNm');
return result;
// return featureLayer.get('lyrNm'); // 레이어 이름 출력
};
useEffect(() => {
const fetchData = async () => {
if (featureId) {
const selectedLayerName = getSelectedLayers(); // 레이어 이름 가져오기
setLayerNm(selectedLayerName); // 상태 업데이트
const layerId = featureId.split('.')[0]
let data = await getData(`v1/fclts/${featureId}?lyrTypeNm=${layerId}`);
setfetchData(data)
switch (selectedLayerName) {
case '하수처리시설':
setButtonChk(false)
break;
case '하수처리구역':
setButtonChk(false)
break;
case '중점우수토실':
setButtonChk(false)
setChkMainSsc(true)
// 데이터 전처리: 합쳐진 필드 추가
data = data ? {
...data,
discharge_pipe_spec: `직경: ${data.pipe_diameter || '-'} / 높이: ${data.pipe_hg || '-'} / 길이: ${data.pipe_lt || '-'}`
} : {};
// 수량/수질측정 정보 데이터 호출
const additionalResponse = await getData(`v1/onsemiro/swgRain/${data.adst_dstr_cd}/${data.manage_no}/mntrngs`);
setMntrngsData(additionalResponse.content);
break;
case '우수토실':
setButtonChk(true)
break;
case '하수관로':
setButtonChk(true)
break;
case '오수펌프':
setButtonChk(true)
break;
case '빗물펌프':
setButtonChk(true)
break;
case '하수맨홀':
setButtonChk(true)
break;
default:
break;
}
setTableData(data);
};
}
fetchData();
}, [featureId]);
// 저장 시 모달 띄우기
const handleSaveClick = () => {
setIsModalOpen(true); // 모달 열기
};
const handleModalSave = () => {
setIsModalOpen(false); // 모달 닫기
btnClickEvent(); // 저장 이벤트 실행
};
const handleModalClose = () => {
setIsModalOpen(false); // 모달 닫기
};
const btnClickEvent = async () => {
const bodyData: Record<string, any> = {}
if (buttonChk && contentRef.current) {
const inputElements = contentRef.current.querySelectorAll('input');
const selectElements = contentRef.current.querySelectorAll('select');
// 카멜케이스 변환 함수
const toCamelCase = (str: string) =>
str.replace(/_([a-z])/g, (_, char) => char.toUpperCase());
// select 태그의 값 가져오기
selectElements.forEach((select) => {
const camelCaseId = toCamelCase(select.id);
bodyData[camelCaseId] = select.value;
});
// input 태그의 값 가져오기
inputElements.forEach((input) => {
const camelCaseId = toCamelCase(input.id);
bodyData[camelCaseId] = input.value;
});
if (layerNm === '하수관로') bodyData['lyrTypeNm'] = 'tb_ms_swage_ppl'
else if (layerNm === '우수토실') bodyData['lyrTypeNm'] = 'tb_ms_stofcbr'
else if (layerNm === '오수펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn'
else if (layerNm === '빗물펌프') bodyData['lyrTypeNm'] = 'tb_ms_swage_pmstn'
else if (layerNm === '하수맨홀') bodyData['lyrTypeNm'] = 'tb_ms_swage_mnhl'
bodyData['fid'] = featureId
const data = await putData(`v1/fclts/${featureId}`, bodyData);
if (data.status == 200) {
alert('저장되었습니다')
setTableData(data)
setfetchData(data)
}
}
}
type ContentComponentProps = {
featureData: any;
chkMainSsc: boolean;
additionalData: any;
};
const ContentComponent = layerNm ? getLayerContentComponent(layerNm) as React.ComponentType<ContentComponentProps> : null;
return (
<div id="popup" className="absolute top-0 right-0 w-[350px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-[102]">
<div className="card-header bg-primary flex items-center justify-between p-4">
<div className="flex mx-3 flex-col">
<h3 className="text-2xl font-medium text-white text-label">{layerNm} 정보</h3>
<div className="font-medium text-white text-label">(00구 00리 하수관로)</div>
</div>
<button
onClick={onClose}
className="text-white hover:text-gray-700 focus:outline-none"
aria-label="닫기"
>
✕
</button>
</div>
<div className="overflow-y-auto overflow-x-hidden flex-1" ref={contentRef}>
<VerticalTable
headName='LX 연계정보'
tableData={[tableData]}
headlist={headlist}
pageSize={20}
total={0}
children={undefined}
cellClick={undefined}
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}
/>
<div className="w-full mx-5 flex items-center justify-end space-x-2">
{buttonChk ? <Button onClick={handleSaveClick} className="px-4 mr-5 py-2 bg-blue-600 text-white rounded-sm text-sm font-medium hover:bg-blue-700">
저장
</Button> : null}
</div>
<Modal isModalOpen={isModalOpen} title="자체입력정보 저장" setIsModalOpen={setIsModalOpen} closeModal={handleModalClose} saveModal={handleModalSave}><div className="text-lg">정보를 저장하시겠습니까?</div></Modal>
{ContentComponent &&
<ContentComponent
featureData={fetchData}
chkMainSsc={chkMainSsc}
additionalData={mntrngsData}
/>
}
</div>
</div>
)
}
export default FeatureClickEventPopup;
-621
View File
@@ -1,621 +0,0 @@
"use client";
import {
Form,
FormField,
FormUi,
SelectBox,
} from "@common/business_components/ui";
import { Button, Input } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useWrStore } from "@/app/store";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
hdtflZod,
type customHtdflBdst,
} from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import { useEffect } from "react";
import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg";
import {
formatCommaNumber,
handleCommaNumberChange,
} from "@/components/lib/func/commom";
import { formH1Class } from "@/components/lib/class/comClass";
export default function HtdflPrfmncSttnPopup({
htdflForm,
isModal,
}: {
htdflForm: customHtdflBdst;
isModal: boolean;
}) {
const { code, htdflBdstUpdate, htdflBdstReg } = useWrStore((state) => state);
const defaultValues: z.infer<typeof hdtflZod> = hdtflZod.parse({});
const form = useForm<z.infer<typeof hdtflZod>>({
resolver: zodResolver(hdtflZod),
defaultValues: defaultValues,
});
const onSubmit = (values: z.infer<typeof hdtflZod>) => {
if (isModal) {
htdflBdstReg(values, '41');
} else {
htdflBdstUpdate(values, '41');
}
};
const cleanHtdflData = (raw: any): z.infer<typeof hdtflZod> => {
return {
...raw,
frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null),
archChgPrmsnDt: raw?.archChgPrmsnDt
? new Date(raw?.archChgPrmsnDt)
: null,
chgBuilding: (raw?.chgBuilding || []).map((item: any) => ({
...item,
archChgPrmsnDt:
item?.archChgPrmsnDt === null
? new Date()
: new Date(item?.archChgPrmsnDt),
bdstChgNm: item?.bdstChgNm ?? "", // null → ""
})),
reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
...item,
instlCmptnDt: new Date(item?.instlCmptnDt),
htdflObj: {
...item?.htdflObj,
},
})),
};
};
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
useEffect(() => {
if (hdtflZod) form.reset(cleanHtdflData(htdflForm));
}, [htdflForm]);
return (
<div className="!mx-[1.6rem] !p-0r">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<div className="grid grid-cols-12 flex items-center card-header">
<h1 className="text-2xl font-medium text-label col-span-10">온배수 시설 정보</h1>
</div>
</div>
{isModal && htdflForm != undefined ? <BdstReg form={form} /> : <></>}
{isModal ? (
<h1 className="text-xl col-span-10 mt-4">
온배수 시설 정보{" "}
</h1>
) : (
<></>
)}
<div className="grid grid-cols-6 gap-2 mt-4">
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.etgtType"
render={({ field }) => (
<FormUi label="발전유형(코드정비후 수정)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.fclCpct" // 이름 이상함.
render={({ field }) => (
<FormUi label="설비용량">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.plwtYn"
render={({ field }) => (
<FormUi label="담수화 여부">
<SelectBox
className={""}
label={""}
selectClass={selectClass}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className=" my-4">
<h1 className={formH1Class}>
온배수 시설 운영현황
</h1>
</div>
<div className="grid grid-cols-10 gap-1 mt-4">
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.orgwtWtritSpt"
render={({ field }) => (
<FormUi label="원수취수 지점(코드정비후 수정)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
value={field.value ?? 0}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.orgwtOcrnProcs"
render={({ field }) => (
<FormUi label="원수발생 공정">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.wtritEntrcTp"
render={({ field }) => (
<FormUi label="취수구 온도">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.amtgnr"
render={({ field }) => (
<FormUi label="발생량(m³/년)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.prcsProcsYn"
render={({ field }) => (
<FormUi label="처리공정">
<SelectBox
className={""}
label={""}
selectClass={selectClass}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.prcsFcltCpct"
render={({ field }) => (
<FormUi label="처리시설 용량(m³/년)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.fmYn"
render={({ field }) => (
<FormUi label="유량계유무">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.utztnCpct"
render={({ field }) => (
<FormUi label="이용량(m³/년)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.utztnUsg"
render={({ field }) => (
<FormUi label="이용용도">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className=" my-2">
<h1 className={formH1Class}>
요구수질
</h1>
</div>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.grssClfg"
render={({ field }) => (
<FormUi label="총대장균군">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.tn"
render={({ field }) => (
<FormUi label="총질소">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.combResdch"
render={({ field }) => (
<FormUi label="결합잔류염소">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-6 ">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.tph"
render={({ field }) => (
<FormUi label="총인">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.trbt"
render={({ field }) => (
<FormUi label="탁도">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.ph"
render={({ field }) => (
<FormUi label="수소이온농도">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.bod"
render={({ field }) => (
<FormUi label="생물학적 산소요구량">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.clIonQnt"
render={({ field }) => (
<FormUi label="염화물">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.smll"
render={({ field }) => (
<FormUi label="냄새">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.cdtnv"
render={({ field }) => (
<FormUi label="전기전도도">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.crmty"
render={({ field }) => (
<FormUi label="색도">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-6">
<FormField
control={form.control}
name="reuseBuilding.0.htdflObj.emsnExitTp"
render={({ field }) => (
<FormUi label="배출구온도">
<Input
className={'w-full !text-xl'}
placeholder="10"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
</form>
</Form>
</div>
);
}
+7 -9
View File
@@ -2,15 +2,12 @@
import Gis from "@common/business_components/ui/map/Gis";
import { useEffect, useRef, useState, useCallback } from "react";
import FeatureClickEventPopup from "../featureClickEventPopup";
import { mapService } from "../service";
import { MapSearchBar } from "../mapSearchBar";
import NewWindowPopup from "../newWindowPopup";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
const Map = () => {
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
const [selectedFeature, setSelectedFeature] = useState(null); // 선택된 피처 상태
const gisMaps = useRef<any | null>(null);
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
@@ -46,7 +43,7 @@ const Map = () => {
// SearchModal, GisContent 등에서 호출
const onFeatureSelect = (data: any) => {
let map = gisMaps.current;
const map = gisMaps.current;
if (!map) {
console.warn("지도가 초기화되지 않았습니다.");
return;
@@ -60,7 +57,7 @@ const Map = () => {
select.resetSelectedFeature();
// 2. data가 OpenLayers Feature 인스턴스인지 확인
let foundFeature = null;
let foundFeature: any = null;
if (
data &&
typeof data.getGeometry === "function" &&
@@ -85,9 +82,9 @@ const Map = () => {
// 3. 피처 선택
if (foundFeature) {
let geometry = foundFeature.getGeometry();
const geometry = foundFeature.getGeometry();
if (geometry) {
let extent = geometry.getExtent();
const extent = geometry.getExtent();
map.getView().fit(extent, {
duration: 300,
@@ -136,7 +133,7 @@ const Map = () => {
// />
// )
// }
detailView={(props: any) => (
detailView={(props: any) =>(
<NewWindowPopup
onClose={handlePopupClose} // 메모이제이션된 함수 사용
checkedLayers={checkedLayers}
@@ -144,7 +141,7 @@ const Map = () => {
{...props}
/>
)}
onFeatureSelect={undefined}
onFeatureSelect={onFeatureSelect}
setIsOpen={setIsOpen}
setFeatureData={setFeatureData}
featureData={featureData}
@@ -152,6 +149,7 @@ const Map = () => {
isOpen={isOpen}
isSearchModalOpen={isSearchModalOpen}
onCheckedLayersChange={handleCheckedLayersChange}
imgVisble={true}
/>
</div>
);
-414
View File
@@ -1,414 +0,0 @@
// "use client"
// import { useWrStore } from "@/app/store";
// import SearchInputText from "@/components/ui/searchInput/searchInput";
// import type { EnvPartSelectDataType, ReturnType, SelectDataType } from "@common/business_components/ui";
// import { SelectBox } from "@common/business_components/ui";
// import { Button, Input, Label } from "@common/components/ui";
// import React, { useEffect, useMemo, useRef, useState } from "react";
// import { MapSearchFormLeft } from "./mapSearchForm";
// // 건물 검색 타입 정의
// interface BuildingInfo {
// bdstInfoPk: number;
// ctpvCd: number;
// sggCd: number;
// daddr: string;
// bdstNm: string;
// frstArchPrmsnDt: string;
// archArea: number;
// ctpvNm: string | null;
// sggNm: string | null;
// lat: number | null;
// lot: number | null;
// regDt: string;
// rgtr: string | null;
// mdfcnDt: string;
// mdfr: string | null;
// }
// type SearchBaseType = {
// searchType: string;
// selectSidoData?: SelectDataType[] | [];
// selectSigunData?: SelectDataType[] | [];
// selectRegionData?: SelectDataType[] | [];
// selectUnitWaterShedData?: SelectDataType[] | [];
// selectMiddleRegionData?: SelectDataType[] | [];
// selectEnvPartData?: EnvPartSelectDataType[] | [];
// onFeatureSelect: () => void;
// btnClass?: string;
// ref?: React.RefObject<ReturnType>;
// isAdmin?: boolean;
// leftClassName?: string;
// rightClassName?: string;
// showQueryButton?: boolean;
// showInitButton?: boolean;
// showApplyButton?: boolean;
// checkedLayers?: string[];
// checkedLayersData?: any[];
// }
// const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`;
// const YEARS = Array.from({ length: 100 }, (_, i) => `${2025 - i}`);
// interface SearchModalProps {
// open: boolean;
// onOpenChange: (open: boolean) => void;
// onFeatureSelect: (row: any) => void;
// }
// interface SelectedDataTypeWithSggNm {
// text: string;
// val: string;
// sggNm: string;
// }
// export function MapSearchBar({
// searchType,
// selectSidoData,
// selectSigunData,
// selectRegionData,
// selectUnitWaterShedData,
// selectMiddleRegionData,
// selectEnvPartData,
// btnClass,
// onFeatureSelect,
// isAdmin = false,
// leftClassName,
// rightClassName,
// showQueryButton = true,
// showInitButton = true,
// showApplyButton = true,
// checkedLayers = [],
// checkedLayersData = [],
// }: SearchBaseType) {
// // 로딩바
// const [isLoading, setIsLoading] = useState(false);
// // 상세 정보 조회를 위한 상태 추가
// const [popupFeature, setPopupFeature] = useState<any>(null);
// const [isChHead, setIsChHead] = useState(false);
// const ref = useRef<ReturnType>({} as ReturnType);
// // zustand store에서 건물 검색 함수와 데이터 가져오기
// const {
// code,
// bdst,
// findBdst,
// wrMap,
// buildingSearchRes,
// buildingNmSearch,
// buildingNmSearchMultiple
// } = useWrStore((state) => state);
// const [selectedBuilding, setSelectedBuilding] = useState<BuildingInfo | null>(null);
// const [buildingSearchText, setBuildingSearchText] = useState("");
// const [buildingList, setBuildingList] = useState<BuildingInfo[]>([]);
// // 전체 목록
// const [partValue, setPartValue] = useState<string>("A");
// const [sidoValue, setSidoValue] = useState<string>("0");
// const [sigunValue, setSigunValue] = useState<string>("0");
// const [regionValue, setRegionValue] = useState<string>("0");
// const [untitWaterShedValue, setUntitWaterShedValue] = useState<string>("0");
// const [middleRegionValue, setMiddleRegionValue] = useState<string>("0");
// const [envPartValue, setEnvPartValue] = useState<string>("0");
// const [resetTrigger, setResetTrigger] = useState(false);
// const [sidoText, setSidoText] = useState<string>("0");
// const [sigunText, setSigunText] = useState<string>("0");
// // 공급처 후보지 조회 필터 목록
// const [selectedSido, setSelectedSido] = useState<SelectDataType>({ text: "전체", val: '0' });
// const [selectedSigun, setSelectedSigun] = useState<SelectDataType>({ text: "전체", val: '0' });
// const [selectedFclt, setSelectedFclt] = useState<SelectedDataTypeWithSggNm>({ text: "전체", val: '0', sggNm: '전체' }); // 시설명 선택 상태
// // 전체 시설
// let allFclt: SelectedDataTypeWithSggNm[] = [{ text: "전체", val: '0', sggNm: '전체' }];
// const [selectedDong, setSelectedDong] = useState<SelectedDataTypeWithSggNm>({ text: "전체", val: '0', sggNm: '전체' }); // 시설명 선택 상태 // 행정동
// const filteredSigunData = useMemo(() => {
// if (!selectedSido || selectedSido.val === '0' || !selectedSido.val) return [{ text: "전체", val: '0' }];
// return [
// { text: "전체", val: '0' },
// ...code.sggCd.filter((item: { val: string; }) => item.val.substring(0, 2) === selectedSido.val.substring(0, 2))
// ];
// }, [selectedSido]);
// const filteredFcltData = useMemo(() => {
// if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) return [{ text: "전체", val: '0', sggNm: '전체' }];
// return [
// { text: "전체", val: '0', sggNm: '전체' },
// ...allFclt.filter(item => item.sggNm === selectedSido.text)
// ];
// }, [selectedSigun]);
// const filteredDong = useMemo(() => {
// if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) return [{ text: "전체", val: '0', sggNm: '전체' }];
// return [
// { text: "전체", val: '0', sggNm: '전체' },
// // ...code.dong.filter(item => item.sggNm === selectedSido.text)
// ];
// }, [selectedSigun]);
// // 조회 함수
// const queryVal = () => {
// // 46 : 하수처리시설
// // 47 : 하수재이용시설
// // 48 : 빗물이용시설
// // 49 : 중수도시설
// // 50 : 온배수시설
// console.log("조회버튼 클릭: ", checkedLayers);
// if (checkedLayers && checkedLayers.includes('48')) {
// // searchBuildings
// }
// }
// // 초기화 함수
// const initVal = () => {
// setPartValue("A");
// setSidoValue("0");
// setSigunValue("0");
// setRegionValue("0");
// setUntitWaterShedValue("0");
// setMiddleRegionValue("0");
// setEnvPartValue("0");
// setSidoText("전체");
// setSigunText("전체");
// setSelectedSido({ text: "전체", val: '0' });
// setSelectedSigun({ text: "전체", val: '0' });
// setSelectedFclt({ text: "전체", val: '0', sggNm: '전체' });
// setSelectedDong({ text: "전체", val: '0', sggNm: '전체' });
// setResetTrigger(true);
// };
// // 적용 버튼
// const applyVal = () => {
// onFeatureSelect();
// };
// useEffect(() => {
// if (resetTrigger) {
// setResetTrigger(false);
// }
// }, [resetTrigger]);
// // 시설 조회
// useEffect(() => {
// const fetchData = async () => {
// setIsLoading(true);
// if (!selectedSigun || selectedSigun.val === '0' || !selectedSigun.val) {
// allFclt = ([{ text: "전체", val: '0', sggNm: '전체' }]);
// setIsLoading(false);
// return;
// }
// try {
// const queryParamsFacility = new URLSearchParams({
// lyrTypeNm: 'tb_il_swage_prcs_fclt',
// page: '0',
// size: '100000',
// sort: 'string',
// });
// const cqlFiltersFacility: string[] = [];
// if (selectedSigun.text && selectedSigun.val !== '0') {
// cqlFiltersFacility.push(`sgg_nm ILIKE '%${selectedSigun.text}%'`);
// }
// if (cqlFiltersFacility.length > 0) {
// queryParamsFacility.append('cqlFiter', cqlFiltersFacility.join(' and '));
// }
// console.log("BaseLayout API URL for Facilities:", `v1/fclts?${queryParamsFacility.toString()}`);
// const facilityRes = await fetch(`${API_URL}/v1/fclts?${queryParamsFacility.toString()}`, {
// method: "GET",
// headers: { accept: "application/json" }
// }).then(res => res.json());
// const facilities = (facilityRes.data || []).map((item: any) => ({
// text: item.swtrmtFcltNm,
// val: item.fid,
// sggNm: item.sggNm
// }));
// allFclt = (facilities);
// } catch (error) {
// console.error("BaseLayout: 지역/시설 데이터 조회 중 오류 발생:", error);
// allFclt = ([{ text: "전체", val: '0', sggNm: '전체' }]);
// } finally {
// setIsLoading(false);
// }
// };
// fetchData();
// }, [selectedSigun]);
// useEffect(() => {
// if (ref && ref.current) {
// const customRef = ref.current;
// customRef.partValue = partValue;
// customRef.sidoValue = sidoValue;
// customRef.sigunValue = sigunValue;
// customRef.regionValue = regionValue;
// customRef.unitWaterShedValue = untitWaterShedValue;
// customRef.middleRegionValue = middleRegionValue;
// customRef.envPartValue = envPartValue;
// customRef.sidoText = selectedSido.text;
// customRef.sigunText = selectedSigun.text;
// }
// }, [partValue, sidoValue, sigunValue, regionValue, untitWaterShedValue, middleRegionValue, envPartValue, ref]);
// // buildingSearchText가 변경될 때 API 호출
// useEffect(() => {
// if (buildingSearchText && buildingSearchText.length > 1) {
// if (checkedLayers && checkedLayers.length > 0) {
// // 다중 레이어 검색
// // buildingNmSearchMultiple(checkedLayers, selectedSigun.val || "", buildingSearchText);
// buildingNmSearch("RNB", selectedSigun.val, buildingSearchText);
// } else {
// // 단일 레이어 검색
// // buildingNmSearch(checkedLayers[0], selectedSigun.val, buildingSearchText);
// }
// } else {
// // 검색 텍스트가 짧으면 리스트 초기화
// if (checkedLayers && checkedLayers.length > 0) {
// // buildingNmSearchMultiple(checkedLayers, selectedSigun.val || "", "");
// } else {
// buildingNmSearch("RNB", selectedSigun.val || "", "");
// }
// }
// }, [buildingSearchText]);
// return (
// <div className="absolute left-1/2 -translate-x-1/2 bg-white flex items-center justify-center p-4 rounded-md shadow-lg w-auto min-w-fit">
// <div className={leftClassName ? leftClassName : `flex items-center justify-center space-x-2 `}>
// <div className="flex gap-8 items-center">
// {searchType == "공급처 후보지 조회" && (
// <>
// <SelectBox
// className="flex items-center"
// label={'시도'}
// selectArray={code.cityCd}
// onSelectValue={(val) => {
// const selected = code.cityCd.find((item: { val: string | number; }) => (item.val === val));
// setSelectedSido(selected || { text: "전체", val: '0' });
// setSelectedSigun({ text: "전체", val: '0' });
// }}
// value={selectedSido.val}
// selectClass={'w-32'}
// />
// <SelectBox
// className="flex items-center"
// label={'시군구'}
// selectArray={filteredSigunData}
// onSelectValue={(val) => {
// const selected = filteredSigunData.find(item => (item.val === val));
// setSelectedSigun(selected || { text: "전체", val: '0' });
// setSelectedFclt({ text: "전체", val: '0', sggNm: '전체' });
// }}
// value={selectedSigun.val}
// selectClass={'w-32'}
// />
// <div className="flex items-center">
// <Label className="w-20 text-xl text-gray-600">시설명</Label>
// <div className="w-64">
// <SearchInputText
// label="시설명"
// initValue={buildingSearchText}
// setValue={(searchNm?: string) => {
// setBuildingSearchText(searchNm || "");
// }}
// setRtnData={function (rtnData: any): void {
// // 선택된 건물 데이터 처리
// // if (rtnData && rtnData.bdstInfoPk) {
// // setSelectedBuilding(rtnData);
// // setBuildingSearchText(rtnData.bdstNm || "");
// // }
// }}
// searchList={buildingSearchRes || []}
// />
// </div>
// </div>
// </>
// )}
// {searchType == "우리동네가뭄지도보기" && (
// <>
// <SelectBox
// className="flex items-center"
// label={'시도'}
// selectArray={code.cityCd}
// onSelectValue={(val) => {
// const selected = code.cityCd.find((item: { val: string | number; }) => (item.val === val));
// setSelectedSido(selected || { text: "전체", val: '0' });
// setSelectedSigun({ text: "전체", val: '0' });
// }}
// value={selectedSido.val}
// selectClass={'w-44'}
// />
// <SelectBox
// className="flex items-center"
// label={'시군구'}
// selectArray={filteredSigunData}
// onSelectValue={(val) => {
// const selected = filteredSigunData.find(item => (item.val === val));
// setSelectedSigun(selected || { text: "전체", val: '0' });
// setSelectedDong({ text: "전체", val: '0', sggNm: '전체' });
// }}
// value={selectedSigun.val}
// selectClass={'w-32'}
// />
// <SelectBox
// className="flex items-center mr-8"
// label={'행정동'}
// selectArray={filteredDong}
// onSelectValue={(val) => {
// const selected = filteredDong.find(item => (item.val === val));
// setSelectedDong(selected || { text: "전체", val: '0', sggNm: '전체' });
// }}
// value={selectedDong.val}
// selectClass={'w-32'}
// />
// </>
// )}
// {searchType == "지도보기" && (
// <div className="flex items-center gap-2 w-[800px]">
// <div className="flex min-w-0"> {/* SearchFormLeft 래퍼 */}
// <MapSearchFormLeft
// isShowPart={true}
// selectSidoData={code.cityCd}
// selectSigunData={filteredSigunData}
// selectRegionData={code.rvbsnCd}
// selectUnitWaterShedData={selectUnitWaterShedData}
// selectMiddleRegionData={selectMiddleRegionData}
// selectEnvPartData={selectEnvPartData}
// setRtnPartValue={setPartValue}
// setRtnSidoValue={setSidoValue}
// setRtnSigunValue={setSigunValue}
// setRtnRegionValue={setRegionValue}
// setRtnUnitWaterShedValue={setUntitWaterShedValue}
// setRtnMiddleRegionValue={setMiddleRegionValue}
// setRtnEnvPartValue={setEnvPartValue}
// setRtnEnvPartSidoValue={setSidoValue}
// setRtnEnvPartSigunValue={setSigunValue}
// setRtnSidoText={setSidoText}
// setRtnSigunText={setSigunText}
// resetTrigger={resetTrigger}
// isAdmin={isAdmin}
// children={undefined}
// />
// </div>
// <Label className="w-auto text-xl text-gray-600 whitespace-nowrap">시설명</Label>
// <div className="w-44">
// <Input className="mr-4" />
// </div>
// </div>
// )}
// </div>
// {/* 버튼 부분 */}
// <div className="flex items-center justify-center gap-4">
// {showQueryButton && <Button className={btnClass} onClick={queryVal}>조회</Button>}
// {showInitButton && <Button className={btnClass} onClick={initVal}>초기화</Button>}
// {showApplyButton && <Button className={btnClass} onClick={applyVal}>적용</Button>}
// </div>
// </div>
// </div>
// )
// }
-340
View File
@@ -1,340 +0,0 @@
"use client"
import React, { useEffect, useState } from 'react';
import type { SelectDataType } from '@common/business_components/ui/search_input_select';
import { SelectBox } from '@common/business_components/ui/select';
/**
* 검색 폼 왼쪽 컴포넌트 타입
*
* @param isShowPart 구분 조회 여부
* @param children 자식 컴포넌트
* @param selectSidoData 시도 데이터
* @param selectSigunData 시군구 데이터
* @param selectRegionData 유역 데이터
* @param selectUnitWaterShedData 단위유역 데이터
* @param selectMiddleRegionData 중권역 데이터
* @param selectEnvPartData 환경청 데이터
* @param selectEnvPartSidoData 환경청 시도 데이터
* @param selectEnvPartSigunData 환경청 시군구 데이터
* @param setRtnPartValue 부분 값 변경 핸들러
*/
type SearchFormLeftProps = {
isShowPart?: boolean | undefined;
children: React.ReactNode;
selectSidoData?: SelectDataType[] | [];
selectSigunData?: SelectDataType[] | [];
selectRegionData?: SelectDataType[] | [];
selectUnitWaterShedData?: SelectDataType[] | [];
selectMiddleRegionData?: SelectDataType[] | [];
selectEnvPartData?: EnvPartSelectDataType[] | [];
selectEnvPartSidoData?: SelectDataType[] | [];
selectEnvPartSigunData?: SelectDataType[] | [];
setRtnPartValue?: (value: string) => void;
setRtnSidoValue?: (value: string) => void;
setRtnSigunValue?: (value: string) => void;
setRtnRegionValue?: (value: string) => void;
setRtnUnitWaterShedValue?: (value: string) => void;
setRtnMiddleRegionValue?: (value: string) => void;
setRtnEnvPartValue?: (value: string) => void;
setRtnEnvPartSidoValue?: (value: string) => void;
setRtnEnvPartSigunValue?: (value: string) => void;
setRtnSidoText?: (value: string) => void;
setRtnSigunText?: (value: string) => void;
resetTrigger?: boolean;
isAdmin?: boolean;
}
export type EnvPartSelectDataType = SelectDataType & {
adstDliStrCd: string,
}
const selectPartData: SelectDataType[] = [
{ text: "행정별", val: 'A' },
{ text: "유역별", val: 'R' },
{ text: "환경청별", val: 'G' },
];
function MapSearchFormLeft({ isShowPart = false, children, selectSidoData = [], selectSigunData = [], selectRegionData = [], selectUnitWaterShedData = [], selectMiddleRegionData = [], selectEnvPartData = [], setRtnPartValue, setRtnSidoValue, setRtnSidoText, setRtnSigunValue, setRtnSigunText, setRtnRegionValue, setRtnUnitWaterShedValue, setRtnMiddleRegionValue, setRtnEnvPartValue, setRtnEnvPartSidoValue, setRtnEnvPartSigunValue, resetTrigger = false, isAdmin = false }: SearchFormLeftProps) {
/******************선택된 데이터******************/
const [partValue, setPartValue] = useState<string>('A');
//행정별 시도 시군구
const [sidoValue, setSidoValue] = useState<string>('0');
const [sigunValue, setSigunValue] = useState<string>('0');
const [sidoText, setSidoText] = useState<string>('');
const [sigunText, setSigunText] = useState<string>('');
//유역별
const [regionValue, setRegionValue] = useState<string>('0');
const [unitWaterShedValue, setUnitWaterShedValue] = useState<string>('0');
const [middleRegionValue, setMiddleRegionValue] = useState<string>('0');
//환경청별 시도 시군구
const [envPartValue, setEnvPartValue] = useState<string>('0');
// 환경청
const [filteredEnvPartSigunDataSelected, setFilteredEnvPartSigunDataSelected] = useState<SelectDataType[]>([]);
/****************** 셀렉트 리스트 데이터. ******************/
// 조회된 조건에 맞는 시도 시군 유역
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]);
const [filteredUnitWaterShedData, setFilteredUnitWaterShedData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]);
const [filteredMiddleRegionData, setFilteredMiddleRegionData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]);
// 조회된 조건에 맞는 환경청 시도 시군
const [filteredEnvPartData, setFilteredEnvPartData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]);
const [filteredEnvPartSidoData, setFilteredEnvPartSidoData] = useState<EnvPartSelectDataType[]>([{ text: "전체", val: '0', adstDliStrCd: '' }]);
const [filteredEnvPartSigunData, setFilteredEnvPartSigunData] = useState<SelectDataType[]>([{ text: "전체", val: '0' }]);
// 시군구 세팅
const initializeSigunData = (sidoCd: string) => {
if (sidoCd === '0') {
setSigunValue('0');
setFilteredSigunData([{ text: "전체", val: '0' }]);
} else {
const newFilteredData = [
{ text: "전체", val: '0' },
...selectSigunData.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd)
];
setSigunValue('0');
setFilteredSigunData(newFilteredData);
}
}
// 단위유역 세팅
const initializeUnitWaterShedData = (regionCd: string) => {
if (regionCd === '0') {
setUnitWaterShedValue('0');
setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]);
} else {
const newFilteredData = [
{ text: "전체", val: '0' },
...selectUnitWaterShedData.filter((item: SelectDataType) => item.val.substring(0, 1) === regionCd)
];
setUnitWaterShedValue('0');
setFilteredUnitWaterShedData(newFilteredData);
}
}
// 중권역 세팅
const initializeMiddleRegionData = (unitWaterShedCd: string) => {
if (unitWaterShedCd === '0') {
setMiddleRegionValue('0');
setFilteredMiddleRegionData([{ text: "전체", val: '0' }]);
} else {
const newFilteredData = [
{ text: "전체", val: '0' },
...selectMiddleRegionData.filter((item: SelectDataType) => item.val.substring(0, 2) === unitWaterShedCd)
];
setMiddleRegionValue('0');
setFilteredMiddleRegionData(newFilteredData);
}
}
// 환경청 세팅 - 시도
const initializeCityDataByEnvPartSido = (envPartCd: string) => {
const foundEnvPart = selectEnvPartData.find((item: EnvPartSelectDataType) => item.val === envPartCd);
const cityArray = foundEnvPart?.adstDliStrCd.toString().split('|').join('').split(',');
// 시군구 데이터
const envSigunData = selectSigunData.filter((item: SelectDataType) => cityArray?.includes(item.val));
// 환경청 시도 데이터
const sidoArray = [...new Set(envSigunData.map((item: SelectDataType) => item.val.substring(0, 2)))];
const envSidoData = selectSidoData.filter((item: SelectDataType) => sidoArray?.includes(item.val));
setFilteredEnvPartSigunDataSelected(envSigunData);
setFilteredEnvPartSidoData([
{ text: "전체", val: '0', adstDliStrCd: '' },
...envSidoData.map((item: SelectDataType) => ({ text: item.text, val: item.val, adstDliStrCd: '' }))
]);
}
// 환경청 세팅 - 시군구
const initializeCityDataByEnvPartSigun = (sidoCd: string) => {
const envSigunData = filteredEnvPartSigunDataSelected.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd);
setFilteredEnvPartSigunData([
{ text: "전체", val: '0' },
...envSigunData.map((item: SelectDataType) => ({ text: item.text, val: item.val }))
]);
}
const onSelectValue = (val: string, type: string) => {
let selectedSido;
let selectedSigun;
let selectedEnvPartSido;
let selectedEnvPartSigun;
switch (type) {
case 'part':
setPartValue(val);
if (setRtnPartValue) {
setRtnPartValue(val);
}
// 구분
if (val == 'R') {
initializeMiddleRegionData('0');
initializeUnitWaterShedData('0');
} else if (val == 'G') {
setFilteredEnvPartData([
{ text: "전체", val: '0', adstDliStrCd: '' },
...selectEnvPartData.filter((item: EnvPartSelectDataType) => item.val !== null && item.adstDliStrCd !== '')
]);
setEnvPartValue('0');
initializeCityDataByEnvPartSido('0');
} else {
initializeSigunData('0');
onSelectValue(selectSigunData[0]?.val || '0', 'sigun');
}
// 다른 selectbox 전체로 초기화
onSelectValue(selectSidoData[0]?.val || '0', 'sido');
onSelectValue(selectSigunData[0]?.val || '0', 'sigun');
break;
case 'sido':
setSidoValue(val);
selectedSido = selectSidoData.find(item => item.val === val);
setSidoText(selectedSido?.text || '');
if (setRtnSidoValue) {
setRtnSidoValue(val);
}
if (setRtnSidoText) {
setRtnSidoText(selectedSido?.text || '');
}
initializeSigunData(val);
onSelectValue(selectSigunData[0]?.val || '0', 'sigun');
break;
case 'sigun':
if (setRtnSigunValue) {
setRtnSigunValue(val);
}
setSigunValue(val);
selectedSigun = filteredSigunData.find(item => item.val === val);
if (setRtnSigunText) {
setRtnSigunText(selectedSigun?.text || '');
}
setSigunText(selectedSigun?.text || '');
break;
// 유역 세팅
case 'region':
setRegionValue(val);
if (setRtnRegionValue) {
setRtnRegionValue(val);
}
initializeUnitWaterShedData(val);
onSelectValue(selectUnitWaterShedData[0]?.val || '0', 'unitWaterShed');
break;
case 'unitWaterShed':
setUnitWaterShedValue(val);
if (setRtnUnitWaterShedValue) {
setRtnUnitWaterShedValue(val);
}
initializeMiddleRegionData(val);
onSelectValue(selectMiddleRegionData[0]?.val || '0', 'middleRegion');
break;
case 'middleRegion':
setMiddleRegionValue(val);
if (setRtnMiddleRegionValue) {
setRtnMiddleRegionValue(val);
}
break;
// 환경청 세팅
case 'envPart':
setEnvPartValue(val);
if (setRtnEnvPartValue) {
setRtnEnvPartValue(val);
}
initializeCityDataByEnvPartSido(val);
onSelectValue(filteredEnvPartSidoData[0]?.val || '0', 'envPartSido');
break;
case 'envPartSido':
setSidoValue(val);
selectedEnvPartSido = filteredEnvPartSidoData.find(item => item.val === val);
setSidoText(selectedEnvPartSido?.text || '');
if (setRtnEnvPartSidoValue) {
setRtnEnvPartSidoValue(val);
}
initializeCityDataByEnvPartSigun(val);
onSelectValue(filteredEnvPartSigunData[0]?.val || '0', 'envPartSigun');
break;
case 'envPartSigun':
setSigunValue(val);
selectedEnvPartSigun = filteredEnvPartSigunData.find(item => item.val === val);
setSigunText(selectedEnvPartSigun?.text || '');
if (setRtnEnvPartSigunValue) {
setRtnEnvPartSigunValue(val);
}
break;
}
}
// 리셋 함수
const resetAllValues = () => {
setPartValue('A');
setSidoValue('0');
setSigunValue('0');
setRegionValue('0');
setUnitWaterShedValue('0');
setMiddleRegionValue('0');
setEnvPartValue('0');
setFilteredSigunData([{ text: "전체", val: '0' }]);
setFilteredUnitWaterShedData([{ text: "전체", val: '0' }]);
setFilteredMiddleRegionData([{ text: "전체", val: '0' }]);
setFilteredEnvPartData([{ text: "전체", val: '0', adstDliStrCd: '' }]);
setFilteredEnvPartSidoData([{ text: "전체", val: '0', adstDliStrCd: '' }]);
setFilteredEnvPartSigunData([{ text: "전체", val: '0' }]);
if (setRtnPartValue) setRtnPartValue('A');
if (setRtnSidoValue) setRtnSidoValue('0');
if (setRtnSigunValue) setRtnSigunValue('0');
if (setRtnRegionValue) setRtnRegionValue('0');
if (setRtnUnitWaterShedValue) setRtnUnitWaterShedValue('0');
if (setRtnMiddleRegionValue) setRtnMiddleRegionValue('0');
if (setRtnEnvPartValue) setRtnEnvPartValue('0');
if (setRtnEnvPartSidoValue) setRtnEnvPartSidoValue('0');
if (setRtnEnvPartSigunValue) setRtnEnvPartSigunValue('0');
};
// 리셋 트리거 변경 감지
useEffect(() => {
if (resetTrigger) {
resetAllValues();
// 리셋 후 트리거를 false로 설정
if (setRtnPartValue) {
setRtnPartValue('0');
}
}
}, [resetTrigger]);
return (
isShowPart ? (
<div className="flex gap-5">
<SelectBox className="w-auto whitespace-nowrap" label={'구분'} selectArray={isAdmin ? selectPartData.slice(0, 1) : selectPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'part')} value={partValue} selectClass={'w-32'} />
{partValue === 'R' ? (
<>
<SelectBox className="w-auto whitespace-nowrap" label={'유역'} selectArray={selectRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'region')} value={regionValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'단위유역'} selectArray={filteredUnitWaterShedData} onSelectValue={(val) => onSelectValue(val.toString(), 'unitWaterShed')} value={unitWaterShedValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'중권역'} selectArray={filteredMiddleRegionData} onSelectValue={(val) => onSelectValue(val.toString(), 'middleRegion')} value={middleRegionValue} selectClass={'w-44'} />
</>
) : partValue === 'G' ? (
<>
<SelectBox className="w-auto whitespace-nowrap" label={'환경청'} selectArray={filteredEnvPartData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPart')} value={envPartValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={filteredEnvPartSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSido')} value={sidoValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredEnvPartSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'envPartSigun')} value={sigunValue} selectClass={'w-44'} />
</>
) : (
<>
<SelectBox className="w-auto whitespace-nowrap" label={'시도'} selectArray={selectSidoData} onSelectValue={(val) => onSelectValue(val.toString(), 'sido')} value={sidoValue} selectClass={'w-44'} />
<SelectBox className="w-auto whitespace-nowrap" label={'시군구'} selectArray={filteredSigunData} onSelectValue={(val) => onSelectValue(val.toString(), 'sigun')} value={sigunValue} selectClass={'w-44'} />
</>
)}
</div>
) : (
<div className="grid grid-cols-12 gap-5 w-11/12 m-4">
{children}
</div>
)
)
}
export { MapSearchFormLeft };
+578 -282
View File
@@ -1,55 +1,40 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { excelDownload } from "@/components/lib/func/commom";
import { Title, UiTable, UITab, ContentsDiv } from '@common/business_components';
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { Button } from "@common/components/ui";
import React, { useCallback, useState, useEffect } from 'react';
"use client"
import NewWindowPortal from '@/app/map/newWindowPortal';
import PbnstPrfmncSttnPopup from "@/app/map/pbnstPrfmncSttnPopup";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import type { chgBuilding, customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import RainPrfmncSttnPopup from "@/app/map/rainPrfmncSttnPopup";
import RswtrPrfmncsSttnPopup from "@/app/map/rswtrPrfmncSttnPopup";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import HtdflPrfmncSttnPopup from "@/app/map/htdflPrfmncSttnPopup";
import { useWrStore } from "@/app/store";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import type { customPbnst, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import { tableData } from "@/components/lib/func/commom";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UITab, UiTable } from '@common/business_components';
import { useGisContext } from "@common/business_components/ui/map/Gis";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import React, { useCallback, useEffect, useState } from 'react';
interface NewWindowPopupProps {
featureData: any;
checkedLayers?: string[];
checkedLayersData?: any[];
seletectedLayerNm?: string
viewMode?: 'list' | 'detail' | 'nothing'
onFeatureSelect: (data: any) => void;
onClose: () => void;
}
// 탭
const TABS = [
{ val: "0", text: "재이용시설1" },
{ val: "1", text: "재이용시설2" },
{ val: "2", text: "재이용시설n" },
];
// 데이터의 속성(key)을 사용자에게 보여줄 한글 이름으로 변환하기 위한 맵
// 실제 데이터에 맞게 이 부분을 확장해야 합니다.
const propertyNameMap: { [key: string]: string } = {
fid: '고유 ID',
fcltNm: '시설명',
opertDe: '운영일자',
addr: '주소',
// ... 필요한 만큼 속성 매핑 추가
};
const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
featureData,
checkedLayers = [],
checkedLayersData = [],
seletectedLayerNm,
onFeatureSelect,
onClose
}) => {
const [activeTab, setActiveTab] = useState(TABS[0]?.val ?? "0");
// swcho : useState의 true, false 값 변경하여 목록, 상태 테스트 하였음
const [showDetailView, setShowDetailView] = useState(true); // 상세정보 화면 표시 상태 추가
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]);
const [activeTab, setActiveTab] = useState<string>('0');
const [viewMode, setViewMode] = useState<'list' | 'detail' | 'nothing'>('list');
const [fcltPk, setFcltPk] = useState<string>('');
// onClose 함수를 useCallback으로 메모이제이션
const memoizedOnClose = useCallback(() => {
@@ -62,320 +47,631 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
pbnstSttn,
pbnstSttnSearch,
pbnSttnInit,
getPbnStnDetail,
pbnNmSearch,
getFlcts
} = useWrStore((state) => state);
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>();
const [pageNation, setPageNation] = useState(1);
const [pbnDetaileData, setPbnDetaileData] = useState<{
isModal: boolean;
data: customPbnst;
}>({ isModal: false, data: {} as customPbnst });
const { fclts, pbnstSttnResCount } = pbnstSttn
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>()
// 빗물재이용시설 변수
const { rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
(state) => state
);
const { rainSttnRes } = rainSttn;
const { rainSttnRes, rainSttnResCount } = rainSttn;
const [rainTable, setRainTable] = useState<customRainBdst[]>();
const [rainBdstChgProps, setRainBdstChgProps] = useState<{
isOpen: boolean;
chBuilding: chgBuilding[];
}>({ isOpen: false, chBuilding: [] });
const [rainPage, setRainPage] = useState(1)
const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false });
const [rainList, setRainList] = useState<customRainBdst[]>(rainSttnRes || []);
// 중수도시설 변수
const { rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
(state) => state
);
const { rswtSttnRes } = rswtSttn;
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>();
const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false });
const [rswtrBdstChgProps, setRswtrBdstChgProps] = useState<{
isOpen: boolean;
chBuilding: chgBuilding[];
}>({ isOpen: false, chBuilding: [] });
const [rswtrPage, setRswtrPage] = useState(1);
const [rswtrList, setRswtrList] = useState<customRswtBdst[]>(rswtSttnRes || []);
// 온배수시설 변수
const { htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
const { htdflSttnRes } = htdflSttn;
const { htdflSttnRes,htdflSttnResCount } = htdflSttn;
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false });
const [bdstChgProps, setBdstChgProps] = useState<{ isOpen: boolean, chBuilding: chgBuilding[] }>({ isOpen: false, chBuilding: [] });
const [htdflPage, setHtdflPage] = useState(1)
const [htdflList, setHtdflList] = useState<customHtdflBdst[]>(htdflSttnRes || []);
if (!featureData) {
return null;
//하수처리시설 변수
const {
pbnst,
pubHasuInit,
} = useWrStore((state) => state);
const { pubFacHeadList, pbnstHasuRes } = pbnst;
const [hasuList, setHasuList] = useState<pubHasuType[]>(pbnstHasuRes || []);
const [isRuseReg, setIsRuseReg] = useState<{
data: any | undefined;
}>({ data: undefined });
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
const [hasuPage, setHasuPage] = useState<number>(1);
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
const getSelectedLayers = () => {
let result = null;
const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
let featureLayer: { get: (key: string) => any } = {get:()=> null};
layers.forEach((layer: any) => {
const source = layer.getSource();
if (source && source.hasFeature && featureData
&& typeof featureData.getId === 'function' && source.hasFeature(featureData)) {
featureLayer = layer; // 피처가 속한 레이어 찾기)
}
});
result = featureLayer.get('lyrNm');
return result;
};
const fetchpbnstDetail = async (featureCd: string) => {
try {
const response = await getFetch("wr", `/reuseFc/pubFc/${featureCd}`);
// 중복 데이터 추가 방지
setTabDataFunc(response, featureCd);
} catch (error) {
console.error("Error fetching data:", error);
}
};
const fetchHasuDetail = async (featureCd: string, data: string) => {
try {
const rainRes = await postFectch(`/prcsFclt/ruseInfo/1/10/A/0/0/1/SW/${featureCd}`, [data], fetchType.COMMON)
setHasuList(
rainRes.data.map((item: any) => {
return {
...item,
fctCpc: Number(item.fctCpc) || 0,
ruse: item.ruse === false ? "N" : "Y",
};
})
)
} catch (error) {
console.error("Error fetching data:", error);
}
};
const detainSttn = async (featureCd: string, layerNm: string) => {
if (layerNm == '빗물이용시설') {
const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`)
setRainList(res)
}
else if(layerNm == '중수도시설'){
const res = await getFetch(fetchType.WR,`/reuseFc/waterreuseFc/1/20/0/${featureCd}`)
setRswtrList(res)
}
else{
const res = await getFetch(fetchType.WR, `/drain/facilityList/1/20/0/${featureCd}`)
setHtdflList(res)
setHtdflDetailModal({ isOpen: true, data: htdflSttnRes[0] });
}
}
// 상세 목록 데이터 상태 처리
useEffect(()=>{
if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] });
},[hasuList])
useEffect(()=>{
if (rainList.length > 0) setRainDetailModal({ isOpen: true, data: rainList[0] });
},[rainList])
useEffect(()=>{
if (rswtrList.length > 0) setRswtrDetailModal({ isOpen: true, data: rswtrList[0] });
},[rswtrList])
useEffect(()=>{
if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] });
},[htdflList])
// 2. RuseMngTable에 필요한 tableData를 생성합니다. (단일 행 데이터)
const tableData = [featureData];
console.log("tableData", tableData);
const layerId = getSelectedLayers();
if (featureData && typeof featureData.getProperties === "function") {
const selectedVal = featureData.getProperties();
let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null;
if (featureCd && featureCd !== fcltPk) {
if (layerId == '하수재이용시설') {
featureCd = selectedVal?.swtrmt_fclt_cd;
setFcltPk(featureCd); // 현재 호출된 featureCd 저장
setActiveTab(featureCd)
fetchpbnstDetail(featureCd); // 상세정보
}
else if (layerId == '하수처리시설') {
featureCd = selectedVal?.swtrmt_fclt_nm;
setFcltPk(featureCd); // 현재 호출된 featureCd 저장
fetchHasuDetail(featureCd, selectedVal?.swtrmt_fclt_cd);
}
else {
featureCd = selectedVal?.bdst_nm;
setFcltPk(featureCd)
if (layerId) {
detainSttn(featureCd, layerId);
}
}
setViewMode("detail")
}
} else if (layerId === null && seletectedLayerNm) { setViewMode("list") }
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
// 물재이용시설 cellClick 이벤트 (상세정보)
///////////////////////////////////////////// 하수재이용시설 //////////////////////////////////////////////////
// 재이용시설 cellClick 이벤트 (상세정보)
const pbnstCellClick = (index: number | undefined) => {
if (
index !== undefined &&
pbnstSttn.pbnstSttnRes &&
pbnstSttn.pbnstSttnRes[index]
) {
const pbnstRuseFcltPk = pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk;
getPbnStnDetail(pbnstRuseFcltPk);
setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltId);
onFeatureSelect(pbnstSttn.pbnstSttnRes[index]);
onClose()
}
};
// 재이용 현황 초기값
useEffect(() => {
if (!pbnstSttn.isInit) {
getFlcts()
}
}, [seletectedLayerNm, pbnstSttn.isInit, getFlcts]);
useEffect(()=>{
pbnSttnInit("1", "15", {
partValue: "A",
sidoValue: '0',
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: ""
}, String(new Date().getFullYear()), pbnstSttn.fclts);
}, [fclts, pbnSttnInit, pbnstSttn.fclts])
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [pbnstSttn.pbnstSttnRes]);
useEffect(() => {
if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk) setShowDetailView(true);
}, [pbnstSttn.pbnstDetail]);
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
// 재이용시설 상세정보
const setTabDataFunc = (res: any, pk: string) => {
setTabData((prev) => {
if (prev.some((tab) => tab.id === pk)) {
return prev; // 이미 존재하는 탭이면 추가하지 않음
}
return [...prev, { id: pk, name: `재이용시설 ${prev.length + 1}`, data: res }];
});
}
// 재이용시설 조회
// 재이용시설 페이징처리 관련 함수
const onPageChangeHandler = useCallback((page: number) => {
pbnstSttnSearch(
false,
String(page),
String(13),
{
partValue: "A",
sidoValue: "0",
sigunValue: "0",
regionValue: "",
unitWaterShedValue: "",
middleRegionValue: "",
envPartValue: "",
sidoText: "",
sigunText: "",
},
"",
String(new Date().getFullYear()), fclts
);
}, [fclts, pbnstSttnSearch]);
// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제.
// const excelClick = useCallback(() => {
// // if (codeData) pbnstSttnSearch(1, "10000", codeData);
// excelDownload(
// [[]],
// "하수재이용시설 현황",
// "sample_pbnstSttn.xlsx",
// "A1:U2"
// );
// }, [pbnstSttnSearch]);
///////////////////////////////////////////// 하수재이용시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 빗물 재이용 //////////////////////////////////////////////////
// 빗물재이용시설 cellClick 이벤트 (상세정보)
const rainCellClick = (index: number | undefined, headId: string) => {
if (
index !== undefined &&
rainTable !== undefined &&
headId !== 'chBuildingYn') {
setRainDetailModal({ isOpen: true, data: rainTable[index] })
} else if (headId === 'chBuildingYn' && index !== undefined && rainTable !== undefined) {
if (rainTable[index] && rainTable[index]?.chgBuilding[0]?.bdstChgNm !== null)
setRainBdstChgProps({ isOpen: true, chBuilding: rainTable[index].chgBuilding });
// setRainDetailModal({ isOpen: true, data: rainTable[index] })
// setViewMode('detail')
onFeatureSelect(rainTable[index]);
onClose();
}
}
useEffect(() => {
if (!rainSttn.isInit) {
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rainSttn.isInit, rainSttnInit]);
useEffect(() => {
const data = tableData(rainSttnRes, { code });
const chData = data
.map((item: any) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].rainyObj,
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst: item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
};
})
.filter((item: any) => item.rainyObj !== undefined);
setRainTable(chData);
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
useEffect(() => {
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
///////////////////////////////////////////// 빗물 재이용 //////////////////////////////////////////////////
///////////////////////////////////////////// 중수도 시설 //////////////////////////////////////////////////
// 중수도시설 cellClick 이벤트 (상세정보)
const rswtCellClick = (index: number | undefined, headId: string) => {
if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] })
} else if (headId === 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
if (rswtrTable[index] && rswtrTable[index]?.chBuildingYn === 'Y') {
setRswtrBdstChgProps({ isOpen: true, chBuilding: rswtrTable[index].chgBuilding });
}
// setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] });
// setViewMode('detail')
onFeatureSelect(rswtrTable[index]);
onClose();
}
}
useEffect(() => {
if (!rswtSttn.isInit) {
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
useEffect(() => {
const data = tableData(rswtSttnRes, { code });
const chData = data
.map((item: customRswtBdst) => {
return {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0]?.rswtrObj,
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
}
})
.filter(
(item: customRswtBdst) =>
item.reuseBuilding[0]?.rswtrObj !== undefined
);
setRswtrTable(chData);
}, [code, rswtSttnRes]);
// FIXME: 윤선화 차장님 요구사항으로 엑셀 다운로드 삭제.
// const rswtSttnExcelDownload = useCallback(() => {
// if (rswtSttn.excelList.length > 0) {
// if (rswtSttn.excelList.length === 0) return;
// excelDownload(
// rswtSttn.excelList,
// "중수도시설 현황",
// "sample_rswtSttn.xlsx",
// "A1:W3",
// );
// }
// }, [rswtSttn.excelList])
useEffect(() => {
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
///////////////////////////////////////////// 중수도 시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 온배수 시설 //////////////////////////////////////////////////
// 온배수시설 cellClick 이벤트 (상세정보)
const htdflCellClick = (index: number | undefined, headId: string) => {
if (
headId !== "chBuildingYn" &&
index !== undefined &&
htdflTable !== undefined
) {
setHtdflDetailModal({ isOpen: true, data: htdflTable[index] });
const htdflCellClick = (index: number | undefined) => {
if (index !== undefined && htdflTable !== undefined) {
onFeatureSelect(htdflTable[index]);
onClose();
}
};
useEffect(() => {
if (!htdflSttn.isInit) {
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
}
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
const excelClick = useCallback(() => {
// if (codeData) pbnstSttnSearch(1, "10000", codeData);
excelDownload(
[[]],
"하수재이용시설 현황",
"sample_pbnstSttn.xlsx",
"A1:U2"
);
}, [pbnstSttnSearch]);
useEffect(() => {
const data = tableData(htdflSttnRes, { code });
const chData = data
.map((item: any) => ({
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].htdflObj,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
}))
.filter((item: any) => item.htdflObj !== undefined);
setHtdflTable(chData);
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
useEffect(() => {
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
///////////////////////////////////////////// 온배수 시설 //////////////////////////////////////////////////
///////////////////////////////////////////// 하수처리 시설 //////////////////////////////////////////////////
useEffect(() => {
if (code.sggCd.length && pbnstHasuRes.length > 0) {
setHasuTable(tableData(pbnstHasuRes, { code }));
}
}, [code, pbnstHasuRes]);
useEffect(() => {
if (!pbnst.isInit) {
pubHasuInit("1", "0");
}
}, [pbnst.isInit, pubHasuInit]);
useEffect(() => {
pubHasuInit(String(hasuPage), "0");
}, [hasuPage, pubHasuInit]);
const hasuCellClick = (index: number | undefined) => {
if (index !== undefined && pbnstHasuRes !== undefined) {
onFeatureSelect(pbnstHasuRes[index]);
onClose();
}
};
///////////////////////////////////////////// 하수처리 시설 //////////////////////////////////////////////////
// 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수
const renderConditionalContent = () => {
// 특정 레이어가 체크되었는지 확인
const hasWaterTreatmentLayer = checkedLayersData.some(layer =>
layer.data?.lyrNm?.includes('하수처리') || layer.data?.lyrNm?.includes('재이용시설')
);
// swcho : true, false 값 변경하여 시설 변경하여 테스트하였음
const actTabData = tabData.find((tab) => tab.id === activeTab);
let layerId:string | undefined | null = getSelectedLayers();
if (layerId === null || layerId === undefined) {
layerId = seletectedLayerNm || '';
}
//하수처리시설
const isPrcsFclt = layerId == '하수처리시설'
// 재이용시설
const isPbnst = true;
const isPbnst = layerId == '하수재이용시설';
// 빗물이용시설
const isRain = false;
const isRain = layerId == '빗물이용시설';
// 중수도시설
const isRswt = false;
const isRswt = layerId == '중수도시설';
// 온배수시설
const isHtdfl = false;
const isHtdfl = layerId == '온배수시설';
if (isPrcsFclt) {
if (viewMode == 'list') {
return (
<>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 현황" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={hasuTable || []}
headlist={pubFacHeadList}
pageSize={10}
total={5000}
headName={""}
cellClick={hasuCellClick}
onPageChange={setHasuPage}
/>
</>
)
} else {
return (
<>
<div className="flex justify-between items-center mb-4">
<Title title="하수처리시설 상세정보" />
</div>
{/* 높이 조정 */}
<UiTable
tableData={isRuseReg?.data || []}
headlist={pubFacHeadList.slice(0, 4)}
pageSize={1}
total={0}
headName={"위치정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
<UiTable
tableData={isRuseReg?.data || []}
headlist={pubFacHeadList.slice(4)}
pageSize={1}
total={0}
headName={"기본정보"}
cellClick={() => { }}
onPageChange={() => { }}
/>
</>
)
}
}
if (isPbnst) {
if (viewMode == 'detail') {
// 재이용시설 상세
return (
<>
<div className="flex justify-between items-center mb-4">
<Title title="하수재이용시설 상세정보" />
</div>
<div className="flex justify-between items-center mb-8">
<UITab
defaultValue={activeTab}
tabList={tabData.map((tab) => ({
value: tab.id,
label: tab.name,
onClick: () => setActiveTab(tab.id),
}))}
/>
</div>
<PbnstSttnModal
data={actTabData?.data[0] || ({} as customPbnst)}
titleVisible={false}
/>
</>
);
} else {
// 재이용시설 목록
return (
<>
<div className="flex justify-between items-center">
<Title title="하수재이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={bdstTable || []}
headlist={pbnstSttn.pbnstSttHeadList}
pageSize={20}
total={pbnstSttnResCount || 0}
cellClick={(index: number | undefined) => {
pbnstCellClick(index);
}}
onPageChange={onPageChangeHandler}
>
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
</UiTable>
</>
);
}
}
if (isRain) {
if (viewMode == 'detail') {
// 빗물이용시설 상세
return (
<SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} />
);
} else {
// 빗물이용시설 목록
return (
<>
<div className="flex justify-between items-center">
<Title title="빗물이용시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rainTable || []}
headlist={rainSttn.rainSttHeadList}
pageSize={20}
total={rainSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rainCellClick(index ?? undefined, headId);
}}
onPageChange={setRainPage}
>
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
</UiTable>
</>
);
}
}
return (
<div className="mt-4">
{/* 체크된 레이어가 없는 경우 (재이용시설 목록) */}
{isPbnst && (
if (isRswt) {
if (viewMode == 'detail') {
// 중수도시설 상세
return (
<SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} />
);
} else {
// 중수도시설 목록
return (
<>
{showDetailView ? (
// 재이용시설 상세
<>
<div className="flex justify-between items-center mb-4">
<Title title='하수재이용시설 상세정보' />
</div>
<div className="flex justify-between items-center mb-8">
<UITab
defaultValue={TABS[0]?.val}
tabList={TABS.map((tab) => ({
value: tab.val,
label: tab.text,
onClick: () => setActiveTab(tab.val),
}))}
children={undefined}
/>
</div>
<PbnstSttnModal
data={pbnDetaileData.data || ({} as customPbnst)}
titleVisible={false}
/>
<PbnstPrfmncSttnPopup isVisible={false} />
</>
) : (
// 재이용시설 목록
<>
<div className="flex justify-between items-center">
<Title title='하수재이용시설 현황' />
<div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>엑셀다운로드</Button>
</div>
</div>
<UiTable
headName={[]}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
}
headlist={pbnstSttn.pbnstSttHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
pbnstCellClick(index);
}}
onPageChange={setPageNation}
/>
</>
)}
<div className="flex justify-between items-center">
<Title title="중수도시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={rswtrTable || []}
headlist={rswtSttn.rswtSttHeadList}
pageSize={20}
total={rswtSttnResCount}
cellClick={(index: number | undefined, headId: string) => {
rswtCellClick(index, headId);
}}
onPageChange={setRswtrPage}
>
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
</UiTable>
</>
)}
{/* 빗물이용시설 */}
{isRain && (
);
}
}
if (isHtdfl) {
if (viewMode == 'detail') {
// 온배수시설 상세
return (
<SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} />
);
} else {
// 온배수시설 목록
return (
<>
{showDetailView ? (
// 빗물이용시설 상세
<>
<div className="flex justify-between items-center mb-4">
<Title title='빗물이용시설 상세정보' />
</div>
<RainPrfmncSttnPopup rainForm={rainDetailModal.data as customRainBdst} isModal={false} />
{/* TODO: 지도 점검 결과 현황 추가 할 것 */}
</>
) : (
// 빗물이용시설 목록
<>
<div className="flex justify-between items-center">
<Title title='빗물이용시설 현황' />
<div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>엑셀다운로드</Button>
</div>
</div>
<UiTable
headName={[]}
tableData={rainTable || []}
children={
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
}
headlist={rainSttn.rainSttHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
rainCellClick(index ?? undefined, headId)
}}
onPageChange={setPageNation}
/>
</>
)}
<div className="flex justify-between items-center">
<Title title="온배수시설 현황" />
{/* <div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>
엑셀다운로드
</Button>
</div> */}
</div>
<UiTable
headName={[]}
tableData={htdflTable || []}
headlist={htdflSttn.htdflSttHeadList}
pageSize={20}
total={htdflSttnResCount || 0}
cellClick={(index: number | undefined) => {
htdflCellClick(index ?? undefined);
}}
onPageChange={setHtdflPage}
>
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
</UiTable>
</>
)}
{/* 중수도시설 */}
{isRswt && (
<>
{showDetailView ? (
// 재이용시설 상세
<>
<div className="flex justify-between items-center mb-4">
<Title title='중수도시설 상세정보' />
</div>
<RswtrPrfmncsSttnPopup rswtForm={rswtrDetailModal.data as customRswtBdst} isModal={false} />
{/* TODO: 지도 점검 결과 현황 추가 할 것 */}
</>
) : (
// 재이용시설 목록
<>
<div className="flex justify-between items-center">
<Title title='중수도시설 현황' />
<div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>엑셀다운로드</Button>
</div>
</div>
<UiTable
headName={[]}
tableData={rswtrTable || []}
children={
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
}
headlist={rswtSttn.rswtSttHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
rswtCellClick(index, headId);
}}
onPageChange={setPageNation}
/>
</>
)}
</>
)}
{/* 온배수시설 */}
{isHtdfl && (
<>
{showDetailView ? (
// 재이용시설 상세
<>
<div className="flex justify-between items-center mb-4">
<Title title='온배수시설 상세정보' />
</div>
{/* <HtdflPrfmncSttnPopup htdflForm={htdflDetailModal.data as customHtdflBdst} isModal={false} /> */}
<HtdflPrfmncSttnPopup htdflForm={htdflDetailModal.data as customHtdflBdst} isModal={false} />
</>
) : (
// 재이용시설 목록
<>
<div className="flex justify-between items-center">
<Title title='온배수시설 현황' />
<div className="flex gap-2 mt-8">
<Button className={btnClass} color="primary" onClick={excelClick}>엑셀다운로드</Button>
</div>
</div>
<UiTable
headName={[]}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
}
headlist={htdflSttn.htdflSttHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
htdflCellClick(index ?? undefined, headId);
}}
onPageChange={setPageNation}
/>
</>
)}
</>
)}
</div>
);
);
}
}
return null; // 조건에 맞는 콘텐츠가 없을 경우
};
return (
<NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보">
{/* 체크된 레이어에 따른 조건부 렌더링 */}
{renderConditionalContent()}
</NewWindowPortal>
viewMode == 'nothing' ? <></> :
<NewWindowPortal onClose={memoizedOnClose} title="시설 상세 정보">
{/* 체크된 레이어에 따른 조건부 렌더링 */}
{renderConditionalContent()}
</NewWindowPortal>
);
};
+2 -2
View File
@@ -48,7 +48,7 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti
if (newWindowRef.current && !newWindowRef.current.closed) return;
// 1. 새 창을 열고 참조를 저장합니다.
newWindowRef.current = window.open('', title, 'width=1400,height=1024,resizable=yes,scrollbars=yes');
newWindowRef.current = window.open('', title, 'width=900,height=800,resizable=yes,scrollbars=yes');
if (newWindowRef.current) {
newWindowRef.current.document.title = title;
@@ -81,7 +81,7 @@ const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, ti
onCloseRef.current();
// onClose();
}
}, [onClose, title]);
}, [handleUnload, onClose, title]);
// `createPortal`을 사용해 children을 새 창의 container div에 렌더링합니다.
return container ? createPortal(children, container) : null;
-596
View File
@@ -1,596 +0,0 @@
"use client";
import { useWrStore } from "@/app/store";
import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SelectBox, UiTable, type ChartConfig, type ReturnType } from "@common/business_components";
import ListDiv from "@common/business_components/ui/list_div";
import { useEffect, useRef, useState } from "react";
import { Toaster } from "react-hot-toast";
interface PbnstPrfmncSttnPopupProps {
isVisible?: boolean;
}
export default function PbnstPrfmncSttnPopup({ isVisible = true }: PbnstPrfmncSttnPopupProps) {
const { code, tableHeadMaker, pbnstPrfmncSttn, pbnstPrfmncInit, pbnstPrfmncSearch, prfmnc } = useWrStore((state) => state);
const { monthHeadList } = prfmnc
const { pbnstPrfHeadList, pbnstPrfmncRes, prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn;
const [isChHead, setIsChHead] = useState(false);
const [fromDate, setFromDate] = useState<string>(String(new Date().getFullYear()));
const [toDate, setToDate] = useState<string>(String(new Date().getFullYear()));
const [year, setYear] = useState<string>(String(new Date().getFullYear()));
const [bdstTable, setbdstTable] = useState<FcPrfType[]>();
const ref = useRef<ReturnType>({} as ReturnType);
const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>();
const [chartConfig, setChartConfig] = useState<ChartConfig>({});
const [chartData, setChartData] = useState<dnChartForm[]>([]);
const [dnInUsage, setDnInUsage] = useState<dnChartForm[]>([]);
const [dnInChartConfig, setDnInChartConfig] = useState<ChartConfig>({});
const [dnOutUsage, setDnOutUsage] = useState<dnChartForm[]>([]);
const [dnOutChartConfig, setDnOutChartConfig] = useState<ChartConfig>({});
const [barData, setBarData] = useState<barChartForm[]>([]);
const [barChartConfig, setBarChartConfig] = useState<ChartConfig>({});
const [prfData, setPrfData] = useState<any[]>();
const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({});
const [lnOutChartConfig, setLnOutChartConfig] = useState<ChartConfig>({});
const [inLineData, setInLineData] = useState<{
chartData1: lineChartDataProps[];
chartData2: lineChartDataProps[];
chartData3: lineChartDataProps[];
chartData4: lineChartDataProps[];
chartData5: lineChartDataProps[];
chartData6: lineChartDataProps[];
chartData7: lineChartDataProps[];
chartData8: lineChartDataProps[];
chartData9: lineChartDataProps[];
}>();
// const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({});
const [outLineData, setOutLineData] = useState<{
chartData1: lineChartDataProps[];
chartData2: lineChartDataProps[];
chartData3: lineChartDataProps[];
chartData4: lineChartDataProps[];
chartData5: lineChartDataProps[];
chartData6: lineChartDataProps[];
}>();
type dnChartForm = { label: string, val: number, fill?: string };
type barChartForm = { label: string, "장내용수": number, "장외용수": number };
type lineChartDataProps = { label: string, val: number, color: string };
const prfTableData = (prfList: PrfType[], year: string) => {
const inUsageData = initValInUsage;
const outUsageData = initValOutUsage;
const inSubtotal = subTotalObj;
const outSubtotal = subTotalObj;
console.log(' prfList ', prfList)
const prfFilter = prfList?.filter((e) => e.ym.slice(0, 4) === year)
if (prfList && prfFilter.length > 0) {
prfList?.forEach((prfItem) => {
const month = Number(prfItem?.ym?.slice(4)); // "MM"
const monthKey = `${month}월`;
inUsageData.forEach((inData: any) => {
const usageKey = inData.usage;
const value = (prfItem as any)[usageKey] ?? 0;
inData[monthKey] = value;
inData.total += value;
if (inSubtotal && usageKey !== "subtotal") {
(inSubtotal as any)[monthKey] =
((inSubtotal as any)[monthKey] ?? 0) + value;
inSubtotal.total += value;
}
});
outUsageData.forEach((outData: any) => {
const usageKey = outData.usage;
const value = (prfItem as any)[usageKey] ?? 0;
outData[monthKey] = value;
outData.total += value;
if (usageKey !== "subtotal") {
(outSubtotal as any)[monthKey] =
((outSubtotal as any)[monthKey] ?? 0) + value;
outSubtotal.total += value;
}
});
});
inUsageData.push(inSubtotal);
outUsageData.push(outSubtotal);
const usageTotalObj: { [key: string]: any } = totalObj;
for (const key in usageTotalObj) {
if (["usage", "gubun", "edit"].includes(key)) continue;
const val =
(Number((inSubtotal as any)[key]) || 0) +
(Number((outSubtotal as any)[key]) || 0);
(usageTotalObj as any)[key] = val;
}
const tableData = [...inUsageData, ...outUsageData, usageTotalObj];
setPrfData(tableData);
} else {
setPrfData([]);
}
}
useEffect(() => {
let wshwtr = 0;
let coolUswtr = 0;
let cleanUswtr = 0;
let drwtUswtr = 0;
let dltnUswtr = 0;
let ithlRswtr = 0;
let ithlEtcUswtr = 0;
let cleanToilUswtr = 0;
let resn = 0;
let lndwtr = 0;
let hydUswtr = 0;
let ugwtChr = 0;
let farmUswtr = 0;
let rvrKeepUswtr = 0;
let indstUswtr = 0;
if (rawData) {
rawData.forEach((item) => {
prfTableData(item.prfList, year);
item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => {
wshwtr += element.wshwtr; //세척수
coolUswtr += element.coolUswtr; //냉각수
cleanUswtr += element.cleanUswtr; //청소수
drwtUswtr += element.drwtUswtr; //식수대
dltnUswtr += element.dltnUswtr //희석용수
ithlRswtr += element.ithlRswtr //중수도
ithlEtcUswtr += element.ithlEtcUswtr //기타
cleanToilUswtr += element.cleanToilUswtr //청소화장실용수
resn += element.resn //세척살수용수
lndwtr += element.lndwtr; //조경용수
hydUswtr += element.hydUswtr; //친수용수
ugwtChr += element.ugwtChr; //지하수충전
farmUswtr += element.farmUswtr //농업용수
rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수
indstUswtr += element.indstUswtr //공업용수
});
})
const data: dnChartForm[] = []
data?.push({ label: "세척수", val: wshwtr, fill: "red" })
data?.push({ label: "냉각수", val: coolUswtr, fill: "orange" })
data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" })
data?.push({ label: "식수대", val: drwtUswtr, fill: "green" })
data?.push({ label: "희석용수", val: dltnUswtr, fill: "skyblue" })
data?.push({ label: "중수도", val: ithlRswtr, fill: "blue" })
data?.push({ label: "기타", val: ithlEtcUswtr, fill: "purple" })
data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "red" })
data?.push({ label: "세척살수용수", val: resn, fill: "orange" })
data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" })
data?.push({ label: "친수용수", val: hydUswtr, fill: "green" })
data?.push({ label: "지하수충전", val: ugwtChr, fill: "skyblue" })
data?.push({ label: "농업용수", val: farmUswtr, fill: "blue" })
data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "purple" })
data?.push({ label: "공업용수", val: indstUswtr, fill: "black" })
setChartData(data);
}
}, [rawData, year])
useEffect(() => {
const newChartConfig = chartData.reduce((config, element) => {
config[element.label] = {
label: element.label,
fill: element.fill
};
return config;
}, {} as Record<string, { label: string; fill?: string }>) satisfies ChartConfig;
setChartConfig(newChartConfig);
}, [chartData]);
// 장내용수 도넛차트
useEffect(() => {
let wshwtr = 0;
let coolUswtr = 0;
let cleanUswtr = 0;
let drwtUswtr = 0;
let dltnUswtr = 0;
let ithlRswtr = 0;
let ithlEtcUswtr = 0;
let cleanToilUswtr = 0;
let resn = 0;
if (rawData) {
rawData.forEach((item) => {
item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => {
wshwtr += element.wshwtr; //세척수
coolUswtr += element.coolUswtr; //냉각수
cleanUswtr += element.cleanUswtr; //청소수
drwtUswtr += element.drwtUswtr; //식수대
dltnUswtr += element.dltnUswtr //희석용수
ithlRswtr += element.ithlRswtr //중수도
ithlEtcUswtr += element.ithlEtcUswtr //기타
cleanToilUswtr += element.cleanToilUswtr //청소화장실용수
resn += element.resn //세척살수용수
});
})
const data: dnChartForm[] = []
data?.push({ label: "세척수", val: wshwtr, fill: "yellow" })
data?.push({ label: "냉각수", val: coolUswtr, fill: "green" })
data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" })
data?.push({ label: "식수대", val: drwtUswtr, fill: "green" })
data?.push({ label: "희석용수", val: dltnUswtr, fill: "yellow" })
data?.push({ label: "중수도", val: ithlRswtr, fill: "green" })
data?.push({ label: "기타", val: ithlEtcUswtr, fill: "yellow" })
data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "green" })
data?.push({ label: "세척살수용수", val: resn, fill: "yellow" })
setDnInUsage(data);
}
}, [rawData, year])
useEffect(() => {
const newChartConfig = dnInUsage.reduce((config, element) => {
config[element.label] = {
label: element.label,
fill: element.fill
};
return config;
}, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig;
setDnInChartConfig(newChartConfig);
}, [dnInUsage]);
// 장외용수 도넛차트
useEffect(() => {
let lndwtr = 0;
let hydUswtr = 0;
let ugwtChr = 0;
let farmUswtr = 0;
let rvrKeepUswtr = 0;
let indstUswtr = 0;
if (rawData) {
rawData.forEach((item) => {
item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => {
lndwtr += element.lndwtr; //조경용수
hydUswtr += element.hydUswtr; //친수용수
ugwtChr += element.ugwtChr; //지하수충전
farmUswtr += element.farmUswtr //농업용수
rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수
indstUswtr += element.indstUswtr //공업용수
});
})
const data: dnChartForm[] = []
data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" })
data?.push({ label: "친수용수", val: hydUswtr, fill: "black" })
data?.push({ label: "지하수충전", val: ugwtChr, fill: "yellow" })
data?.push({ label: "농업용수", val: farmUswtr, fill: "black" })
data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "yellow" })
data?.push({ label: "공업용수", val: indstUswtr, fill: "black" })
setDnOutUsage(data);
}
}, [rawData, year])
useEffect(() => {
const newChartConfig = dnOutUsage.reduce((config, element) => {
config[element.label] = {
label: element.label,
fill: element.fill
};
return config;
}, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig;
setDnOutChartConfig(newChartConfig);
}, [dnOutUsage]);
//월별 장내외 용수 총 실적 막대차트
useEffect(() => {
let wshwtr = 0;
let coolUswtr = 0;
let cleanUswtr = 0;
let drwtUswtr = 0;
let dltnUswtr = 0;
let ithlRswtr = 0;
let ithlEtcUswtr = 0;
let cleanToilUswtr = 0;
let resn = 0;
let lndwtr = 0;
let hydUswtr = 0;
let ugwtChr = 0;
let farmUswtr = 0;
let rvrKeepUswtr = 0;
let indstUswtr = 0;
let inUsageSum = 0;
let outUsageSum = 0;
let inUsageArr = [];
let outUsageArr = [];
if (rawData) {
const data: barChartForm[] = []
rawData.forEach((item) => {
item.prfList
.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => {
wshwtr = element.wshwtr; //세척수
coolUswtr = element.coolUswtr; //냉각수
cleanUswtr = element.cleanUswtr; //청소수
drwtUswtr = element.drwtUswtr; //식수대
dltnUswtr = element.dltnUswtr //희석용수
ithlRswtr = element.ithlRswtr //중수도
ithlEtcUswtr = element.ithlEtcUswtr //기타
cleanToilUswtr = element.cleanToilUswtr //청소화장실용수
resn = element.resn //세척살수용수
lndwtr = element.lndwtr; //조경용수
hydUswtr = element.hydUswtr; //친수용수
ugwtChr = element.ugwtChr; //지하수충전
farmUswtr = element.farmUswtr //농업용수
rvrKeepUswtr = element.rvrKeepUswtr //하천등유지용수
indstUswtr = element.indstUswtr //공업용수
inUsageSum = wshwtr + coolUswtr + cleanUswtr + drwtUswtr + dltnUswtr + ithlRswtr + ithlEtcUswtr + cleanToilUswtr + resn;
inUsageArr.push(inUsageSum)
outUsageSum = lndwtr + hydUswtr + ugwtChr + farmUswtr + rvrKeepUswtr + indstUswtr;
outUsageArr.push(outUsageSum)
const month = Number(element.ym.slice(4, 6))
data.push({ label: `${month}월`, "장내용수": inUsageSum, "장외용수": outUsageSum })
},
);
})
setBarData(data);
}
}, [rawData, year])
useEffect(() => {
const newChartConfig = barData.reduce((config, element) => {
config[element.label] = {
label: element.label,
};
return config;
}, {} as Record<string, { label: string }>) satisfies ChartConfig;
setBarChartConfig(newChartConfig);
}, [barData]);
//월별 장내 용수 실적 라인차트
useEffect(() => {
if (rawData) {
const wshwtrData: lineChartDataProps[] = []
const coolUswtrData: lineChartDataProps[] = []
const cleanUswtrData: lineChartDataProps[] = []
const drwtUswtrData: lineChartDataProps[] = []
const dltnUswtrData: lineChartDataProps[] = []
const ithlRswtrData: lineChartDataProps[] = []
const ithlEtcUswtrData: lineChartDataProps[] = []
const cleanToilUswtrData: lineChartDataProps[] = []
const resnData: lineChartDataProps[] = []
rawData.forEach((item) => {
item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => {
const month = Number(element.ym.slice(4, 6))
wshwtrData.push({ label: `${month}월`, val: element.wshwtr, color: "red" })
coolUswtrData.push({ label: `${month}월`, val: element.coolUswtr, color: "red" })
cleanUswtrData.push({ label: `${month}월`, val: element.cleanUswtr, color: "red" })
drwtUswtrData.push({ label: `${month}월`, val: element.drwtUswtr, color: "red" })
dltnUswtrData.push({ label: `${month}월`, val: element.dltnUswtr, color: "red" })
ithlRswtrData.push({ label: `${month}월`, val: element.ithlRswtr, color: "red" })
ithlEtcUswtrData.push({ label: `${month}월`, val: element.ithlEtcUswtr, color: "red" })
cleanToilUswtrData.push({ label: `${month}월`, val: element.cleanToilUswtr, color: "red" })
resnData.push({ label: `${month}월`, val: element.resn, color: "red" })
},
);
})
const rtndata = {
chartData1: wshwtrData,
chartData2: coolUswtrData,
chartData3: cleanUswtrData,
chartData4: drwtUswtrData,
chartData5: dltnUswtrData,
chartData6: ithlRswtrData,
chartData7: ithlEtcUswtrData,
chartData8: cleanToilUswtrData,
chartData9: resnData
}
setInLineData(rtndata)
}
}, [rawData, year])
useEffect(() => {
if (inLineData?.chartData1) {
const newChartConfig = {
chartData1: {
label: '세척수',
color: "red",
},
chartData2: {
label: '냉각수',
color: "orange",
},
chartData3: {
label: '청소수',
color: "yellow",
},
chartData4: {
label: '식수대',
color: "pink",
},
chartData5: {
label: '희석용수',
color: "purple",
},
chartData6: {
label: '중수도',
color: "green",
},
chartData7: {
label: '기타',
color: "blue",
},
chartData8: {
label: '청소화장실용수',
color: "magenta",
},
chartData9: {
label: '세척살수용수',
color: "skyblue",
},
} satisfies ChartConfig;
setLnInChartConfig(newChartConfig);
}
}, [inLineData]);
//월별 장외 용수 실적 라인차트
useEffect(() => {
if (rawData) {
const lndwtrData: lineChartDataProps[] = []
const hydUswtrData: lineChartDataProps[] = []
const ugwtChrData: lineChartDataProps[] = []
const farmUswtrData: lineChartDataProps[] = []
const rvrKeepUswtrData: lineChartDataProps[] = []
const indstUswtrData: lineChartDataProps[] = []
rawData.forEach((item) => {
item.prfList.filter((e) => e.ym.slice(0, 4) === year).forEach((element) => {
const month = Number(element.ym.slice(4, 6))
lndwtrData.push({ label: `${month}월`, val: element.lndwtr, color: "red" })
hydUswtrData.push({ label: `${month}월`, val: element.hydUswtr, color: "red" })
ugwtChrData.push({ label: `${month}월`, val: element.ugwtChr, color: "red" })
farmUswtrData.push({ label: `${month}월`, val: element.farmUswtr, color: "red" })
rvrKeepUswtrData.push({ label: `${month}월`, val: element.rvrKeepUswtr, color: "red" })
indstUswtrData.push({ label: `${month}월`, val: element.indstUswtr, color: "red" })
},
);
})
setOutLineData({
chartData1: lndwtrData,
chartData2: hydUswtrData,
chartData3: ugwtChrData,
chartData4: farmUswtrData,
chartData5: rvrKeepUswtrData,
chartData6: indstUswtrData,
})
}
}, [rawData, year])
useEffect(() => {
if (outLineData?.chartData1) {
const newChartConfig = {
chartData1: {
label: '조경용수',
color: "red",
},
chartData2: {
label: '친수용수',
color: "orange",
},
chartData3: {
label: '지하수충전',
color: "yellow",
},
chartData4: {
label: '농업용수',
color: "green",
},
chartData5: {
label: '하천등유지용수',
color: "blue",
},
chartData6: {
label: '공업용수',
color: "purple",
},
} satisfies ChartConfig;
setLnOutChartConfig(newChartConfig);
}
}, [outLineData]);
useEffect(() => {
if (!pbnstPrfmncSttn.isInit) {
pbnstPrfmncInit("1", "11");
}
}, [pbnstPrfmncSttn.isInit, pbnstPrfmncInit]);
useEffect(() => {
setbdstTable(prfmncRes);
}, [prfmncRes]);
return (
<>
<ContentsDiv>
<ListDiv>
<hr />
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">하수재이용실적 상세현황</h3>
<SelectBox
className="w-1/12 text-2xl mt-4 ml-2"
label="연도"
selectClass={""}
selectArray={selectYearList}
value={year}
onSelectValue={(val: string | number) => setYear(String(val))} />
<h1 className="mt-4 ml-2">장내·외 용도별 하수재이용실적 현황(계)</h1>
<div className="flex">
<div className="w-1/3">
<MainChart chartConfig={chartConfig} chartData={chartData} chartTitle={"장내·외 용수 총 실적"} chartForm={CHART_FORM.DN} />
</div>
<div className="w-1/3">
<MainChart chartConfig={dnInChartConfig} chartData={dnInUsage} chartTitle={"장내용수 실적"} chartForm={CHART_FORM.DN} />
</div>
<div className="w-1/3">
<MainChart chartConfig={dnOutChartConfig} chartData={dnOutUsage} chartTitle={"장외용수 실적"} chartForm={CHART_FORM.DN} />
</div>
</div>
<h1 className="">장내·외 월별 하수재이용실적 현황</h1>
<div className="flex">
<div className="w-1/3">
<MainChart chartConfig={barChartConfig} chartData={barData} chartTitle={"월별 장내·외 용수 총 실적"} chartForm={CHART_FORM.DOUBLEBAR} />
</div>
<div className="w-1/3">
<MainChart chartConfig={lnInChartConfig} chartData={inLineData} chartTitle={"월별 장내 용수 실적"} chartForm={CHART_FORM.LINE} />
</div>
<div className="w-1/3">
<MainChart chartConfig={lnOutChartConfig} chartData={outLineData} chartTitle={"월별 장외 용수 총 실적"} chartForm={CHART_FORM.LINE} />
</div>
</div>
{/* 하수재이용실적 현황 - 조건부 렌더링 */}
{isVisible && (
<>
<h1 className="">하수재이용실적 현황</h1>
<ListDiv className="col-span-8 pr-6 ">
<ScrollArea className="h-[60vh]">
<div className="card-header">
<h3 className="text-2xl font-medium text-label">
{"하수처리수재이용 실적(m3) 등록결과"}
</h3>
</div>
<UiTable
headName={undefined}
tableData={prfData || []}
headlist={monthHeadList}
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}>
</UiTable>
</ScrollArea>
</ListDiv>
</>
)}
</ListDiv>
</ContentsDiv>
<Toaster position="top-center" />
</>
)
}
-421
View File
@@ -1,421 +0,0 @@
"use client";
import { useWrStore } from "@/app/store";
import {
rainZod,
selectClass,
TEST_UUID,
type customRainBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { DatePicker, FormUi } from "@common/business_components";
import { Form, FormField, SelectBox } from "@common/business_components/ui";
import { Button, Input } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { useForm, useWatch, type UseFormReturn } from "react-hook-form";
import { z } from "zod";
import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg";
import {
formatCommaNumber,
handleCommaNumberChange,
} from "@/components/lib/func/commom";
import { formH1Class, formH2Class } from "@/components/lib/class/comClass";
import { Label } from "@common/business_components/ui/form/lib/label";
export default function RainPrfmncSttnPopup({
rainForm,
isModal,
}: {
rainForm: customRainBdst;
isModal: boolean;
}) {
const { code, rainBdstReg, rainBdstUpdate, rain } = useWrStore(
(state) => state
);
const { rainFcltCd } = code;
const defaultValues: z.infer<typeof rainZod> = rainZod.parse({});
const form = useForm<z.infer<typeof rainZod>>({
resolver: zodResolver(rainZod),
defaultValues: defaultValues,
});
const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn] = form.watch([
"reuseBuilding.0.grntchBdstCertYn",
"reuseBuilding.0.instlCstSprtYn",
"reuseBuilding.0.rainyObj.filtrTrtmfctYn",
]);
const cleanRainData = (raw: any): z.infer<typeof rainZod> => {
return {
...raw,
frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null),
archChgPrmsnDt: raw?.archChgPrmsnDt
? new Date(raw?.archChgPrmsnDt)
: null,
reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
...item,
instlCmptnDt: new Date(item?.instlCmptnDt),
operMngCd: item?.operMngCd ?? "", // null → ""
grntchBdstCertYr:
typeof item?.grntchBdstCertYr === "string"
? item?.grntchBdstCertYr
: "", // null → ""
rainObj: {
...item?.rainObj,
},
})),
};
};
useEffect(() => {
if (grntchBdstCertYn === "N") {
form.setValue("reuseBuilding.0.grntchBdstCertYr", "");
form.setValue("reuseBuilding.0.grntchBdstCertNo", "");
form.setValue("reuseBuilding.0.grntchBdstCertGrd", "");
} else if (instlCstSprtYn === "N") {
form.setValue("reuseBuilding.0.instlCstSprtAmt", 0);
} else if (filtrTrtmfctYn === "N") {
form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctCpct", 0);
form.setValue("reuseBuilding.0.rainyObj.filtrTrtmfctPrs", "");
}
}, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctYn]);
// form 값이 변경될 때마다 로그 출력
useEffect(() => {
const subscription = form.watch((value) => {
});
return () => subscription.unsubscribe();
}, [form]);
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
const onSubmit = (values: z.infer<typeof rainZod>) => {
if (isModal) {
rainBdstReg(values, "41");
} else {
rainBdstUpdate(values, "41");
}
};
useEffect(() => {
if (rainZod) form.reset(cleanRainData(rainForm));
}, [rainForm]);
return (
<div className="!mx-[1.6rem] !p-0r">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div>
<div className="grid grid-cols-12 flex items-center card-header">
<h1 className="text-2xl font-medium text-label col-span-10">
{isModal ? "건축물 운영정보" : "빗물이용시설 정보"}
</h1>
</div>
</div>
{isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>}
{isModal ? (
<h1 className="pl-3 text-xl col-span-10 mt-4">
빗물이용시설 정보{" "}
</h1>
) : (
<></>
)}
<h1 className={formH1Class}>
기본정보
</h1>
<div className="grid grid-cols-4 gap-2 mt-4">
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.instlCmptnDt"
render={({ field }) => (
<FormUi label="설치완료일">
<DatePicker
mode="single"
field={{
value:
field.value && !isNaN(new Date(field.value).getTime())
? new Date(field.value)
: new Date(), // Provide a default Date value
onChange: (date) => field.onChange(date),
}}
selectClass={"w-full"}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.instlCst"
render={({ field }) => (
<FormUi label="설치비">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="">
<h1 className={formH1Class}>
빗물이용시설 정보
</h1>
</div>
<div>
<h2 className={formH2Class}>집수면</h2>
</div>
<div className="grid grid-cols-10 gap-4 mt-4 ">
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.pntfColKnd"
render={({ field }) => (
<FormUi label="종류">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={rainFcltCd}
onSelectValue={field.onChange}
value={field.value ?? rainFcltCd[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.pntfColArea"
render={({ field }) => (
<FormUi label="면적(m³)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
/>
</FormUi>
)}
/>
</div>
</div>
<div>
<h2 className={formH2Class}>여과 등 처리시설</h2>
</div>
<div className="grid grid-cols-12 gap-2 mt-4">
<div className="col-span-4">
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.filtrTrtmfctYn"
render={({ field }) => (
<FormUi label="유무">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-4">
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.filtrTrtmfctCpct"
render={({ field }) => (
<FormUi label="용량(m³/일)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={filtrTrtmfctYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-4">
<FormField
control={form.control}
name="reuseBuilding.0.rainyObj.filtrTrtmfctPrs"
render={({ field }) => (
<FormUi label="처리공정">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={filtrTrtmfctYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
</div>
<div className=" my-2">
<h1 className={formH1Class}>
인센티브 정보
</h1>
</div>
<div>
<h2 className={formH2Class}>설치비 지원</h2>
</div>
<div className="grid grid-cols-10 gap-2 mt-4">
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.instlCstSprtYn"
render={({ field }) => (
<FormUi label="지원 여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-5">
<FormField
control={form.control}
name="reuseBuilding.0.instlCstSprtAmt"
render={({ field }) => (
<FormUi label="지원금액(원)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={instlCstSprtYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
</div>
<div>
<h2 className={formH2Class}>녹색건축물 인증</h2>
</div>
<div className="grid grid-cols-6 gap-2 mt-4">
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertYn"
render={({ field }) => (
<FormUi label="인증여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertYr"
render={({ field }) => (
<FormUi label="인증년도">
<Input
className={'w-full !text-xl'}
placeholder="2024"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={grntchBdstCertYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 ">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertNo"
render={({ field }) => (
<FormUi label="인증번호">
<Input
className={'w-full !text-xl'}
placeholder="ab1234678"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={grntchBdstCertYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertGrd"
render={({ field }) => (
<FormUi label="인증등급">
<Input
className={'w-full !text-xl'}
placeholder="A"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={grntchBdstCertYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
</div>
</form>
</Form>
</div>
);
}
-404
View File
@@ -1,404 +0,0 @@
"use client";
import {
DatePicker,
Form,
FormField,
FormUi,
SelectBox,
} from "@common/business_components/ui";
import { Button, Input } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useWrStore } from "@/app/store";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
rswtZod,
type customRswtBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { useEffect } from "react";
import BdstReg from "@/components/ui/form/fcltReg/bdstReg/bdstReg";
import {
formatCommaNumber,
handleCommaNumberChange,
} from "@/components/lib/func/commom";
import { formH1Class, formH2Class } from "@/components/lib/class/comClass";
import { Label } from "@common/business_components/ui/form/lib/label";
export default function RswtrPrfmncsSttnPopup({
rswtForm,
isModal,
}: {
rswtForm: customRswtBdst;
isModal: boolean;
}) {
const { rswt, code, rswtBdstUpdate, rswtBdstReg } = useWrStore(
(state) => state
);
const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({});
const form = useForm<z.infer<typeof rswtZod>>({
resolver: zodResolver(rswtZod),
defaultValues: defaultValues,
});
const [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs] = form.watch([
"reuseBuilding.0.grntchBdstCertYn",
"reuseBuilding.0.instlCstSprtYn",
"reuseBuilding.0.rswtrObj.filtrTrtmfctProcs",
]);
const onSubmit = (values: z.infer<typeof rswtZod>) => {
if (isModal) {
rswtBdstReg(values, "41");
} else {
rswtBdstUpdate(values, "41");
}
};
const cleanRswtData = (raw: any): z.infer<typeof rswtZod> => {
return {
...raw,
frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt || null),
archChgPrmsnDt: raw?.archChgPrmsnDt
? new Date(raw?.archChgPrmsnDt)
: null,
reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
...item,
instlCmptnDt: new Date(item?.instlCmptnDt),
operMngCd: item?.operMngCd ?? "", // null → ""
grntchBdstCertYr:
typeof item?.grntchBdstCertYr === "string"
? item?.grntchBdstCertYr
: "", // null → ""
rswtrObj: {
...item?.rswtrObj,
},
})),
};
};
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
useEffect(() => {
console.log("filtrTrtmfctProcs ", filtrTrtmfctProcs);
if (grntchBdstCertYn === "N") {
form.setValue("reuseBuilding.0.grntchBdstCertYr", "");
form.setValue("reuseBuilding.0.grntchBdstCertNo", "");
form.setValue("reuseBuilding.0.grntchBdstCertGrd", "");
} else if (instlCstSprtYn === "N") {
form.setValue("reuseBuilding.0.instlCstSprtAmt", 0);
}
}, [grntchBdstCertYn, instlCstSprtYn, filtrTrtmfctProcs]);
useEffect(() => {
if (rswtZod) form.reset(cleanRswtData(rswtForm));
}, [rswtForm]);
return (
<div className="!mx-[1.6rem] !p-0r">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<div className="grid grid-cols-12 flex items-center card-header">
<h1 className="text-2xl font-medium text-label col-span-10">
건축물 운영정보
</h1>
</div>
</div>
{isModal && rswtForm != undefined ? <BdstReg form={form} /> : <></>}
{isModal ? (
<h1 className="pl-3 text-xl col-span-10 mt-4 ">
중수도 시설 정보{" "}
</h1>
) : (
<></>
)}
<h1 className={formH1Class}>기본정보</h1>
<div className="grid grid-cols-4 gap-2 mt-4">
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.instlCmptnDt"
render={({ field }) => (
<FormUi label="설치완료일">
<DatePicker
mode="single"
field={{
value:
field.value && !isNaN(new Date(field.value).getTime())
? new Date(field.value)
: new Date(), // Provide a default Date value
onChange: (date) => field.onChange(date),
}}
selectClass={"w-full"}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.instlCst"
render={({ field }) => (
<FormUi label="설치비">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className="grid grid-cols-4 gap-2 mt-4">
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.wtrUsqty"
render={({ field }) => (
<FormUi label="물사용량(m³)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-2">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.oblgTrgtWtrUsqty"
render={({ field }) => (
<FormUi label="의무대상 물사용량(m³)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className=" my-4">
<h1 className={formH1Class}>중수도 시설 정보</h1>
</div>
<div className="grid grid-cols-12 gap-1 mt-4">
<div className="col-span-4">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.filtrTrtmfctCpct"
render={({ field }) => (
<FormUi label="처리시설 용량">
<Input
className={'w-full !text-xl'}
placeholder="0"
type="number"
value={field.value ?? ""}
onChange={(e)=>{field.onChange(Number(e.target.value))} }
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-4">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.orgwtKndCd"
render={({ field }) => (
<FormUi label="원수 종류">
<SelectBox
className={""}
label={""}
selectClass={selectClass}
selectArray={code.orgwtKndCd}
onSelectValue={field.onChange}
value={field.value ?? code.orgwtKndCd[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-4">
<FormField
control={form.control}
name="reuseBuilding.0.rswtrObj.filtrTrtmfctProcs"
render={({ field }) => (
<FormUi label="주요처리공정">
<Input
className={'w-full !text-xl'}
placeholder="주요처리공정"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
<div className=" my-2">
<h1 className={formH1Class}>인센티브 정보</h1>
</div>
<div>
<h2 className={formH2Class}>설치비 지원</h2>
</div>
<div className="grid grid-cols-2 gap-2 mt-4">
<div className="col-span-1">
<FormField
control={form.control}
name="reuseBuilding.0.instlCstSprtYn"
render={({ field }) => (
<FormUi label="설치비 지원여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-1">
<FormField
control={form.control}
name="reuseBuilding.0.instlCstSprtAmt"
render={({ field }) => (
<FormUi label="지원금액(원)">
<Input
className={'w-full !text-xl'}
placeholder="1,000,000"
type="text"
onChange={(e) => {
handleCommaNumberChange(e, field.onChange);
}}
value={formatCommaNumber(field.value)}
readOnly={instlCstSprtYn !== "Y"}
/>
</FormUi>
)}
/>
</div>
</div>
<div>
<h2 className={formH2Class}>녹색건축물 인증</h2>
</div>
<div className="grid grid-cols-6 gap-2 mt-4">
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertYn"
render={({ field }) => (
<FormUi label="인증여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertYr"
render={({ field }) => (
<FormUi label="인증년도">
<Input
className={'w-full !text-xl'}
placeholder="2024"
type="text"
{...field}
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertNo"
render={({ field }) => (
<FormUi label="인증번호">
<Input
className={'w-full !text-xl'}
placeholder="ab1234678"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3">
<FormField
control={form.control}
name="reuseBuilding.0.grntchBdstCertGrd"
render={({ field }) => (
<FormUi label="인증등급">
<Input
className={'w-full !text-xl'}
placeholder="A"
type=""
value={field.value ?? ""}
onChange={field.onChange}
readOnly={true}
/>
</FormUi>
)}
/>
</div>
</div>
</form>
</Form>
</div>
);
}
+10 -13
View File
@@ -1,13 +1,13 @@
"use client";
import { useWrStore } from "@/app/store";
import { usageProcData } from "@/app/store/matDmd/coMatRvw/headList";
import {
DmdCoReqSchema,
type DedMatUpdateType,
type DmdCoReqType,
type DmdMatTableType,
} from "@/app/store/matDmd/coMatRvw/type";
import { formH1Class, formTableName } from "@/components/lib/class/comClass";
import { formH1Class } from "@/components/lib/class/comClass";
import {
formatPhoneNumber,
getCity,
@@ -15,33 +15,30 @@ import {
tableData,
yearOptions,
} from "@/components/lib/func/commom";
import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
Form,
FormField,
FormUi,
ScrollArea,
SearchDiv,
SearchFormLeft,
SearchFormRight,
SearchInput,
SelectBox,
Title,
UiModal,
UiTable,
type SelectDataType,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Input, Label } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import moment from "moment";
import { useEffect, useRef, useState } from "react";
import { useForm, useWatch } from "react-hook-form";
import toast, { Toaster } from "react-hot-toast";
import { z } from "zod";
import moment from "moment";
import { usageProcData } from "@/app/store/matDmd/coMatRvw/headList";
import { zodResolver } from "@hookform/resolvers/zod";
import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
export default function CoMatRvw() {
const { code, coRvw, coMatRvwInit, coMatRvwSearch, coMatRvwInqua } =
@@ -119,7 +116,7 @@ export default function CoMatRvw() {
useEffect(() => {
if (coMatRvwRes&&coMatRvwRes.length > 0) {
const data = coMatRvwRes?.map((item, index) => {
const data = coMatRvwRes?.map((item) => {
let flag = "";
flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg ||undefined);
@@ -238,7 +235,7 @@ export default function CoMatRvw() {
<div className="flex flex-row space-x-2">
<Button
size={"sm"}
onClick={(e) => {
onClick={() => {
if (fromDate && toDate) {
const fromNum = Number(fromDate);
const toNum = Number(toDate);
@@ -277,12 +274,12 @@ export default function CoMatRvw() {
headlist={coRvwHeadList}
pageSize={20}
total={coMatRvwCount}
cellClick={(index: number | undefined, headId: string) => {
cellClick={(index: number | undefined) => {
if (index !== undefined && index >= 0) {
TableCellClick(index);
}
}}
onPageChange={() => {}}
onPageChange={(val) => {setPageNatiion(val)}}
></UiTable>
</ListDiv>
<hr />
@@ -5,7 +5,6 @@ import { ruseUtzType } from "@/app/store/matDmd/ruseCaseMng/headList";
import { excelDownload, getCity } from "@/components/lib/func/commom";
import RuseCaseMngExcel from "@/components/ui/modal/coMat/ruseCaseMng/ruseCaseMngExcelModal";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import {
ContentsDiv,
filePickedBlobArray,
@@ -22,7 +21,7 @@ import {
import ListDiv from "@common/business_components/ui/list_div";
import { Button } from "@common/components/ui";
import { useEffect, useState } from "react";
import { toast, Toaster } from "react-hot-toast";
import { Toaster } from "react-hot-toast";
export default function RuseCaseMng() {
const { code, ruseCaseMng, selectRuseCaseMng } = useWrStore((state) => state);
@@ -37,7 +36,7 @@ export default function RuseCaseMng() {
// 물재이용사례 조회
const searchRuseCaseMng = async (pageNo: number, pageSize: number) => {
const res = await selectRuseCaseMng(
await selectRuseCaseMng(
pageNo,
pageSize,
sidoCd ?? "",
@@ -237,11 +236,10 @@ export default function RuseCaseMng() {
<UiTable
headName={"물재이용사례 현황"}
tableData={ruseCaseMngList}
children={undefined}
headlist={ruseCaseMng.ruseHeadList}
pageSize={20}
total={count}
cellClick={(index: number | undefined, headId: string) => {}}
cellClick={() => {}}
onPageChange={(pageNo: number) => {
searchRuseCaseMng(pageNo, 10);
}}
+36 -54
View File
@@ -10,9 +10,9 @@ import {
formatPhoneNumber,
getCity,
getdmdMatFlag,
tableData,
yearOptions,
} from "@/components/lib/func/commom";
import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
@@ -26,15 +26,12 @@ import {
type SelectDataType,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, DatePicker, Input, Label } from "@common/components/ui";
import { Button, Label } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import moment from "moment";
import { useCallback, useEffect, useState } from "react";
import { set, useFieldArray, useForm } from "react-hook-form";
import { z } from "zod";
import { tableData } from "@/components/lib/func/commom";
import { useForm } from "react-hook-form";
import toast, { Toaster } from "react-hot-toast";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
export default function RuseRvwHstry() {
const {
code,
@@ -44,7 +41,7 @@ export default function RuseRvwHstry() {
ruseRvwInqua,
ruseRvwComplete,
} = useWrStore((state) => state);
const { rvwHistRes, ruseHistHeadList,rvwHistCount } = ruseHist;
const { rvwHistRes, ruseHistHeadList, rvwHistCount } = ruseHist;
const [pageNation, setPageNatiion] = useState<number>(1);
const [dmdCoNm, setDmdCoNm] = useState<string>("");
@@ -70,18 +67,16 @@ export default function RuseRvwHstry() {
setObjSearch({ city: cityValue, sgg: "0" });
};
useEffect(() =>{
getButtonSearch()
},[pageNation])
useEffect(() => {
getButtonSearch();
}, [pageNation]);
const getButtonSearch=()=>{
const getButtonSearch = () => {
if (fromDate && toDate) {
const fromNum = Number(fromDate);
const toNum = Number(toDate);
if (fromNum > toNum) {
toast.error(
"시작년도가 종료년도 이후로 설정할 수 없습니다."
);
toast.error("시작년도가 종료년도 이후로 설정할 수 없습니다.");
} else {
let con: string | number = "";
if (String(objSearch.city).length > 0) {
@@ -90,16 +85,10 @@ export default function RuseRvwHstry() {
if (String(objSearch.sgg).length > 0 && objSearch.sgg !== "0") {
con = String(objSearch.sgg);
}
getSearch(
fromNum,
toNum,
con,
dmdCoNm,
ruseUtztnFcltNm
);
getSearch(fromNum, toNum, con, dmdCoNm, ruseUtztnFcltNm);
}
}
}
};
const getSgg = (val: string | number) => {
console.log(val);
setObjSearch({ ...objSearch, sgg: String(val) });
@@ -123,8 +112,6 @@ export default function RuseRvwHstry() {
ruseUtztnFcltNm
);
} else {
ruseRvwInqua(pageNation, 13, String(startYear), String(endYear), sggCd);
}
};
@@ -150,7 +137,7 @@ export default function RuseRvwHstry() {
const confrirmToast = () => {
const completeData = rvwHistData
?.map((item) => {
form.clearErrors;
form.clearErrors();
if (item?.completeYn) {
return Number(item.dmdInfoSn);
}
@@ -166,7 +153,7 @@ export default function RuseRvwHstry() {
<button
onClick={() => {
toast.dismiss(t.id);
ruseRvwComplete(completeData as Number[]);
ruseRvwComplete(completeData as number[]);
}}
>
확인
@@ -175,7 +162,7 @@ export default function RuseRvwHstry() {
</span>
));
} else {
ruseRvwComplete(completeData as Number[]);
ruseRvwComplete(completeData as number[]);
}
};
useEffect(() => {
@@ -191,33 +178,33 @@ export default function RuseRvwHstry() {
useEffect(() => {
if (rvwHistRes) {
const data = rvwHistRes?.map((item, index) => {
const data = rvwHistRes?.map((item) => {
let flag = "";
flag = getdmdMatFlag(item.demandMatching?.splyFcltFlg ?? "");
const formatDate = (dateStr: string | null | undefined) => {
// null, undefined, 빈 문자열인 경우 '없음'을 반환합니다.
if (!dateStr) return "없음";
// "YYYYMMDD" 형식으로 날짜를 파싱합니다.
const d = moment(dateStr, "YYYYMMDD");
// 파싱된 날짜가 유효한 경우에만 포맷하고, 그렇지 않으면 '없음'을 반환합니다.
return d.isValid() ? d.format("YYYY-MM-DD") : "없음";
};
flag = getdmdMatFlag(item.demandMatching?.splyFcltFlg ?? "");
const formatDate = (dateStr: string | null | undefined) => {
// null, undefined, 빈 문자열인 경우 '없음'을 반환합니다.
if (!dateStr) return "없음";
// "YYYYMMDD" 형식으로 날짜를 파싱합니다.
const d = moment(dateStr, "YYYYMMDD");
// 파싱된 날짜가 유효한 경우에만 포맷하고, 그렇지 않으면 '없음'을 반환합니다.
return d.isValid() ? d.format("YYYY-MM-DD") : "없음";
};
return {
...item,
ctpvCd: item.demandCo?.ctpvCd,
sggCd: item.demandCo?.sggCd,
dmdCoNm: item.demandCo?.dmdCoNm,
daddr: item.demandCo?.daddr,
telno: formatPhoneNumber(item.demandCo?.telno ||''),
telno: formatPhoneNumber(item.demandCo?.telno || ""),
dmndTmng: item?.dmndTmng
? moment(item?.dmndTmng).format("YYYY-MM-DD")
: "없음",
rvwCmptnYmd: formatDate(item.demandMatching?.rvwCmptnYmd),
mtchnCmptnYmd: formatDate(item.demandMatching?.mtchnCmptnYmd),
ruseUtztnFcltNm: item.ruseUtztnFcltNm,
rvwCmptnYmd: formatDate(item.demandMatching?.rvwCmptnYmd),
mtchnCmptnYmd: formatDate(item.demandMatching?.mtchnCmptnYmd),
ruseUtztnFcltNm: item.ruseUtztnFcltNm,
dmndQty: item.dmndQty,
splyFcltFlg: flag,
completeYn: false,
@@ -228,7 +215,6 @@ export default function RuseRvwHstry() {
}
}, [rvwHistRes]);
useEffect(() => {
console.log("변경여부 ", form.formState.isDirty);
}, [form.formState]);
@@ -308,8 +294,8 @@ export default function RuseRvwHstry() {
<div className="flex flex-row space-x-2">
<Button
size={"sm"}
onClick={(e) => {
getButtonSearch()
onClick={() => {
getButtonSearch();
}}
>
조회
@@ -333,16 +319,12 @@ export default function RuseRvwHstry() {
headlist={ruseHistHeadList}
pageSize={20}
total={rvwHistCount}
cellClick={(index: number | undefined, headId: string) => {
cellClick={(index: number | undefined) => {
TableCellClick(index);
}}
onPageChange={
(page)=>{
setPageNatiion(page)
}
}
onPageChange={(page) => {
setPageNatiion(page);
}}
></UiTable>
{/* <hr />
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">
+90 -58
View File
@@ -2,15 +2,15 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import { excelCoSttnParsing } from "@/app/store/matDmd/coSttn/excel";
import { fetchType, getFetch } from "@/components/lib/api";
import {
excelDownload,
formatPhoneNumber,
getCity,
tableData
tableData,
} from "@/components/lib/func/commom";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import {
ContentsDiv,
SearchDiv,
@@ -42,7 +42,6 @@ export default function CoSttn() {
updateDemandCompany,
coSttnTxtSearch,
demandCompList,
dmdIsSucees
} = useWrStore((state) => state);
const [bdstTable, setBdstTable] = useState<DemandCompType[]>();
@@ -60,17 +59,21 @@ export default function CoSttn() {
const [seartchTxt, setSearchTxt] = useState<string>();
const [upadateData, setUpdateData] = useState<DemandCompType>();
const getSelCity = useCallback((val: string | number) => {
const getSelCity = useCallback(
(val: string | number) => {
const cityValue = String(val);
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
// 시/도를 변경하면 시/군/구는 '전체'("0")로 초기화합니다.
setObjSearch({ city: cityValue, sgg: "0" });
}, [code.sggCd]);
},
[code.sggCd]
);
const getSgg = useCallback((val: string | number) => {
setObjSearch((prev) => ({ ...prev, sgg: String(val) }));
setPageNation(1);
}, []);
useEffect(() => {
@@ -83,7 +86,7 @@ export default function CoSttn() {
}
}
}, [code.cityCd, objSearch.city, getSelCity]);
useEffect(() => {
if (!coSttn.isInit) {
coSttnInit("1", "13", "0");
@@ -91,15 +94,13 @@ export default function CoSttn() {
}, [coSttn.isInit, coSttnInit]);
useEffect(() => {
if(coSttnRes){
if (coSttnRes) {
if (coSttnRes?.length > 0 && code.cityCd.length > 0) {
const data = tableData(coSttnRes, { code });
const chData = data.map((item: any) => ({
...item,
telno:formatPhoneNumber(item.telno||undefined),
regDt: moment(item.regDt).format("YYYY-MM-DD")
telno: formatPhoneNumber(item.telno || undefined),
regDt: moment(item.regDt).format("YYYY-MM-DD"),
}));
// .filter((item: any) => item !== undefined);
setBdstTable(chData);
@@ -112,41 +113,46 @@ export default function CoSttn() {
useEffect(() => {
if (coSttn.excelList.length > 0) {
if (coSttn.excelList.length === 0) return;
excelDownload(
const coExcel = excelCoSttnParsing(
coSttn.excelList,
code.cityCd,
code.sggCd
);
excelDownload(
coExcel as [],
"수요처 관리",
"sample_coSttn.xlsx",
"A1:F1",
"A1:H1",
2
);
}
}, [coSttn.excelList]);
useEffect(() => {
const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city ? objSearch.city : "0";
if(con){
coSttnSearch(String(pageNation), "13", String(con));
}
}, [coSttnSearch, objSearch.city, objSearch.sgg, pageNation]);
}, [coSttn.excelList, code]);
const excelClick = useCallback(() => {
const con = objSearch.sgg ? objSearch.sgg : objSearch.city;
const con =
objSearch.sgg && objSearch.sgg !== "0" ? objSearch.sgg : objSearch.city;
if (con) coSttnSearch("1", "10000", String(con));
}, [coSttnSearch, objSearch.city, objSearch.sgg]);
// }, [excelDownload, bdstTable]);
const searchClick = () => {
const con = (objSearch.sgg && objSearch.sgg !== "0") ? objSearch.sgg : objSearch.city;
const con =
objSearch.sgg && objSearch.sgg !== "0" ? objSearch.sgg : objSearch.city;
if (con) {
if (seartchTxt && seartchTxt?.length > 0) {
console.log(' seartchTxt ', seartchTxt)
coSttnTxtSearch("1", "13", String(con), seartchTxt ?? "");
coSttnTxtSearch(
String(pageNation),
"13",
String(con),
seartchTxt ?? ""
);
} else {
coSttnSearch("1", "13", String(con));
coSttnSearch(String(pageNation), "13", String(con));
}
}
};
return (
<>
<ContentsDiv>
@@ -161,7 +167,10 @@ export default function CoSttn() {
label="시도"
selectClass={""}
selectArray={code.cityCd || []}
onSelectValue={getSelCity}
onSelectValue={(val) => {
getSelCity(val);
setPageNation(1);
}}
value={objSearch.city}
/>
<SelectBox
@@ -191,7 +200,6 @@ export default function CoSttn() {
size={"sm"}
className={btnClass}
onClick={() => {
setUpdateData(undefined);
setIsDmdModal({ ...isDmdModal, isMoal: true });
}}
@@ -204,11 +212,12 @@ export default function CoSttn() {
onClick={() => {
/* 저장 로직 */
if (!upadateData) {
toast.error("수요처 변경을 원하는 행을 선택해주세요")
}else{
toast.error("수요처 변경을 원하는 행을 선택해주세요");
} else {
setIsDmdModal({
...isDmdModal,
isMoal: true})
isMoal: true,
});
}
}}
>
@@ -233,21 +242,30 @@ export default function CoSttn() {
headName={[]}
tableData={bdstTable || []}
headlist={coSttn.coSttHeadList}
pageSize={bdstTable?.length ? Math.ceil(bdstTable.length / 13) : 0}
total={ coSttnResCount || 0 }
cellClick={(index: number | undefined, headId: string) => {
pageSize={20}
total={coSttnResCount + 10 || 0}
cellClick={(index: number | undefined) => {
setUpdateData(coSttnRes[index as number]);
}}
onPageChange={setPageNation}
onPageChange={(page) => {
const con =
objSearch.sgg && objSearch.sgg !== "0"
? objSearch.sgg
: objSearch.city;
setPageNation(page);
coSttnSearch(String(page), "13", String(con));
}}
></UiTable>
</ListDiv>
</div>
</div>
<UiModal
bodyClass={"w-[40vw] max-w-none h-[90vh]"}
bodyClass={
"w-[40vw] max-w-none h-[80vh] " // +upadateData?.dmdInfoId?'h-[60vh]':'h-[90vh]'
}
open={isDmdModal.isMoal}
onOpenChange={() => {
setIsDmdModal({ isMoal: false, data: {} as DemandCompType });
setIsDmdModal({ isMoal: false, data: {} as DemandCompType });
}}
body={
<SdmInsertForm
@@ -257,24 +275,38 @@ export default function CoSttn() {
rtnValue={(searchText: string, pageCnt: number) => {
getDemandCompList(searchText, pageCnt);
}}
rtnInputData={ async(data) => {
if(upadateData?.dmdInfoPk){
updateDemandCompany(data as DemandCompType)
}else{
const dmd= await getFetch(fetchType.WR,`/reuseFc/request/${data.dmdInfoPk}`)
if(dmd) {
toast.error(`사업자번호 ${dmd.dmdInfoPk}는 이미 등록되었습니다. 다시등록해주세요`)
return
}
regDemandCompany(data as DemandCompType);
rtnInputData={async (data) => {
const con =
objSearch.sgg && objSearch.sgg !== "0"
? objSearch.sgg
: objSearch.city;
console.log("data ", data);
if (upadateData?.dmdInfoId) {
console.log("data ", data);
await updateDemandCompany(data as DemandCompType);
coSttnInit("1", "13", String(con));
setIsDmdModal({
isMoal: false,
data: data as DemandCompType,
});
} else {
const dmd = await getFetch(
fetchType.WR,
`/reuseFc/request/${data.dmdInfoId}`
);
if (dmd) {
toast.error(
`사업자번호 ${dmd.dmdInfoId}는 이미 등록되었습니다. 다시등록해주세요`
);
return;
}
await regDemandCompany(data as DemandCompType);
coSttnInit("1", "13", String(con));
setIsDmdModal({
isMoal: false,
data: data as DemandCompType,
});
}
if(dmdIsSucees ==='success'){
toast.success(`수요처 등록 및 수정 완료되었습니다..`)
setIsDmdModal({ isMoal: false, data: data as DemandCompType });
}else{
toast.error(`수요처 등록 및 수정 에러입니다.`)
}
}}
bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"}
updateList={upadateData}
+23 -23
View File
@@ -24,12 +24,12 @@ export default function DrgtSttn() {
const [excelData, setExcelData] = useState<any[]>();
const [drgtModal, setDrgtModal] = useState<{
isOpen: boolean;
data: customDrgt | undefined;
data: customDrgt[] | undefined;
}>({ data: undefined, isOpen: false });
const cellClick = (index: number | undefined, headId: string) => {
if (fromDate && toDate) {
drgtModalSearch(fromDate, toDate, drgtRes[index].sggNm);
const cellClick = (index: number) => {
if (fromDate && toDate && drgtRes[index]) {
drgtModalSearch(fromDate, toDate, drgtRes[index].sggNm ?? '');
} else {
toast.error("조회기간을 선택해주세요.");
}
@@ -151,12 +151,12 @@ export default function DrgtSttn() {
<div className="flex flex-row w-1/4">
<DateMonthPicker
field={{
value: fromDate,
onChange: (date: string) => {
const year = date.slice(0, 4);
let month = date.slice(4);
if (month.length < 2) {
month = month.padStart(2, "0");
value: fromDate ?? "",
onChange: (date: string | undefined) => {
const year = date ? date.slice(0, 4) : '';
let month = date?.slice(4);
if (month&&month?.length < 2) {
month = month?.padStart(2, "0");
}
const formatted = `${year}${month}`;
setFromDate(formatted);
@@ -167,12 +167,12 @@ export default function DrgtSttn() {
<span className="ml-2 text-center">~</span>
<DateMonthPicker
field={{
value: toDate,
onChange: (date: string) => {
const year = date.slice(0, 4);
let month = date.slice(4);
if (month.length < 2) {
month = month.padStart(2, "0");
value: toDate ?? "",
onChange: (date: string | undefined) => {
const year = date ? date.slice(0, 4) : '';
let month = date?.slice(4);
if (month&&month.length < 2) {
month = month?.padStart(2, "0");
}
const formatted = `${year}${month}`;
setToDate(formatted);
@@ -190,9 +190,9 @@ export default function DrgtSttn() {
<div className="flex flex-row space-x-2 items-center">
<Button
size={"sm"}
onClick={(e) => {
let sidoText = '';
let sggText = [];
onClick={() => {
let sidoText: string = '';
let sggText: string | string[] = '';
if (objSearch?.city.toString().length > 0) {
sidoText = code.cityCd.find((item) => item.val === objSearch?.city)?.text ?? '';
@@ -210,7 +210,7 @@ export default function DrgtSttn() {
sggText = sidoText;
}
const searchArr = [];
const searchArr:string[] = [];
if (sidoText) searchArr.push(sidoText);
if (Array.isArray(sggText)) {
searchArr.push(...sggText);
@@ -252,8 +252,8 @@ export default function DrgtSttn() {
headlist={drgtHeadListExport}
pageSize={14}
total={0}
cellClick={(index: number | undefined, headId: string) => {
cellClick(index ?? undefined, headId);
cellClick={(index: number | undefined) => {
cellClick(index ?? -1);
}}
onPageChange={() => { }}
></UiTable>
@@ -267,7 +267,7 @@ export default function DrgtSttn() {
setDrgtModal({ ...drgtModal, isOpen: !drgtModal.isOpen });
}}
bodyClass={"w-[50vw] max-w-none h-[80vh]"}
body={<DrgtDetailModal data={drgtModal.data} />}
body={<DrgtDetailModal data={drgtModal.data as customDrgt[]} />}
/>
<Toaster position="top-center" />
</ContentsDiv>
+63 -77
View File
@@ -3,11 +3,11 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import { type customLdrmnt } from "@/app/store/matDmd/ldrmntCoSttn";
import { ldrmntHeadListExport, ldrmntNodeListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList";
import { ldrmntHeadListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList";
import {
confirmToast,
excelDownload,
getCity,
getCityOrSgg,
tableData
} from "@/components/lib/func/commom";
import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcelModal";
@@ -24,60 +24,83 @@ import {
Title,
UiModal,
UiTable,
type ReturnType,
type SelectDataType
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
export default function LdrmntCoSttn() {
const { code, ldrmnt, ldrmntInit, ldrmntSearch, } = useWrStore(
const { code, ldrmnt, ldrmntInit, ldrmntSearch, ldrmntUpdate } = useWrStore(
(state) => state
);
const { ldrmntRes, excelList } = ldrmnt;
const { ldrmntRes, excelList, ldrmntResCount } = ldrmnt;
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 [bdstTable, setBdstTable] = useState<customLdrmnt[]>();
const [searchTxt, setSearchTxt] = useState<string>();
const ref = useRef<ReturnType>({} as ReturnType);
const [excelData, setExcelData] = useState<any[]>();
const [isExcelDownload, setIsExcelDownload] = useState(false);
const [resetPage, isResetPage] = useState(false);
const { t } = useTranslation('base');
// const [isExcelDownload, setIsExcelDownload] = useState(false);
const excelClick = useCallback(() => {
excelDownload(
[[]],
"잠재수요처 관리",
"잠재수요처 등록양식",
"sample_ldrmntCoSttn.xlsx",
"A1:AL1",
2
);
}, []);
const excelDownloadClick = () => {
ldrmntSearch(1, "10000", "0", "");
setIsExcelDownload(true);
}
const computeCityNm = () => {
let cityTxt = "";
let sggTxt = "";
if (objSearch.city) {
cityTxt =
code.cityCd.find((c) => c.val === objSearch.city)?.text || "";
}
if (objSearch.sgg) {
sggTxt =
code.sggCd.find((s) => s.val === objSearch.sgg)?.text || "";
}
if (cityTxt === "" || cityTxt === "전체") cityTxt = "0";
return sggTxt && sggTxt !== "0"
? `${cityTxt} ${sggTxt}`
: cityTxt;
};
const excelDownloadClick = useCallback(() => {
const cityNm = computeCityNm();
ldrmntSearch(true, 1, String(ldrmntResCount), cityNm, searchTxt || "");
// setIsExcelDownload(true);
}, [objSearch, searchTxt, code, ldrmntSearch, computeCityNm, ldrmntResCount]);
useEffect(() => {
if (isExcelDownload && excelData && excelData.length > 0) {
if (/*isExcelDownload &&*/ excelData && excelData.length > 0) {
downloadExcel({
data: excelData,
fileName: "잠재수요처 관리",
sheetNameArray: ["Sheet1"],
headerRange: "A1:F1"
});
setIsExcelDownload(false);
// setIsExcelDownload(false);
}
}, [excelData, isExcelDownload]);
}, [excelData, /*isExcelDownload*/]);
const [isExcelOpen, setIsExcelOpen] = useState<{
isModal: boolean;
}>({ isModal: false });
const cellClick = (index: number | undefined, headId: string) => {
const cellClick = (index: number | undefined) => {
if (index !== undefined) {
setDetailModal({ isOpen: true, data: ldrmntRes[index] });
}
@@ -92,7 +115,6 @@ export default function LdrmntCoSttn() {
} else {
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
const firstSggVal = data.find(item => item.val === "0")?.val || (data[0]?.val ?? "");
setObjSearch({ city: cityValue, sgg: firstSggVal });
}
@@ -141,33 +163,8 @@ export default function LdrmntCoSttn() {
}, [excelList])
useEffect(() => {
let cityTxt = ''
let sggTxt = ''
if (objSearch?.city.toString().length > 0) {
cityTxt = code.cityCd.find((item) => item.val === objSearch?.city)?.text ?? '';
}
if (objSearch?.sgg.toString().length > 1) {
sggTxt = code.sggCd.find((item) => item.val === objSearch?.sgg)?.text ?? '';
}
if (cityTxt === '전체' || cityTxt === '') {
cityTxt = '0'
}
let cityNm = ""
if (sggTxt !== "0") {
cityNm = cityTxt + " " + sggTxt
} else {
cityNm = cityTxt
}
if (cityNm) {
ldrmntSearch(pageNation, '20', cityNm, searchTxt || "");
} else {
ldrmntSearch(pageNation, '20', '0', searchTxt || "");
}
ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || "");
isResetPage(false)
}, [pageNation]);
return (
@@ -209,33 +206,9 @@ export default function LdrmntCoSttn() {
<div className="flex flex-row space-x-2 items-center">
<Button
size={"sm"}
onClick={(e) => {
let cityTxt = ''
let sggTxt = ''
if (objSearch?.city.toString().length > 0) {
cityTxt = code.cityCd.find((item) => item.val === objSearch?.city)?.text ?? '';
}
if (objSearch?.sgg.toString().length > 1) {
sggTxt = code.sggCd.find((item) => item.val === objSearch?.sgg)?.text ?? '';
}
if (cityTxt === '전체' || cityTxt === '') {
cityTxt = '0'
}
let cityNm = ""
if (sggTxt !== "0") {
cityNm = cityTxt + " " + sggTxt
} else {
cityNm = cityTxt
}
if (cityNm) {
ldrmntSearch(pageNation, '20', cityNm, searchTxt || "");
}
onClick={() => {
ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || "");
isResetPage(true)
}}
>
조회
@@ -273,13 +246,14 @@ export default function LdrmntCoSttn() {
<div className="overflow-x-auto">
<ListDiv className="min-w-max">
<UiTable
headName={[]}
headName={undefined}
tableData={bdstTable || []}
headlist={ldrmntHeadListExport}
pageSize={20}
total={10000}
cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }}
total={ldrmntResCount || 0}
cellClick={(index: number | undefined) => { cellClick(index ?? undefined) }}
onPageChange={setPageNation}
resetPageNo={resetPage}
/>
</ListDiv>
</div>
@@ -290,7 +264,18 @@ export default function LdrmntCoSttn() {
setDetailModal({ ...detailModal, isOpen: !detailModal.isOpen })
}}
bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"}
body={<CoDetailModal formObj={detailModal.data} />}
body={<CoDetailModal formObj={detailModal.data} onFormSubmit={async (value) => {
// confirmToast(t('isUpdateMsg'), await ldrmntUpdate(value))
// // await ldrmntUpdate(value)
// setDetailModal({ ...detailModal, isOpen: false })
// ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || "");
const handleConfirm = async () => {
await ldrmntUpdate(value);
setDetailModal({ ...detailModal, isOpen: false });
ldrmntSearch(false, pageNation, '20', computeCityNm(), searchTxt || "");
};
confirmToast(t('isUpdateMsg'), handleConfirm);
}} />}
/>
<UiModal
@@ -299,8 +284,9 @@ export default function LdrmntCoSttn() {
setIsExcelOpen({ isModal: !isExcelOpen.isModal })
}}
bodyClass={"w-[40vw] max-w-none"}
body={<CoRegExcel />}
body={<CoRegExcel isModal={(isOpen) => setIsExcelOpen({ isModal: isOpen })} />}
/>
<Toaster position="top-center"></Toaster>
</div>
@@ -1,6 +1,10 @@
"use client";
import { useWrStore } from "@/app/store";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import { tableData } from "@/components/lib/func/commom";
import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm";
import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
ScrollArea,
@@ -12,21 +16,14 @@ import {
UiModal,
UiTable,
} from "@common/business_components";
import { Button } from "@common/components";
import ListDiv from "@common/business_components/ui/list_div";
import { Button } from "@common/components";
import { useEffect, useState } from "react";
import { tableData } from "@/components/lib/func/commom";
import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm";
import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import { Toaster } from "react-hot-toast";
export default function Home() {
const { code, htdfl, initHtdflReg, getHtdflBdstData ,htdflNmSearch} = useWrStore(
(state) => state
);
const { code, htdfl, initHtdflReg, getHtdflBdstData, htdflNmSearch } =
useWrStore((state) => state);
const [searchTxt, setSearchTxt] = useState("");
const [pageNation, setPageNation] = useState(1);
@@ -34,42 +31,41 @@ export default function Home() {
const [bdstTable, setbdstTable] = useState<customHtdflBdst[]>();
const [issNewReg, setIsNewReg] = useState<boolean>(false);
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chgBuilding: chgBuilding[];
}>({ isOpen: false, chgBuilding: [] });
// const [bdstChgProps, setBdstChgProps] = useState<{
// isOpen: boolean;
// chgBuilding: chgBuilding[];
// }>({ isOpen: false, chgBuilding: [] });
const { htdflRes } = htdfl;
const { htdflRes ,htdflResCount} = htdfl;
useEffect(() => {
if (!htdfl.isInit) {
initHtdflReg('41')
initHtdflReg("0");
}
}, [htdfl.isInit, initHtdflReg]);
useEffect(() => {
if (htdflRes&&htdflRes.length>0) {
console.log('htdflRes ', htdflRes)
if (htdflRes && htdflRes.length > 0) {
const htdflData = tableData(htdflRes, { code }).map(
(item: customHtdflBdst) => {
let archArea = item?.archArea.split('.')[0]!=='-1'?item?.archArea.split('.')[0]:'확인불가'
const archArea =
item?.archArea.split(".")[0] !== "-1"
? item?.archArea.split(".")[0]
: "확인불가";
return {
...item,
archArea:archArea
archArea: archArea,
};
}
);
setbdstTable(htdflData);
}else{
} else {
setbdstTable([]);
}
}, [code, htdflRes]);
const cellClick: (val: number | undefined, headId: string) => void = (
val,
headId
val
) => {
if ((bdstTable ?? []).length > 0 && val !== undefined) {
{
@@ -78,7 +74,7 @@ export default function Home() {
}
// if (headId === "bdstChgYn" && val !== undefined) {
// if (
// htdflRes[val]?.bdstInfoPk != null &&
// htdflRes[val]?.bdstInfoSn != null &&
// htdflRes[val]?.chgBuilding?.length > 0
// ) {
// bdstChgModal(htdflRes[val]?.chgBuilding as chgBuilding[]);
@@ -89,7 +85,7 @@ export default function Home() {
// setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding });
// };
useEffect(() => {
getHtdflBdstData(pageNation, "41");
getHtdflBdstData(pageNation, "0");
}, [pageNation]);
return (
@@ -102,7 +98,7 @@ export default function Home() {
<SearchFormLeft>
<SearchInput
className="col-span-3 my-7 !text-3xl"
label="건물명"
label="시설명"
textValue={searchTxt || ""}
setText={(e) => {
setSearchTxt(e);
@@ -114,11 +110,10 @@ export default function Home() {
<Button
size={"sm"}
onClick={() => {
if(searchTxt&&searchTxt.length>0){
htdflNmSearch(String(41),searchTxt)
}else{
initHtdflReg(String(41) );
if (searchTxt && searchTxt.length > 0) {
htdflNmSearch(String(0), searchTxt);
} else {
initHtdflReg(String(0));
}
}}
>
@@ -139,9 +134,9 @@ export default function Home() {
<UiTable
tableData={bdstTable || []}
headlist={htdfl.upHeadList}
pageSize={100}
total={10}
headName={"건축물 목록"}
pageSize={20}
total={htdflResCount}
headName={"시설물 목록"}
cellClick={(val, headId) => {
cellClick(val || undefined, headId);
}}
@@ -175,17 +170,7 @@ export default function Home() {
}}
/>
<Toaster position="top-center" />
{/* <UiModal
bodyClass={""}
open={bdstChgProps.isOpen}
body={
<BdstChgModal chgBuilding={bdstChgProps.chgBuilding}></BdstChgModal>
}
onOpenChange={(open) => {
setBdstChgProps({ ...bdstChgProps, isOpen: open });
}}
/> */}
<Toaster position="top-center" />
</ContentsDiv>
</>
);
+113 -118
View File
@@ -14,7 +14,7 @@ import { useWrStore } from "../../../store";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components";
import { useCallback, useEffect, useState } from "react";
import ListDiv from "@common/business_components/ui/list_div";
import { tableData } from "@/components/lib/func/commom";
import { confirmToast, tableData } from "@/components/lib/func/commom";
import type {
customPbnst,
fcBizType,
@@ -24,7 +24,6 @@ import type {
import {
pbnstRegZod,
pbnstRegArrayZod,
fcBizSchema,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm";
@@ -34,10 +33,8 @@ import { writeRgtrAndMdfr } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg";
import { useFieldArray, useForm, type FieldErrors } from "react-hook-form"; // FieldErrors 타입 추가
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { createDefaultPbnstItem } from "./utilsZod";
import { useTranslation } from "react-i18next";
export default function PublicReuseFaciltyInsert() {
const {
@@ -50,12 +47,13 @@ export default function PublicReuseFaciltyInsert() {
pubHasuSearch,
pbnstRuseBizUpdate,
} = useWrStore((state) => state);
const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst;
const [currentTab, setCurrentTab] = useState<string>("mng");
const { t } = useTranslation("base");
const { pubFacHeadList, pbnstHasuResCount, pbnstHasuRes, pbnstRes } = pbnst;
const [, setCurrentTab] = useState<string>("mng");
const [isRuseReg, setIsRuseReg] = useState<{
isModal: boolean;
}>({ isModal: false });
const [resetPage, isResetPage] = useState(false);
const [indexMng, setIndexMng] = useState<number>(0);
const [indexBiz, setIndexBiz] = useState<number>(0);
const [searchTxt, setSearchTxt] = useState<string>();
@@ -89,18 +87,19 @@ export default function PublicReuseFaciltyInsert() {
}, [pbnst.isInit, pubHasuInit]);
const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => {
if (!isDirty) {
toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시
return;
} const data = writeRgtrAndMdfr(valuse.items);
}
const data = writeRgtrAndMdfr(valuse.items);
let bizs = [] as fcBizType[];
data.forEach((fclt) => {
bizs = [...bizs, ...fclt.fcBizs];
});
const pbnst = data.map((fclt) => {
return {
pbnstRuseFcltPk: fclt.pbnstRuseFcltPk,
pbnstRuseFcltId: fclt.pbnstRuseFcltId,
fcltCpct: fclt.fcltCpct,
ruseCpct: fclt.ruseCpct,
splyExtraCpct: fclt.splyExtraCpct,
@@ -110,63 +109,89 @@ export default function PublicReuseFaciltyInsert() {
fcOpers: fclt.fcOpers,
};
});
await pbnstRuseFcltUpdate(pbnst as customPbnst[])
await pbnstRuseBizUpdate(bizs);
const handleConfirm = async () => {
Promise.allSettled([
pbnstRuseFcltUpdate(pbnst as customPbnst[]),
pbnstRuseBizUpdate(bizs),
]).then(([resFclt, resBiz]) => {
const isFcltSuccess = resFclt.status === "fulfilled";
const isBizSuccess = resBiz.status === "fulfilled";
if (isFcltSuccess && isBizSuccess) {
toast.success("하수 재이용 시설 및 사업이 수정되었습니다. ");
// 메시지 표시, 페이지 이동 등
} else {
let message = "";
// ✅ 각각 어떤 항목이 실패했는지도 로그/알림 처리
if (!isFcltSuccess) {
message = "하수재이용 시설 ";
}
if (!isBizSuccess) {
message += "하수재이용 시설 사업 ";
}
toast.error(message + "오류 입니다 ");
pubHasuInit("1", "41");
}
});
};
confirmToast(t("isUpdatetMsg"), handleConfirm);
};
// 폼 유효성 검사 실패 시 호출될 함수
const onInvalid = (errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }>) => {
console.log("errors:", errors);
const onInvalid = (
errors: FieldErrors<{ items: z.infer<typeof pbnstRegZod>[] }>
) => {
const findAllErrors = (
errorObject: any,
path: (string | number)[] = []
): { message: string; path: (string | number)[] }[] => {
if (!errorObject) return [];
return Object.keys(errorObject).flatMap((key) => {
const value = errorObject[key];
const currentKey = !isNaN(parseInt(key)) ? parseInt(key) : key;
const newPath = [...path, currentKey];
if (value && typeof value === "object") {
if (value.message) {
return [{ message: value.message, path: newPath }];
}
return findAllErrors(value, newPath);
}
return [];
});
};
const errorList = findAllErrors(errors);
if (errorList.length > 0) {
errorList.forEach((errorInfo) => {
const { message, path } = errorInfo;
let prefix = "";
const itemsIndex = path.indexOf("items");
if (itemsIndex > -1 && path.length > itemsIndex + 1) {
const itemIdx = path[itemsIndex + 1] as number;
const facilityName = form.getValues(`items.${itemIdx}.ruseUtztnFcltNm`);
const facilityName = form.getValues(
`items.${itemIdx}.ruseUtztnFcltNm`
);
if (facilityName) {
prefix += `[${facilityName}] `;
}
const fcBizsIndex = path.indexOf("fcBizs");
if (fcBizsIndex > -1 && path.length > fcBizsIndex + 1) {
const bizIdx = path[fcBizsIndex + 1] as number;
const cycle = form.getValues(`items.${itemIdx}.fcBizs.${bizIdx}.cycl`);
const cycle = form.getValues(
`items.${itemIdx}.fcBizs.${bizIdx}.cycl`
);
if (cycle) {
prefix += `[${cycle}차수] `;
}
}
}
// 최종 오류 메시지 출력
toast.error(`${prefix}${message}`);
});
@@ -176,6 +201,10 @@ export default function PublicReuseFaciltyInsert() {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
useEffect(() => {
console.log("formState", items);
}, [items]);
useEffect(() => {
if (code.sggCd.length && pbnstHasuRes.length > 0) {
setbdstTable(tableData(pbnstHasuRes, { code }));
@@ -197,17 +226,6 @@ export default function PublicReuseFaciltyInsert() {
setCurrentTab(value);
};
useEffect(() => {
if (pbnst.pbnstRes && pbnst.pbnstRes?.length > 0) {
form.reset({ items: pbnst.pbnstRes });
} else {
form.reset({ items: [] });
}
}, [pbnst.pbnstRes]);
useEffect(() => {
if (indexMng) {
setIndexBiz(0);
@@ -215,56 +233,33 @@ export default function PublicReuseFaciltyInsert() {
}, [indexMng]);
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
if (pbnst.pbnstRes && pbnst.pbnstRes?.length > 0) {
form.reset({ items: pbnst.pbnstRes });
} else {
form.reset({ items: [] });
}
}, [pbnst.pbnstRes]);
const appendPbnstRuseFclt = useCallback(() => {
const selecTableRow = selectRow;
if (pbnstRes && pbnstRes.length > 0) {
const lastPbnst = pbnstRes[pbnstRes.length - 1];
if (lastPbnst && selecTableRow) {
// append(
// pbnstRegZod.parse({
// pbnstRuseFcltPk:
// String(selecTableRow.bscFctCd) + String(pbnstRes.length + 1),
// ruseUtztnFcltNm: null,
// fcBizs: [
// fcBizSchema.parse({
// pbnstRuseFcltFk:
// String(lastPbnst.pbnstRuseFcltPk) +
// String(pbnstRes.length + 1),
// cycl: 1,
// }),
// ] as fcBizType[],
// })
// );
append(createDefaultPbnstItem(selecTableRow, pbnstRes.length));
if (selectRow) {
// pbnstRes.length를 사용하여 새로운 항목의 인덱스를 결정
append(createDefaultPbnstItem(selectRow, pbnstRes.length));
setIsRuseReg({ isModal: true });
}
} else {
if (selecTableRow) {
append(
pbnstRegZod.parse({
pbnstRuseFcltPk: String(selecTableRow.bscFctCd) + "1",
ruseUtztnFcltNm: "",
regDt: null,
mdfcnDt: null,
fcBizs: [
fcBizSchema.parse({
pbnstRuseFcltFk: String(selecTableRow.bscFctCd) + "1",
cycl: 1,
}),
] as fcBizType[],
})
);
if (selectRow) {
// pbnstRes가 비어있으면 첫 항목이므로 인덱스 0
append(createDefaultPbnstItem(selectRow, 0));
setIsRuseReg({ isModal: true });
}
}
}, [pbnstRegZod, pbnstRes, append, selectRow, form]);
}, [pbnstRes, append, selectRow]);
useEffect(() => {
pubHasuInit(String(pageNation), "41");
isResetPage(false);
}, [pageNation, pubHasuInit]);
return (
@@ -287,10 +282,13 @@ export default function PublicReuseFaciltyInsert() {
<Button
className=""
size={"sm"}
onClick={(e) => {
searchTxt && searchTxt?.length > 0
? pubHasuSearch(String(pageNation), "41", searchTxt)
: pubHasuInit(String(pageNation), "41");
onClick={() => {
if (searchTxt && searchTxt?.length > 0) {
pubHasuSearch(String(pageNation), "41", searchTxt);
} else {
pubHasuInit(String(pageNation), "41");
}
isResetPage(true);
}}
>
조회
@@ -328,40 +326,39 @@ export default function PublicReuseFaciltyInsert() {
tableData={bdstTable || []}
headlist={pubFacHeadList}
pageSize={10}
total={100000}
headName={"공공 하수처리시설 등록"}
total={pbnstHasuResCount || 20}
headName={"공공 하수처리시설 목록"}
cellClick={cellClick}
onPageChange={setPageNation}
children={undefined}
resetPageNo={resetPage}
/>
</ScrollArea>
</ListDiv>
</div>
<ListDiv className="col-span-2 pr-6 ">
<ScrollArea className="h-[60vh]">
{formWatch && formWatch[0]?.pbnstRuseFcltPk ? (
<Tabs defaultValue="mng" onValueChange={handleTabChange}>
<TabsList className="">
<TabsTrigger className="!text-xl" value="mng">
시설정보
</TabsTrigger>
<TabsTrigger className="!text-xl" value="buse">
차수별정보
</TabsTrigger>
<Button
size={"sm"}
onClick={form.handleSubmit(onSubmit, onInvalid)}
className="!justify-end" // 저장 버튼 위치 조정
>
저장
</Button>
</TabsList>
{formWatch && formWatch[0]?.pbnstRuseFcltId ? (
<Tabs defaultValue="mng" onValueChange={handleTabChange}>
<TabsList className="">
<TabsTrigger className="!text-xl" value="mng">
시설정보
</TabsTrigger>
<TabsTrigger className="!text-xl" value="buse">
차수별정보
</TabsTrigger>
<Button
size={"sm"}
onClick={form.handleSubmit(onSubmit, onInvalid)}
className="!justify-end" // 저장 버튼 위치 조정
>
저장
</Button>
</TabsList>
<ScrollArea className="h-[60vh]">
<TabsContent className="max-h-full" value="mng">
<PbnstMngForm
formType="update"
form={form}
setIndexMng={(index: number) => {
console.log("setIndexMng", index);
setIndexMng(index);
}}
indexMng={indexMng}
@@ -378,17 +375,18 @@ export default function PublicReuseFaciltyInsert() {
indexBiz={indexBiz}
/>
</TabsContent>
</Tabs>
) : (
<>
</ScrollArea>
</Tabs>
) : (
<>
<div className="card-header text-2xl">
등록된 재이용시설 정보가 없습니다.
등록된 재이용시설 정보가 없습니다.
</div>
<div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 border rounded-md">
<p className="text-3xl mb-4">
신규등록 버튼을 클릭하여 재이용시설을 등록해주세요.
</p>
<Button
<div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 border rounded-md">
<p className="text-3xl mb-4">
신규등록 버튼을 클릭하여 재이용시설을 등록해주세요.
</p>
<Button
size={"sm"}
className=""
onClick={() => {
@@ -405,11 +403,9 @@ export default function PublicReuseFaciltyInsert() {
>
신규등록
</Button>
</div>
</>
)}
</ScrollArea>
</div>
</>
)}
</ListDiv>
<UiModal
body={
@@ -421,8 +417,7 @@ export default function PublicReuseFaciltyInsert() {
setIsRuseReg({ isModal: false });
}
}}
onInvalid ={onInvalid}
onInvalid={onInvalid}
></PbnstRegModal>
}
bodyClass="w-[68vw] max-w-none h-[90vh]"
@@ -1,37 +1,46 @@
import type { fcBizType, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import type { fcBizType, operType, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
export function createDefaultPbnstItem(
selecTableRow: pubHasuType,
index: number
) {
const pk = String(selecTableRow.bscFctCd) + String(index + 1);
export function createDefaultPbnstItem(row: pubHasuType, index: number) {
const pk = row.bscFctCd + String(index + 1);
return JSON.parse(JSON.stringify({
pbnstRuseFcltId: pk,
swtrmtFcltId: "",
ruseUtztnFcltNm: "",
fcltCpct: 0,
ruseCpct: 0,
splyExtraCpct: 0,
regDt: null,
rgtr: "",
mdfcnDt: null,
mdfr: "",
fcFiles: [],
fcBizs: [createDefaultBiz(pk, 1)],
fcOpers: [], // 빈 배열 강제
}));
}
export function createDefaultOper(pbnstRuseFcltId: string): operType {
return {
pbnstRuseFcltPk: pk,
swtrmtFcltFk: "",
ruseUtztnFcltNm: "", // 필수 입력이므로 빈 문자열로
fcltCpct: 0,
ruseCpct: 0,
splyExtraCpct: 0,
regDt: null,
rgtr: "test",
mdfcnDt: null,
mdfr: "test",
fcFiles: [],
fcBizs: [
createDefaultBiz(pk, 1), // 첫 차수
],
fcOpers: [],
};
pbnstRuseFcltId,
operMthd: "",
rprtvBzenty: "",
bgngDt: new Date(),
endDt: new Date(),
choose: false,
rgtr: "",
mdfr: "",
} as operType;
}
export function createDefaultBiz(
pbnstRuseFcltFk: string,
pbnstRuseFcltId: string,
cycl: number
): fcBizType {
return {
pbnstRuseFcltFk,
pbnstRuseFcltId,
cycl,
// 필요한 값 있으면 여기에 추가
} as fcBizType;
@@ -1,12 +1,10 @@
"use client";
import { useWrStore } from "@/app/store";
import {
type chgBuilding,
type customRainBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { tableData } from "@/components/lib/func/commom";
import RainRegForm from "@/components/ui/form/fcltReg/rainReg/rainRegForm";
import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal";
import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
@@ -29,16 +27,12 @@ export default function Home() {
return state;
}
);
const { rainRes } = rain;
const { rainRes, rainResCount } = rain;
const [rainForm, setRainForm] = useState<customRainBdst>();
const [issNewReg, setIsNewReg] = useState<boolean>(false);
const [pageNation, setPageNation] = useState(1);
const [bdstTable, setbdstTable] = useState<customRainBdst[]>();
const [searchTxt, setSearchTxt] = useState<string>();
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chgBuilding: chgBuilding[];
}>({ isOpen: false, chgBuilding: [] });
useEffect(() => {
setIsNewReg(false);
@@ -49,41 +43,34 @@ export default function Home() {
useEffect(() => {
if (code.sggCd.length > 0) {
const rainData = tableData(rainRes, { code }).map(
(item: customRainBdst) => {
let archArea = item?.archArea.split('.')[0]!=='-1'?item?.archArea.split('.')[0]:'확인불가'
return {
...item,
archArea:archArea,
bdstChgYn: item.chgBuilding.length > 0 ? "Y" : "N",
};
}
);
if (rainRes && rainRes.length > 0) {
const rainData = tableData(rainRes, { code }).map(
(item: customRainBdst) => {
const archArea =
item?.archArea.split(".")[0] !== "-1"
? item?.archArea.split(".")[0]
: "확인불가";
return {
...item,
archArea: archArea,
setbdstTable(rainData);
};
}
);
setbdstTable(rainData);
} else {
setbdstTable([]);
}
}
}, [code, rainRes]);
const cellClick: (val: number | undefined, headId: string) => void = (
val,
headId
const cellClick: (val: number | undefined) => void = (
val
) => {
if (val !== undefined) {
setRainForm(rainRes[val]);
}
if (headId === "bdstChgYn" && val !== undefined) {
if (
rainRes[val]?.bdstInfoPk != null &&
rainRes[val]?.chgBuilding.length > 0
) {
bdstChgModal(rainRes[val].chgBuilding);
}
}
};
const bdstChgModal = (chgBuilding: chgBuilding[]) => {
setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding });
};
useEffect(() => {
@@ -110,8 +97,9 @@ export default function Home() {
<Button
className=""
size={"sm"}
onClick={(e) => {
rainSearch(searchTxt || "", pageNation, "41");
onClick={() => {
rainSearch(searchTxt || "", 1, "41");
//rainSearch(searchTxt || "", pageNation, "41");
}}
>
조회
@@ -139,10 +127,10 @@ export default function Home() {
tableData={bdstTable || []}
headlist={rain.upHeadList}
pageSize={20}
total={10000}
total={rainResCount}
headName={"건축물 목록"}
cellClick={(val, headId) => {
cellClick(val, headId);
cellClick={(val) => {
cellClick(val);
}}
onPageChange={setPageNation}
></UiTable>
@@ -175,17 +163,6 @@ export default function Home() {
}}
/>
<UiModal
bodyClass={""}
open={bdstChgProps.isOpen}
body={
<BdstChgModal chgBuilding={bdstChgProps.chgBuilding}></BdstChgModal>
}
onOpenChange={(open) => {
setBdstChgProps({ ...bdstChgProps, isOpen: open });
}}
/>
<Toaster position="top-center" />
</ContentsDiv>
</>
@@ -1,10 +1,8 @@
"use client";
import { useWrStore } from "@/app/store";
import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { tableData } from "@/components/lib/func/commom";
import RswtrRegForm from "@/components/ui/form/fcltReg/rswtrReg/rswtrRegForm";
import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal";
import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import {
ContentsDiv,
@@ -32,59 +30,57 @@ export default function Home() {
const [pageNation, setPageNation] = useState(1);
const [selectVal, setSelect] = useState<number>();
const [bdstTable, setbdstTable] = useState<customRswtBdst[]>();
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chgBuilding: chgBuilding[];
}>({ isOpen: false, chgBuilding: [] });
const { rswtRes } = rswt;
const { rswtRes, rswtResCount } = rswt;
useEffect(() => {
if (!rswt.isInit) {
initRswt("41");
}
}, [rswt.isInit, initRswt]);
useEffect(() => {
if (code.sggCd.length > 0 && rswtRes?.length > 0) {
const rswtData = tableData(rswtRes, { code })?.map(
(item: customRswtBdst) => {
let archArea =
item?.archArea.split(".")[0] !== "-1"
? item?.archArea.split(".")[0]
: "확인불가";
return {
...item,
archArea: archArea,
bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N",
bdstUsgCd: item.reuseBuilding[0]?.bdstUsgCd,
};
}
);
setbdstTable(rswtData);
if (code.sggCd.length > 0) {
if (rswtRes?.length > 0) {
const rswtData = tableData(rswtRes, { code })?.map(
(item: customRswtBdst) => {
const archArea =
item?.archArea.split(".")[0] !== "-1"
? item?.archArea.split(".")[0]
: "확인불가";
return {
...item,
archArea: archArea,
bdstChgYn: item.chgBuilding[0]?.bdstChgNm != null ? "Y" : "N",
bdstUsgCd: item.reuseBuilding[0]?.bdstUsgCd,
};
}
);
setbdstTable(rswtData);
setRswtForm(rswtRes[selectVal ?? 0]);
} else {
setbdstTable([]);
setRswtForm({} as customRswtBdst);
}
}
// }, [code, rswtRes, selectVal]);
}, [code, rswtRes]);
useEffect(() => {
if (rswtRes && rswtRes.length > 0) {
setRswtForm(rswtRes[selectVal ?? 0]);
}
}, [code, rswtRes, selectVal]);
}, [rswtRes, selectVal]);
const cellClick: (val: number | undefined, headId: string) => void = (
val,
headId
val
) => {
if ((bdstTable ?? []).length > 0 && val !== undefined) {
{
setSelect(val);
setRswtForm(rswtRes[val]);
}
}
if (headId === "bdstChgYn" && val !== undefined) {
if (
rswtRes[val]?.bdstInfoPk != null &&
rswtRes[val]?.chgBuilding?.length > 0
) {
bdstChgModal(rswtRes[val].chgBuilding);
}
}
};
const bdstChgModal = (chgBuilding: chgBuilding[]) => {
setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding });
};
useEffect(() => {
getRswtBdstData(pageNation, "41");
}, [pageNation]);
@@ -111,7 +107,7 @@ export default function Home() {
<Button
size={"sm"}
className="mr-4 "
onClick={(e) => {
onClick={() => {
rswtBdstSearch(searchTxt || "", pageNation, "41");
}}
>
@@ -137,7 +133,7 @@ export default function Home() {
tableData={bdstTable || []}
headlist={rswt.upHeadList}
pageSize={20}
total={10000}
total={rswtResCount}
headName={"건축물 목록"}
cellClick={cellClick}
onPageChange={setPageNation}
@@ -170,16 +166,6 @@ export default function Home() {
setIsNewReg(open);
}}
/>
<UiModal
bodyClass={""}
open={bdstChgProps.isOpen}
body={
<BdstChgModal chgBuilding={bdstChgProps.chgBuilding}></BdstChgModal>
}
onOpenChange={(open) => {
setBdstChgProps({ ...bdstChgProps, isOpen: open });
}}
/>
<Toaster position="top-center" />
</ContentsDiv>
@@ -3,20 +3,18 @@
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type {
chgBuilding,
customRainBdst,
customRainBdst
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
excelDownload,
getCity,
getCityOrSgg,
tableData,
tableData
} from "@/components/lib/func/commom";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import {
ContentsDiv,
SearchBaseForm,
SearchDiv,
SearchFormLeft,
SearchFormRight,
@@ -25,26 +23,26 @@ import {
Title,
UiModal,
UiTable,
type ReturnType,
type SelectDataType,
type SelectDataType
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { Button, Label } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import { excelHtdflSttnParsing } from "@/app/store/ruseFcltMng/fcltSttn/htdflSttn/excel";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
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 { htdflSttnRes } = htdflSttn;
const ref = useRef<ReturnType>({} as ReturnType);
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
const isDownloadTriggered = useRef(false);
const { t } = useTranslation('base');
const [pageNation, setPageNation] = useState(1);
const [isChHead, setIsChHead] = useState(false);
const [resetPage, isResetPage] = useState(false);
const [bdstTable, setBdstTable] = useState<customRainBdst[]>();
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
@@ -52,20 +50,15 @@ export default function HtdflSttn() {
isOpen: boolean;
data: customRainBdst | undefined;
}>({ data: undefined, isOpen: false });
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chBuilding: chgBuilding[];
}>({ isOpen: false, chBuilding: [] });
// const [bdstChgProps, setBdstChgProps] = useState<{
// isOpen: boolean;
// chBuilding: chgBuilding[];
// }>({ isOpen: false, chBuilding: [] });
const [fcltNm, setFcltNm] = useState<string>("");
const excelClick = useCallback(() => {
// 최신 검색 조건 반영
const con = getConValue();
htdflSttnSearch(1, "10000", String(con), fcltNm, code.cityCd, code.sggCd);
}, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd]);
useEffect(() => {
htdflSttnSearch(pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
htdflSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
isResetPage(false)
}, [pageNation]);
const getSelCity = (val: string | number) => {
@@ -106,21 +99,32 @@ export default function HtdflSttn() {
setDetailModal({ isOpen: true, data: bdstTable[index] });
}
};
const excelClick = useCallback(() => {
isDownloadTriggered.current = true;
htdflSttnSearch(true, 1, String(htdflSttnResCount), String(getConValue()), fcltNm, code.cityCd, code.sggCd);
}, [htdflSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, htdflSttnResCount]);
useEffect(() => {
if (!isDownloadTriggered.current) {
return;
}
if (htdflSttn.excelList.length > 0) {
if (htdflSttn.excelList.length === 0) return;
excelDownload(
htdflSttn.excelList,
"온배수시설 현황",
"sample_htdflSttn.xlsx",
"A1:S3"
"A1:R3"
);
} else {
toast.error(t('excelDownErrMsg'));
}
isDownloadTriggered.current = false;
}, [htdflSttn.excelList, code]);
useEffect(() => {
if (!htdflSttn.isInit) {
initHtdfl(1, "20", "0", fcltNm, code.cityCd, code.sggCd);
initHtdfl(false, 1, "20", "0", fcltNm, code.cityCd, code.sggCd);
}
}, [htdflSttn.isInit, initHtdfl]);
@@ -181,8 +185,8 @@ export default function HtdflSttn() {
<Button
size={"sm"}
onClick={() => {
const con = getConValue();
htdflSttnSearch(pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd);
htdflSttnSearch(false, 1, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
isResetPage(true)
}}
>
조회
@@ -214,17 +218,17 @@ export default function HtdflSttn() {
<UiTable
headName={undefined}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
}
headlist={htdflSttn.htdflSttHeadList}
pageSize={20}
total={100000}
total={htdflSttnResCount || 0}
cellClick={(index: number | undefined, headId: string) => {
cellClick(index ?? undefined, headId);
}}
onPageChange={setPageNation}
></UiTable>
resetPageNo={resetPage}
>
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
</UiTable>
</ListDiv>
</div>
</div>
@@ -253,6 +257,7 @@ export default function HtdflSttn() {
body={<SttnDetailModal type={"HTB"} formObj={detailModal.data} />}
/>
</ContentsDiv>
<Toaster position="top-center" />
</>
);
}
@@ -18,7 +18,6 @@ import { useCallback, useEffect, useRef, useState } from "react";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { excelDownload, yearOptions } from "@/components/lib/func/commom";
import SearchInputText from "@/components/ui/searchInput/searchInput";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
@@ -29,9 +28,10 @@ export default function PbnstSttn() {
pbnstSttnSearch,
pbnSttnInit,
getPbnStnDetail,
pbnNmSearch,
getFlcts,
} = useWrStore((state) => state);
const { pbnstSttnRes, fclts, pbnstSttnResCount } = pbnstSttn;
const ref = useRef<ReturnType>({} as ReturnType);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
@@ -46,21 +46,25 @@ export default function PbnstSttn() {
const [pbnRuseNm, setPbnRuseNm] = useState<string>("");
const excelClick = useCallback(() => {
pbnstSttnSearch("1", "10000", ref.current, "", searchYear);
}, [pbnstSttnSearch, searchYear, ref.current]);
pbnstSttnSearch(
true,
String(1),
"100000",
ref.current,
pbnRuseNm,
searchYear,
fclts
);
}, [pbnstSttnSearch, fclts, pbnRuseNm]);
const cellCLick = useCallback(
(index: number | undefined) => {
if (
index !== undefined &&
pbnstSttn.pbnstSttnRes &&
pbnstSttn.pbnstSttnRes[index]
) {
const pbnstRuseFcltPk = pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk;
getPbnStnDetail(pbnstRuseFcltPk);
if (index !== undefined && pbnstSttnRes && pbnstSttnRes[index]) {
const pbnstRuseFcltId = pbnstSttnRes[index].pbnstRuseFcltId;
getPbnStnDetail(pbnstRuseFcltId);
}
},
[getPbnStnDetail, pbnstSttn.pbnstSttnRes]
[getPbnStnDetail, pbnstSttnRes]
);
useEffect(() => {
@@ -69,30 +73,30 @@ export default function PbnstSttn() {
pbnstSttn.excelList,
"하수재이용시설 현황",
"sample_pbnstSttn.xlsx",
"A1:U2"
"A1:U2",
3
);
}
}, [pbnstSttn.excelList]);
useEffect(() => {
if (!pbnstSttn.isInit) {
pbnSttnInit("1", "13", ref.current, searchYear);
getFlcts();
}
}, [pbnstSttn.isInit, pbnSttnInit, ref.current]);
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [pbnstSttn.pbnstSttnRes]);
// useEffect(() => {
// pbnstSttnSearch("1", "20", ref.current, pbnRuseNm, searchYear);
// }, [pageNation, ref.current, pbnRuseNm, searchYear, pbnstSttnSearch]);
// useEffect(() => {
// if (pbnRuseNm.length > 1)
// pbnNmSearch(String(pageNation), "23", ref.current, pbnRuseNm, searchYear);
// }, [pbnRuseNm,pageNation]);
if (pbnstSttnRes && pbnstSttnRes.length > 0) {
setBdstTable(pbnstSttnRes);
} else {
setBdstTable([]);
}
}, [pbnstSttnRes]);
useEffect(() => {
if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk)
pbnSttnInit("1", "15", ref.current, searchYear, pbnstSttn.fclts);
}, [fclts]);
useEffect(() => {
if (pbnstSttn.pbnstDetail.pbnstRuseFcltId)
setPbnDetaileData({
isModal: true,
data: pbnstSttn.pbnstDetail,
@@ -127,34 +131,44 @@ export default function PbnstSttn() {
}
leftChildren={
<div className="col-span-3 flex items-center">
<SelectBox
className="w-48 h-full text-2xl"
label="연도"
selectClass={"w-full "}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
<Label className="w-64 mt-2 mx-4 text-xl text-gray-600">
{"하수처리시설명 "}
</Label>
<SearchInput
className={"text-2xl w-full ㅍ"}
label=""
textValue={pbnRuseNm || ""}
setText={(e) => {
setPbnRuseNm(e || "");
}}
/>
</div>
<SelectBox
className="w-48 h-full text-2xl"
label="연도"
selectClass={"w-full "}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
<Label className="w-64 mt-2 mx-4 text-xl text-gray-600">
{"하수처리시설명 "}
</Label>
<SearchInput
className={"text-2xl w-full ㅍ"}
label=""
textValue={pbnRuseNm || ""}
setText={(e) => {
setPbnRuseNm(e || "");
}}
/>
</div>
}
queryClick={function (returnType: ReturnType): void {
pbnstSttnSearch("1", "20", returnType, pbnRuseNm, searchYear);
pbnstSttnSearch(
false,
"1",
"15",
returnType,
pbnRuseNm,
searchYear,
fclts
);
}}
excelClick={excelClick}
initClick={function (): void {}}
initClick={function (): void {
setPbnRuseNm("");
}}
btnClass={btnClass}
ref={ref}
isAdmin={false}
@@ -165,27 +179,28 @@ export default function PbnstSttn() {
<div className="col-span-6">
<ListDiv>
<UiTable
headName={[]}
headName={undefined}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
}
headlist={pbnstSttn.pbnstSttHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
pageSize={15}
total={pbnstSttnResCount}
cellClick={(index: number | undefined) => {
cellCLick(index);
}}
onPageChange={(page: number) => {
pbnstSttnSearch(
false,
String(page),
String(13),
String(15),
ref.current,
pbnRuseNm,
searchYear
searchYear,
fclts
);
}}
></UiTable>
>
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
</UiTable>
</ListDiv>
</div>
</div>
@@ -214,7 +229,9 @@ export default function PbnstSttn() {
bodyClass="w-[68vw] max-w-none h-[90vh]"
open={pbnDetaileData.isModal}
onOpenChange={(open) => {
setPbnDetaileData({ data: {} as customPbnst, isModal: false });
//TODO:OPEN 상태 확인필요
if(!open)
setPbnDetaileData({ data: {} as customPbnst, isModal: open });
}}
/>
</ContentsDiv>
@@ -1,17 +1,19 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type {
customRainBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
excelDownload,
getCity,
getCityOrSgg,
tableData,
} from "@/components/lib/func/commom";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import {
ContentsDiv,
SearchBaseForm,
SearchDiv,
SearchFormLeft,
SearchFormRight,
@@ -20,68 +22,61 @@ import {
Title,
UiModal,
UiTable,
type ReturnType,
type SelectDataType,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { Button, Label } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import type {
chgBuilding,
customRainBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
export default function RainSttn() {
const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
(state) => state
);
const { rainSttnRes } = rainSttn;
const ref = useRef<ReturnType>({} as ReturnType);
const { rainSttnRes, rainSttnResCount } = rainSttn;
const [pageNation, setPageNation] = useState(1);
const [isChHead, setIsChHead] = useState(false);
const [bdstTable, setBdstTable] = useState<customRainBdst[]>();
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false })
const [bdstChgProps, setBdstChgProps] = useState<{
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>();
const [resetPage, isResetPage] = useState(false);
const isDownloadTriggered = useRef(false);
const [objSearch, setObjSearch] = useState<objSearchType>({
sgg: "",
city: "",
});
const [detailModal, setDetailModal] = useState<{
isOpen: boolean;
chBuilding: chgBuilding[];
}>({ isOpen: false, chBuilding: [] });
data: customRainBdst | undefined;
}>({ data: undefined, isOpen: false });
const [fcltNm, setFcltNm] = useState<string>("");
const { t } = useTranslation("base");
const cellClick = (index: number | undefined, headId: string) => {
if (headId !== 'chBuildingYn' && index !== undefined && bdstTable !== undefined) {
setDetailModal({ isOpen: true, data: bdstTable[index] })
} else if (headId === 'chBuildingYn' && index !== undefined && bdstTable !== undefined) {
if (bdstTable[index] && bdstTable[index]?.chgBuilding[0]?.bdstChgNm !== null) {
setBdstChgProps({ isOpen: true, chBuilding: bdstTable[index].chgBuilding });
}
const cellClick = (index: number | undefined) => {
if (index !== undefined && bdstTable !== undefined) {
setDetailModal({ isOpen: true, data: bdstTable[index] });
}
};
const getSelCity = (val: string | number) => {
const cityValue = String(val);
if (cityValue === "0") {
setSelectSgg([]);
setObjSearch({ city: cityValue, sgg: "" });
} else {
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
const firstSggVal = data.find(item => item.val === "0")?.val || (data[0]?.val ?? "");
const firstSggVal =
data.find((item) => item.val === "0")?.val || (data[0]?.val ?? "");
setObjSearch({ city: cityValue, sgg: firstSggVal });
}
};
const getSgg = (val: string | number) => {
setObjSearch({ ...objSearch, sgg: String(val) })
setObjSearch({ ...objSearch, sgg: String(val) });
};
const getConValue = () => {
@@ -96,7 +91,7 @@ export default function RainSttn() {
useEffect(() => {
if (!rainSttn.isInit) {
rainSttnInit(1, "20", "0", fcltNm, code.cityCd, code.sggCd);
rainSttnInit(false, 1, "20", "0", fcltNm, code.cityCd, code.sggCd);
}
}, [rainSttn.isInit, rainSttnInit]);
@@ -108,50 +103,84 @@ export default function RainSttn() {
...item,
...item.reuseBuilding[0],
...item.reuseBuilding[0].rainyObj,
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst: item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
dtfcltCpct:
item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
instlCst:
item.reuseBuilding[0].instlCst === -1
? "확인불가"
: item.reuseBuilding[0].instlCst,
instlCstSprtAmt:
item.reuseBuilding[0].instlCstSprtAmt === -1
? "확인불가"
: item.reuseBuilding[0].instlCstSprtAmt,
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
pntfColArea:
item.reuseBuilding[0].rainyObj.pntfColArea === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.pntfColArea,
filtrTrtmfctCpct:
item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
? "확인불가"
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
archArea:
Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
};
})
.filter((item: any) => item.rainyObj !== undefined);
setBdstTable(chData);
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
}, [code, rainSttnRes]);
useEffect(() => {
rainSttnSearch(pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
rainSttnSearch(
false,
pageNation,
"20",
String(getConValue()),
fcltNm,
code.cityCd,
code.sggCd
);
isResetPage(false);
}, [pageNation]);
useEffect(() => {
if (!isDownloadTriggered.current) {
return;
}
if (rainSttn.excelList.length > 0) {
if (rainSttn.excelList.length === 0) return;
excelDownload(
rainSttn.excelList,
"빗물재이용시설 현황",
"sample_rainSttn.xlsx",
"A1:W3"
);
} else {
toast.error(t("excelDownErrMsg"));
}
isDownloadTriggered.current = false;
}, [rainSttn.excelList]);
const excelClick = useCallback(() => {
// 최신 검색 조건 반영
const con = getConValue();
rainSttnSearch(1, "10000", String(con), fcltNm, code.cityCd, code.sggCd);
}, [rainSttnSearch, objSearch, code.cityCd, code.sggCd]);
isDownloadTriggered.current = true;
rainSttnSearch(
true,
1,
String(rainSttnResCount),
String(getConValue()),
fcltNm,
code.cityCd,
code.sggCd
);
}, [
rainSttnSearch,
objSearch,
code.cityCd,
code.sggCd,
fcltNm,
rainSttnResCount,
]);
return (
<>
@@ -190,14 +219,21 @@ export default function RainSttn() {
</div>
</div>
</SearchFormLeft>
<SearchFormRight
className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<div className="flex flex-row space-x-2 items-center">
<Button
size={"sm"}
onClick={() => {
const con = getConValue();
rainSttnSearch(pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd);
rainSttnSearch(
false,
1,
"20",
String(getConValue()),
fcltNm,
code.cityCd,
code.sggCd
);
isResetPage(true);
}}
>
조회
@@ -229,15 +265,17 @@ export default function RainSttn() {
<UiTable
headName={undefined}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
}
headlist={rainSttn.rainSttHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }}
total={rainSttnResCount || 0}
cellClick={(index: number | undefined) => {
cellClick(index ?? undefined);
}}
onPageChange={setPageNation}
></UiTable>
resetPageNo={resetPage}
>
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
</UiTable>
</ListDiv>
</div>
</div>
@@ -265,17 +303,8 @@ export default function RainSttn() {
bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"}
body={<SttnDetailModal type={"RNB"} formObj={detailModal.data} />}
/>
<UiModal
bodyClass={""}
open={bdstChgProps.isOpen}
body={
<BdstChgModal chgBuilding={bdstChgProps.chBuilding}></BdstChgModal>
}
onOpenChange={(open) => {
setBdstChgProps({ ...bdstChgProps, isOpen: open });
}}
/>
</ContentsDiv>
<Toaster position="top-center" />
</>
);
}
@@ -1,21 +1,17 @@
"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import {
excelDownload,
getCity,
getCityOrSgg,
tableData,
tableData
} from "@/components/lib/func/commom";
import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import {
ContentsDiv,
SearchBaseForm,
SearchDiv,
SearchFormLeft,
SearchFormRight,
@@ -24,13 +20,14 @@ import {
Title,
UiModal,
UiTable,
type ReturnType,
type SelectDataType,
type SelectDataType
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import { Button, Label } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
export default function RswtSttn() {
const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
@@ -38,31 +35,21 @@ export default function RswtSttn() {
);
const [pageNation, setPageNation] = useState(1);
const { rswtSttnRes } = rswtSttn;
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
const [isChHead, setIsChHead] = useState(false);
const ref = useRef<ReturnType>({} as ReturnType);
const [resetPage, isResetPage] = useState(false);
const [bdstTable, setBdstTable] = useState<customRswtBdst[]>();
const isDownloadTriggered = useRef(false);
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false })
const [bdstChgProps, setBdstChgProps] = useState<{
isOpen: boolean;
chBuilding: chgBuilding[];
}>({ isOpen: false, chBuilding: [] });
const [fcltNm, setFcltNm] = useState<string>("");
const { t } = useTranslation('base');
const cellClick = (index: number | undefined) => {
const cellClick = (index: number | undefined, headId: string) => {
if (headId !== 'chBuildingYn' && index !== undefined && bdstTable !== undefined) {
if ( index !== undefined && bdstTable !== undefined) {
setDetailModal({ isOpen: true, data: bdstTable[index] })
} else if (headId === 'chBuildingYn' && index !== undefined && bdstTable !== undefined) {
if (
bdstTable[index] &&
bdstTable[index]?.chBuildingYn === 'Y'
) {
setBdstChgProps({ isOpen: true, chBuilding: bdstTable[index].chgBuilding });
}
}
}
}
const getSelCity = (val: string | number) => {
@@ -96,7 +83,7 @@ export default function RswtSttn() {
useEffect(() => {
if (!rswtSttn.isInit) {
rswtSttnInit(1, "20", "0", fcltNm, code.cityCd, code.sggCd);
rswtSttnInit(false, 1, "20", "0", fcltNm, code.cityCd, code.sggCd);
}
}, [rswtSttn.isInit, rswtSttnInit]);
@@ -111,7 +98,7 @@ export default function RswtSttn() {
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
archArea : item?.archArea.split('.')[0]!=='-1'?item?.archArea.split('.')[0]:'확인불가'
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
}
})
.filter(
@@ -123,25 +110,30 @@ export default function RswtSttn() {
}, [code, rswtSttnRes]);
useEffect(() => {
if (!isDownloadTriggered.current) {
return;
}
if (rswtSttn.excelList.length > 0) {
if (rswtSttn.excelList.length === 0) return;
excelDownload(
rswtSttn.excelList,
"중수도시설 현황",
"sample_rswtSttn.xlsx",
"A1:W3",
);
} else {
toast.error(t('excelDownErrMsg'));
}
isDownloadTriggered.current = false;
}, [rswtSttn.excelList]);
const excelClick = useCallback(() => {
// 최신 검색 조건 반영
const con = getConValue();
rswtSttnSearch(1, "10000", String(con), fcltNm, code.cityCd, code.sggCd);
}, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd]);
isDownloadTriggered.current = true;
rswtSttnSearch(true, 1, String(rswtSttnResCount), String(getConValue()), fcltNm, code.cityCd, code.sggCd);
}, [rswtSttnSearch, objSearch, code.cityCd, code.sggCd, fcltNm, rswtSttnResCount]);
useEffect(() => {
rswtSttnSearch(pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
rswtSttnSearch(false, pageNation, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
isResetPage(false)
}, [pageNation]);
return (
@@ -158,7 +150,9 @@ export default function RswtSttn() {
label="시도"
selectClass={""}
selectArray={code.cityCd}
onSelectValue={getSelCity}
onSelectValue={
getSelCity
}
/>
<SelectBox
className="col-span-2 w-1/6 h-full text-2xl ml-4"
@@ -166,7 +160,9 @@ export default function RswtSttn() {
selectClass={""}
selectArray={selectSgg || []}
value={objSearch.sgg} // value props 추가
onSelectValue={getSgg}
onSelectValue={
getSgg
}
/>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">
@@ -187,8 +183,8 @@ export default function RswtSttn() {
<Button
size={"sm"}
onClick={() => {
const con = getConValue();
rswtSttnSearch(pageNation, "20", String(con), fcltNm, code.cityCd, code.sggCd);
rswtSttnSearch(false, 1, "20", String(getConValue()), fcltNm, code.cityCd, code.sggCd);
isResetPage(true)
}}
>
조회
@@ -220,15 +216,15 @@ export default function RswtSttn() {
<UiTable
headName={undefined}
tableData={bdstTable || []}
children={
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
}
headlist={rswtSttn.rswtSttHeadList}
pageSize={20}
total={10000}
cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }}
total={rswtSttnResCount || 0}
cellClick={(index: number | undefined) => { cellClick(index ?? undefined) }}
onPageChange={setPageNation}
></UiTable>
resetPageNo={resetPage}
>
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
</UiTable>
</ListDiv>
</div>
</div>
@@ -257,17 +253,8 @@ export default function RswtSttn() {
body={<SttnDetailModal type={"RST"} formObj={detailModal.data} />}
/>
<UiModal
bodyClass={""}
open={bdstChgProps.isOpen}
body={
<BdstChgModal chgBuilding={bdstChgProps.chBuilding}></BdstChgModal>
}
onOpenChange={(open) => {
setBdstChgProps({ ...bdstChgProps, isOpen: open });
}}
/>
</ContentsDiv>
<Toaster position="top-center" />
</>
);
}
@@ -11,6 +11,7 @@ import {
type rswtrChkDetailsZodType,
} from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn";
import {
confirmToast,
excelArrayDownload,
excelDownload,
yearOptions,
@@ -39,6 +40,7 @@ import {
} from "@common/components/ui/tooltip";
import { useCallback, useEffect, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
export default function Page() {
const {
@@ -92,6 +94,7 @@ export default function Page() {
commonCd,
fcltNm
);
setRainPageNation(1);
} else {
rainChkInit(rainPageNation, rainPageSize, searchYear, commonCd);
}
@@ -104,6 +107,7 @@ export default function Page() {
commonCd,
fcltNm
);
setRswtPageNation(1);
} else {
rswtChkgdnInit(rswtPageNation, rswtPageSize, searchYear, commonCd);
}
@@ -199,25 +203,32 @@ export default function Page() {
}
}, [rainChkgdn.isSttn, rswtChkgdn.isSttn]);
const { t } = useTranslation('base');
const clickDelete = (data: number[], selFcltDiv: string) => {
if (data.length > 0) {
if (selFcltDiv === "RNB") {
rainChkDelete(data);
const handleConfirm = async () => {
rainChkDelete(data, searchYear);
};
confirmToast(t('isDeleteMsg'), handleConfirm);
} else {
rswtChkDelete(data);
const handleConfirm = async () => {
rswtChkDelete(data, searchYear);
};
confirmToast(t('isDeleteMsg'), handleConfirm);
}
}
};
const chkUpdateTable = (selFcltDiv: string) => {
if (selFcltDiv === "RNB") {
if (updateRainDetail && updateRainDetail.length > 0) {
rainChkDetilUpdate(updateRainDetail);
} else {
rainChkDetilUpdate(updateRainDetail, searchYear);
} else {
toast.error("수정을 원하는 행을 선택하고 저장버튼을 눌러주세요 ");
}
} else {
if (updateRswtDetail && updateRswtDetail.length > 0) {
rswtChkDetilsUpdate(updateRswtDetail);
rswtChkDetilsUpdate(updateRswtDetail, searchYear);
} else {
toast.error("수정을 원하는 행을 선택하고 저장버튼을 눌러주세요 ");
}
@@ -279,7 +290,7 @@ export default function Page() {
<div className="flex flex-row space-x-2">
<Button
size={"sm"}
onClick={(e) => {
onClick={() => {
cellClick();
}}
>
@@ -297,14 +308,14 @@ export default function Page() {
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
size={"sm"}
onClick={() => {
chkUpdateTable(selFcltDiv);
}}
>
저장
</Button>
<Button
size={"sm"}
onClick={() => {
chkUpdateTable(selFcltDiv);
}}
>
저장
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" sideOffset={5}>
<h2 className="text-xl">
@@ -314,7 +325,6 @@ export default function Page() {
</Tooltip>
</TooltipProvider>
<Button
size={"sm"}
onClick={() => {
@@ -343,7 +353,8 @@ export default function Page() {
rainChkData={rainChkgdn.rainChk}
pageNation={rainPageNation}
onPageChange={rainPageChange}
pageCount={rainChkgdn.rainChkCount} />
pageCount={rainChkgdn.rainChkCount}
/>
) : (
<RswtChkgdTable
detaiRswtlUpdate={setUpdateRSwtDetail}
@@ -380,6 +391,9 @@ export default function Page() {
<ChkgdExcel
type={selFcltDiv}
setIsRegExcel={setIsRegExcel}
setYearChange={(year) => {
setSearchYear(year);
}}
></ChkgdExcel>
}
/>
@@ -1,19 +1,28 @@
"use client";
import { useWrStore } from "@/app/store";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { excelDownload, yearOptions } from "@/components/lib/func/commom";
import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel";
import {
initValInUsage,
initValOutUsage,
subTotalObj,
totalObj,
type FcPrfType,
type PrfType,
} from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
import { confirmToast, excelDownload, yearOptions } from "@/components/lib/func/commom";
import { InputTableBody } from "@/components/lib/func/TableData";
import PbnPrfExcelModal from "@/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal";
import {
ContentsDiv,
Title,
ScrollArea,
SearchDiv,
SearchFormLeft,
SelectBox,
SearchInput,
SearchFormRight,
ScrollArea,
UiTable,
SearchInput,
SelectBox,
Title,
UiModal,
UiTable,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import {
@@ -23,27 +32,16 @@ import {
TableBody,
TableHeader,
} from "@common/components/ui";
import { useState, useEffect, useCallback } from "react";
import { set } from "react-hook-form";
import { useCallback, useEffect, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { headMakeprfmnc } from "../chkgdnReg/TableHead";
import { InputTableBody } from "@/components/lib/func/TableData";
import {
initValInUsage,
initValOutUsage,
subTotalObj,
totalObj,
type FcPrfType,
type PrfType,
} from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel";
import data from "@common/components/ui/icon-finder/data";
export default function prfmncPrfmncReg() {
const { code, prfmnc, prfmncHasuInit, prfmnRegData } = useWrStore(
export default function PrfmncPrfmncReg() {
const { prfmnc, prfmncHasuInit, prfmnRegData, prfmncHasuNmSearch } = useWrStore(
(state) => state
);
const { pbnstPrfmncHeadList, monthHeadList, prfmncRes } = prfmnc;
const { pbnstPrfmncHeadList, monthHeadList, prfmncRes, prfmncResCount } = prfmnc;
const [bdstTable, setbdstTable] = useState<FcPrfType[]>();
const [searchTxt, setSearchTxt] = useState<string>();
const [isExcelOpen, setIsExcelOPen] = useState<{
@@ -51,7 +49,7 @@ export default function prfmncPrfmncReg() {
data: FcPrfType;
}>({ isModal: false, data: {} as FcPrfType });
const [inputData, setInputData] = useState<any[]>();
const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState<string>();
const [pbnstRuseFcltId, setpbnstRuseFcltId] = useState<string>();
const [pageNation, setPageNation] = useState<number>(1);
const [cellNum, setCellNum] = useState<number>(1);
const [searchYear, setSearchYear] = useState<string>(
@@ -66,20 +64,40 @@ export default function prfmncPrfmncReg() {
"A1:O1"
);
}, [prfmnc.excelList]);
/*
const onSave = useCallback(
async() => {
if (pbnstRuseFcltId) {
await prfmnRegData(pageNation,'41',
excelToPbnPrfData(
inputData as unknown as JSON[],
searchYear,
pbnstRuseFcltId
) as unknown as PrfType
);
// cellClick(cellNum)
}
}, [inputData, searchYear, pbnstRuseFcltId, pageNation,cellNum]);*/
const onSave = useCallback(
async() => {
if (pbnstRuseFcltPk) {
await prfmnRegData(pageNation,'41',
const { t } = useTranslation('base');
const onSave = useCallback(() => {
const handleConfirm = async () => {
if (!pbnstRuseFcltId) return;
prfmnRegData(
pageNation,
'41',
excelToPbnPrfData(
inputData as unknown as JSON[],
searchYear,
pbnstRuseFcltPk
pbnstRuseFcltId
) as unknown as PrfType
,searchYear
);
// cellClick(cellNum)
}
}, [inputData, searchYear, pbnstRuseFcltPk, pageNation,cellNum]);
};
confirmToast(t('isUpdateMsg'), handleConfirm);
}, [inputData, searchYear, pbnstRuseFcltId, pageNation, cellNum]);
const cellClick = useCallback(
(index: number | undefined) => {
@@ -153,7 +171,7 @@ export default function prfmncPrfmncReg() {
(usageTotalObj as any)[key] = val;
}
const tableData = [...inUsageData, ...outUsageData, usageTotalObj];
setPbnstRuseFcltPk(prfmncRes[index].pbnstRuseFcltPk);
setpbnstRuseFcltId(prfmncRes[index].pbnstRuseFcltId);
setInputData(tableData);
} else {
setInputData([]);
@@ -165,11 +183,17 @@ export default function prfmncPrfmncReg() {
useEffect(() => {
if (!prfmnc.isInit) {
prfmncHasuInit(1, "41");
const year = new Date().getFullYear()
prfmncHasuInit(1, "41", String(year));
}
}, [prfmnc.isInit, prfmncHasuInit]);
useEffect(() => {
setbdstTable(prfmncRes);
if (prfmncRes && prfmncRes.length > 0) {
setbdstTable(prfmncRes);
}
// cellNum이 0일 경우(첫 번째 행)도 유효한 인덱스이므로 undefined 여부만 체크합니다.
if (cellNum !== undefined) {
@@ -217,7 +241,17 @@ export default function prfmncPrfmncReg() {
<SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<div className="space-y">
<div className="flex flex-row space-x-2">
<Button size={"sm"} onClick={(e) => {}}>
<Button size={"sm"} onClick={() => {
if (searchTxt && searchTxt?.length > 0) {
prfmncHasuNmSearch(1, '41', searchYear, searchTxt)
setPageNation(1)
} else {
prfmncHasuInit(1, '41', searchYear)
setPageNation(1)
}
}}>
조회
</Button>
<Button
@@ -260,14 +294,17 @@ export default function prfmncPrfmncReg() {
tableData={bdstTable || []}
headlist={pbnstPrfmncHeadList}
pageSize={10}
total={10000}
total={prfmncResCount}
headName={"하수재이용시설 목록"}
cellClick={(index: number | undefined, headId: string) => {
cellClick={(index: number | undefined) => {
cellClick(index);
setCellNum(index ?? 0);
}}
onPageChange={setPageNation}
children={undefined}
onPageChange={
(page) => {
prfmncHasuInit(page, "41", searchYear);
setPageNation(page)
}}
/>
</ScrollArea>
</ListDiv>
@@ -279,12 +316,11 @@ export default function prfmncPrfmncReg() {
{"하수처리수재이용 실적(m3) 등록결과"}
</h3>
</div>
<Table variant="secondary">
<TableHeader className="font-bold">
{headMakeprfmnc(monthHeadList, [])}
</TableHeader>
<TableBody key={prfmnc.pageKey+'pageKey'}>
<TableBody key={prfmnc.pageKey + 'pageKey'}>
{InputTableBody(inputData ?? [], monthHeadList, setInputData)}
</TableBody>
</Table>
@@ -299,15 +335,15 @@ export default function prfmncPrfmncReg() {
data={isExcelOpen.data}
setIsExcelOPen={(open) => {
setIsExcelOPen({ ...isExcelOpen, isModal: open })
}}
setModalExcelData={ async(excelData ) =>{
await prfmnRegData(pageNation,'41',
setModalExcelData={async (excelData) => {
await prfmnRegData(pageNation, '41',
excelData,
searchYear
);
// 데이터 저장 후 UI 업데이트는 useEffect가 감지하여 처리하므로 여기서는 호출하지 않습니다.
}
}
}
></PbnPrfExcelModal>
}
open={isExcelOpen.isModal}
@@ -23,11 +23,11 @@ import {
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Label } from "@common/components/ui";
import { useCallback, useEffect, useState } from "react";
import { Toaster } from "react-hot-toast";
import toast, { Toaster } from "react-hot-toast";
import { useTranslation } from "react-i18next";
export default function Page() {
const {
code,
rainChkSttn,
rswtChkSttn,
rainChkSttnInit,
@@ -97,7 +97,6 @@ export default function Page() {
useEffect(() => {
if (!rainChkSttn.isInit) {
isRainSttn(true)
console.log("여기", rainPageSize)
rainChkSttnInit(1, rainPageSize, new Date().getFullYear().toString(), commonCd);
setIsModal({ data: {}, open: false });
}
@@ -119,8 +118,13 @@ export default function Page() {
},
[isModal]
);
const { t } = useTranslation('base');
const excelDown = () => {
if (rainChkSttn.sttnExcelList && selFcltDiv === "RNB") {
if (!rainChkSttn.sttnExcelList || rainChkSttn.sttnExcelList.length === 0) {
toast.error(t('excelDownErrMsg'));
return;
}
excelDownload(
rainChkSttn.sttnExcelList,
"빗물이용시설 지도점검 현황",
@@ -129,6 +133,10 @@ export default function Page() {
3
);
} else if (rswtChkSttn.sttnExcelList && selFcltDiv === "RST") {
if (!rswtChkSttn.sttnExcelList || rswtChkSttn.sttnExcelList.length === 0) {
toast.error(t('excelDownErrMsg'));
return;
}
excelDownload(
rswtChkSttn.sttnExcelList,
"중수도시설 지도점검 현황",
@@ -191,13 +199,13 @@ export default function Page() {
<div className="flex flex-row space-x-2">
<Button
size={"sm"}
onClick={(e) => {
onClick={() => {
cellClick();
}}
>
조회
</Button>
<Button color="green" size={"sm"} onClick={(e) => { excelDown() }}>
<Button color="green" size={"sm"} onClick={() => { excelDown() }}>
다운로드
</Button>
</div>
@@ -6,20 +6,19 @@ import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType,
import { excelPrfmncSttnParsing } from "@/app/store/prfmncSttn/pbnstPrfmncSttn/excel";
import { excelDownload, yearOptions } from "@/components/lib/func/commom";
import SearchInputText from "@/components/ui/searchInput/searchInput";
import { CHART_FORM, ContentsDiv, MainChart, ScrollArea, SearchBaseForm, SearchInput, SelectBox, Title, UiTable, type ChartConfig, type ReturnType } from "@common/business_components";
import { CHART_FORM, ContentsDiv, MainChart, SearchBaseForm, SelectBox, Title, UiTable, type ChartConfig, type ReturnType } from "@common/business_components";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Label, Table, TableBody, TableHeader } from "@common/components/ui";
import { Label } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import toast, { Toaster } from "react-hot-toast";
import { headMakeprfmnc } from "../../prfmncReg/chkgdnReg/TableHead";
import { InputTableBody } from "@/components/lib/func/TableData";
import { useTranslation } from "react-i18next";
export default function PbnstPrfmncSttn() {
const {
code,
tableHeadMaker,
pbnstPrfmncSttn,
pbnstPrfmncInit,
// pbnstPrfmncInit,
pbnstPrfmncSearch,
prfmnc,
pbnstSttn,
@@ -27,20 +26,22 @@ export default function PbnstPrfmncSttn() {
} = useWrStore((state) => state);
const { monthHeadList } = prfmnc
const { pbnstPrfHeadList, prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn;
const [isChHead, setIsChHead] = useState(false);
// const [isChHead, setIsChHead] = useState(false);
const [fromDate, setFromDate] = useState<string>(String(new Date().getFullYear()));
const [toDate, setToDate] = useState<string>(String(new Date().getFullYear()));
const [year, setYear] = useState<string>(String(new Date().getFullYear()));
const [bdstTable, setbdstTable] = useState<FcPrfType[]>();
const ref = useRef<ReturnType>({} as ReturnType);
const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>();
// const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>();
const [pbnRuseNm, setPbnRuseNm] = useState<string>("");
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
const { t } = useTranslation('base');
const searchYear = String(new Date().getFullYear());
const [excelData, setExcelData] = useState<any[]>([]);
const excelClick = useCallback(() => {
if (!excelData || excelData.length === 0) {
toast.error(t('excelDownErrMsg'));
return;
}
excelDownload(
excelData,
"하수재이용실적 현황",
@@ -80,18 +81,18 @@ export default function PbnstPrfmncSttn() {
chartData8: lineChartDataProps[];
}>();
type dnChartForm = { label: string, val: number, fill?: string };
type dnChartForm = { label: string, val: number, color?: string };
type barChartForm = { label: string, "장내용수": number, "장외용수": number };
type lineChartDataProps = { label: string, val: number, color: string };
const prfTableData = (prfList: PrfType[], year: string) => {
const inUsageData = structuredClone(initValInUsage).map(row => ({
...row,
구분: "장내용수",
...row
// 구분: "장내용수",
}));
const outUsageData = structuredClone(initValOutUsage).map(row => ({
...row,
구분: "장외용수",
...row
// 구분: "장외용수",
}));
const inSubtotal = { ...structuredClone(subTotalObj), 구분: "장내용수" };
const outSubtotal = { ...structuredClone(subTotalObj), 구분: "장외용수" };
@@ -173,7 +174,7 @@ export default function PbnstPrfmncSttn() {
let inUsageSum = 0,
outUsageSum = 0;
let inUsageArr: number[] = [],
const inUsageArr: number[] = [],
outUsageArr: number[] = [];
// 라인차트용 데이터
@@ -206,10 +207,10 @@ export default function PbnstPrfmncSttn() {
rawData.forEach((item) => {
// 실적 테이블 데이터
if (chartId) {
if (item.prfList?.[0]?.ym.slice(0, 4) === year && item.prfList?.[0]?.pbnstRuseFcltFk === chartId) {
if (item.prfList?.[0]?.ym.slice(0, 4) === year && item.prfList?.[0]?.pbnstRuseFcltId === chartId) {
prfTableData(item.prfList, year);
}
item.prfList.filter((e) => e.ym.slice(0, 4) === year && e.pbnstRuseFcltFk === chartId).forEach((element) => {
item.prfList.filter((e) => e.ym.slice(0, 4) === year && e.pbnstRuseFcltId === chartId).forEach((element) => {
// 누적
wshwtr += element.wshwtr;
coolUswtr += element.coolUswtr;
@@ -284,27 +285,45 @@ export default function PbnstPrfmncSttn() {
})
// 도넛차트 데이터
dnData.push({ label: "장내용수", val: dnTotalIn, fill: "#8DD8FF" });
dnData.push({ label: "장외용수", val: dnTotalOut, fill: "#FFF085" });
dnData.push({ label: "장내용수", val: dnTotalIn, color: "#8DD8FF" });
dnData.push({ label: "장외용수", val: dnTotalOut, color: "#FFF085" });
// 장내용수 도넛
dnInData.push({ label: "세척수", val: wshwtr, fill: "#F7CFD8" });
dnInData.push({ label: "냉각수", val: coolUswtr, fill: "#F4F8D3" });
dnInData.push({ label: "청소수", val: cleanUswtr, fill: "#A6D6D6" });
dnInData.push({ label: "식수대", val: drwtUswtr, fill: "#8E7DBE" });
dnInData.push({ label: "희석용수", val: dltnUswtr, fill: "#FF8383" });
dnInData.push({ label: "중수도", val: ithlRswtr, fill: "#FFF574" });
dnInData.push({ label: "기타", val: ithlEtcUswtr, fill: "#A1D6CB" });
dnInData.push({ label: "세척수", val: wshwtr, color: "#F7CFD8" });
dnInData.push({ label: "냉각수", val: coolUswtr, color: "#F4F8D3" });
dnInData.push({ label: "청소수", val: cleanUswtr, color: "#A6D6D6" });
dnInData.push({ label: "식수대", val: drwtUswtr, color: "#8E7DBE" });
dnInData.push({ label: "희석용수", val: dltnUswtr, color: "#FF8383" });
dnInData.push({ label: "중수도", val: ithlRswtr, color: "#FFF574" });
dnInData.push({ label: "기타", val: ithlEtcUswtr, color: "#A1D6CB" });
// 장외용수 도넛
dnOutData.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "#A19AD3" });
dnOutData.push({ label: "세척살수용수", val: resn, fill: "#B1F0F7" });
dnOutData.push({ label: "조경용수", val: lndwtr, fill: "#81BFDA" });
dnOutData.push({ label: "친수용수", val: hydUswtr, fill: "#F5F0CD" });
dnOutData.push({ label: "지하수충전", val: ugwtChr, fill: "#FADA7A" });
dnOutData.push({ label: "농업용수", val: farmUswtr, fill: "#A6AEBF" });
dnOutData.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "#C5D3E8" });
dnOutData.push({ label: "공업용수", val: indstUswtr, fill: "#D0E8C5" });
dnOutData.push({ label: "청소화장실용수", val: cleanToilUswtr, color: "#A19AD3" });
dnOutData.push({ label: "세척살수용수", val: resn, color: "#B1F0F7" });
dnOutData.push({ label: "조경용수", val: lndwtr, color: "#81BFDA" });
dnOutData.push({ label: "친수용수", val: hydUswtr, color: "#F5F0CD" });
dnOutData.push({ label: "지하수충전", val: ugwtChr, color: "#FADA7A" });
dnOutData.push({ label: "농업용수", val: farmUswtr, color: "#A6AEBF" });
dnOutData.push({ label: "하천등유지용수", val: rvrKeepUswtr, color: "#C5D3E8" });
dnOutData.push({ label: "공업용수", val: indstUswtr, color: "#D0E8C5" });
// 라인차트 데이터 월별 오름차순 정렬
const sortFn = (a: { label: string }, b: { label: string }) => parseInt(a.label) - parseInt(b.label);
wshwtrData.sort(sortFn);
coolUswtrData.sort(sortFn);
cleanUswtrData.sort(sortFn);
drwtUswtrData.sort(sortFn);
dltnUswtrData.sort(sortFn);
ithlRswtrData.sort(sortFn);
ithlEtcUswtrData.sort(sortFn);
cleanToilUswtrData.sort(sortFn);
resnData.sort(sortFn);
lndwtrData.sort(sortFn);
hydUswtrData.sort(sortFn);
ugwtChrData.sort(sortFn);
farmUswtrData.sort(sortFn);
rvrKeepUswtrData.sort(sortFn);
indstUswtrData.sort(sortFn);
// 라인차트 데이터
setInLineData({
@@ -326,6 +345,7 @@ export default function PbnstPrfmncSttn() {
chartData7: rvrKeepUswtrData,
chartData8: indstUswtrData,
});
barData.sort((a, b) => parseInt(a.label) - parseInt(b.label));
setBarData(barData);
setChartData(dnData);
setDnInUsage(dnInData);
@@ -337,10 +357,10 @@ export default function PbnstPrfmncSttn() {
const newChartConfig = chartData.reduce((config, element) => {
config[element.label] = {
label: element.label,
fill: element.fill
color: element.color
};
return config;
}, {} as Record<string, { label: string; fill?: string }>) satisfies ChartConfig;
}, {} as Record<string, { label: string; color?: string }>) satisfies ChartConfig;
setChartConfig(newChartConfig);
}, [chartData]);
@@ -348,7 +368,7 @@ export default function PbnstPrfmncSttn() {
const newChartConfig = dnInUsage.reduce((config, element) => {
config[element.label] = {
label: element.label,
fill: element.fill
color: element.color ?? "gray"
};
return config;
}, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig;
@@ -359,7 +379,7 @@ export default function PbnstPrfmncSttn() {
const newChartConfig = dnOutUsage.reduce((config, element) => {
config[element.label] = {
label: element.label,
fill: element.fill
color: element.color ?? "gray"
};
return config;
}, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig;
@@ -471,20 +491,26 @@ export default function PbnstPrfmncSttn() {
}, []);
useEffect(() => {
setbdstTable(prfmncRes);
if (prfmncRes?.[0]?.pbnstRuseFcltPk) setChartId(prfmncRes[0].pbnstRuseFcltPk)
setbdstTable(prfmncRes.map((e, idx) => {
return ({
...e,
number: String(idx + 1)
})
}))
if (prfmncRes?.[0]?.pbnstRuseFcltId) setChartId(prfmncRes[0].pbnstRuseFcltId)
}, [prfmncRes]);
useEffect(() => {
if (pbnRuseNm.length > 1)
pbnNmSearch("1", "23", ref.current, pbnRuseNm, searchYear);
pbnNmSearch("1", "23", ref.current, pbnRuseNm, searchYear,[]);
}, [pbnRuseNm]);
const cellClick = (index: number | undefined, headId: string) => {
if (index !== undefined && headId !== undefined) {
setChartId(prfmncRes[index].pbnstRuseFcltPk)
setChartId(prfmncRes[index].pbnstRuseFcltId)
}
}
@@ -501,14 +527,7 @@ export default function PbnstPrfmncSttn() {
selectUnitWaterShedData={code.lgbsnCd}
selectMiddleRegionData={code.mdmbsnCd}
selectEnvPartData={code.lclgvrnmntCd}
rightChildren={<Button
className={btnClass}
onClick={() => {
setIsChHead(true);
}}
>
조회항목설정
</Button>}
rightChildren={undefined}
leftChildren={<div className="col-span-5">
<div className="flex flex-row">
<div className="flex flex-row items-center">
@@ -534,9 +553,9 @@ export default function PbnstPrfmncSttn() {
setValue={(searchNm?: string) => {
setPbnRuseNm(searchNm || "");
}}
setRtnData={function (rtnData: any[]): void {
// setbdstTable(rtnData);
}}
setRtnData={/*function (rtnData: any[]): void {setbdstTable(rtnData);}*/
()=>{}
}
searchList={pbnstSttn.pbnstSearchData || []}
></SearchInputText>
{/* <SelectBox
@@ -639,9 +658,7 @@ export default function PbnstPrfmncSttn() {
pageSize={0}
total={0}
cellClick={undefined}
onPageChange={function (page: number): void {
throw new Error("Function not implemented.");
}}>
onPageChange={()=>{}}>
</UiTable>
{/* <ListDiv className="col-span-8 pr-6 ">
-74
View File
@@ -1,74 +0,0 @@
'use client'
import { useWrStore } from "@/app/store";
import { yearOptions } from "@/components/lib/func/commom";
import { ContentsDiv, Title, SearchDiv, SearchFormLeft, SelectBox, 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";
export default function MatStat(){
const { code, matStat } = useWrStore((state) => {
return state;
});
const [pageNation, setPageNation] = useState(1);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
return(
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<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="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="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={matStat.matStatHeadList}
pageSize={20}
total={10000}
headName={"건축물 목록"}
cellClick={(val, headId) => {}}
onPageChange={setPageNation}
></UiTable>
{/* </ScrollArea> */}
</ListDiv>
</div>
</div>
</ContentsDiv>
</>
)
}
+2 -2
View File
@@ -29,7 +29,7 @@ export default function RainStat() {
useEffect(() => {
searchRainStatList(searchYear);
}, [code.cityCd, code.sggCd, searchRainStatList, searchYear])
}, [code.cityCd, code.sggCd, searchRainStatList])
const excelDetailDownLoad=() =>{
const sidoList = new Set<string>();
@@ -237,7 +237,7 @@ export default function RainStat() {
/>
</div>
<div className="flex flex-row space-x-2 items-center">
<Button className="" size={"sm"} onClick={() => { }}>
<Button className="" size={"sm"} onClick={()=>{searchRainStatList(searchYear);}}>
조회
</Button>
<Button className="" size={"sm"} onClick={() => excelClick()}>
+3 -3
View File
@@ -26,14 +26,14 @@ export default function RswtStat() {
useEffect(() => {
searchRswtStatList(searchYear)
}, [searchRswtStatList, searchYear])
}, [searchRswtStatList])
const excelClick = () => {
downloadExcel({
data: (excelData as unknown as JSON[]) ?? [],
fileName: "중수도재이용통계",
sheetNameArray: ["Sheet1"],
headerRange: "A1:O1"
headerRange: "A1:N1"
})
}
@@ -59,7 +59,7 @@ export default function RswtStat() {
return {
"시도": item.cityText,
"개소": item.ctpvCnt,
"건축연면적(m³)": item.archArea,
// "건축연면적(m³)": item.archArea,
"처리용량(m³)": item.filtrTrtmfctCpct,
"물사용량(m³/년)": item.wtrUsqty,
"중수도+대체수이용량(m³/년)": item.rswtAltSum,
@@ -1,5 +1,8 @@
import type { SelectDataType } from "@common/business_components";
export const numSize = 12;
export const txtSize = 20;
export const yn: SelectDataType[] = [
{ val: "Y", text: "Y" },
{ val: "N", text: "N" },
@@ -181,10 +184,26 @@ export const rswtPrscCdMthdCd = [
];
export const htdPowerMthdCd= [
{
val: "해당없음",
text: "해당없음",
},
{
val: "석탄화력발전",
text: "석탄화력발전",
},
{
val: "화력발전",
text: "화력발전",
},
{
val: "수력발전",
text: "수력발전",
},
{
val: "태양관발전",
text: "태양관발전",
},
];
//(공업용수/양식장/농업용수)
+7
View File
@@ -3,6 +3,10 @@ import type { EnvPartSelectDataType, SelectDataType } from "@common/business_com
import { bdstFilterYn, bdstGrntchClass, bdstIncenYn, bdstUsgCd, chBuCd, dmdUszCd, erctUswtrPrcsMeth, htdPowerMthdCd, htdUtztnUsgCd, orgwtKndCd, pplLenght, pplQulity, rainFcltCd, rswtPrscCdMthdCd, ruseBizMthdCd, ruseMngMtd, rusePrcsMthdCd, ruseSeCd, yn } from "./basicCode";
export const btnClass = "p-4 m-2 text-white rounded-sm text-lg font-medium "
const laeSecd = '41'
export const buildingType = {
RST:"RST",
RNB:"RNB",
@@ -167,6 +171,8 @@ export type comCodeState = {
rswtPrscCdMthdCd:SelectDataType[];
htdPowerMthdCd:SelectDataType[]
htdUtztnUsgCd:SelectDataType[]
userSiSggCd : string;
};
};
@@ -203,6 +209,7 @@ export const comCodeStateExport: comCodeState = {
rswtPrscCdMthdCd:rswtPrscCdMthdCd,
htdPowerMthdCd:htdPowerMthdCd,
htdUtztnUsgCd:htdUtztnUsgCd,
userSiSggCd:laeSecd,
},
};
+31 -16
View File
@@ -7,16 +7,15 @@ import {
import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import type { conCostFeeType, rateFeeType } from "./type";
import toast from "react-hot-toast";
export const comFcltStateExport: comFcltState = {
searchFclts: [] as pubHasuType[],
demandCompList: [],
dmdIsSucees: '',
checkDemand: {
index: 0,
dmdInfoPk: "",
dmdInfoFk: "",
dmdInfoId: "",
bzmnNo: "",
dmdCoNm: "",
daddr: "",
@@ -52,7 +51,6 @@ export type comFcltType = comFcltState & comFcltActions;
export type comFcltState = {
searchFclts: pubHasuType[];
demandCompList: DemandCompType[];
dmdIsSucees: string;
checkDemand: DemandCompType;
constCostRes:conCostFeeType[],
rateFeeRes:rateFeeType[],
@@ -110,19 +108,20 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
data,
fetchType.WR
);
let message = "";
if (response.status === 200) {
message = "success";
} else {
message = "fail";
toast.success('수요처가 등록되었습니다. ')
set((state: comFcltState) => {
return {
...state,
dmdIsSucees: "success"
}
});
}
set((state: comFcltState) => {
return state.dmdIsSucees = message;
});
} catch (err) {
console.log(err);
toast.error('수요처가 등록 오류입니다.. ')
}
},
updateDemandCompany: async (data: DemandCompType) => {
@@ -132,15 +131,21 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
let message = "";
if (response.status === 200) {
message = "success";
toast.success('수요처 정보가 변경되었습니다. ' )
} else {
message = "fail";
}
set((state: comFcltState) => {
return state.dmdIsSucees = message;
return {
...state,
dmdIsSucees: message
}
});
} catch (err) {
console.log(err);
toast.success('수요처 정보가 오류입니다. ' )
}
},
getRateFee: async (year: string) => {
@@ -149,7 +154,11 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
const rateFeeRes = await getFetch(fetchType.COMMON, url);
set((state: comFcltState) => {
return state.rateFeeRes = rateFeeRes;;
return {
...state,
rateFeeRes: rateFeeRes
}
});
} catch (e) {
console.log(" error ", e);
@@ -159,9 +168,15 @@ export const comFcltSearchAction: (set: any) => comFcltActions = (set: any) => {
const url = `/prcsFclt/CstRuse/${year}`;
const constCost = await getFetch(fetchType.COMMON, url);
set((state: comFcltState) => {
return state.constCostRes = constCost;;
return {
...state,
constCostRes: constCost
}
});
}catch (e) {
console.log('getConstCostFee ', e)
}
}
+1
View File
@@ -22,6 +22,7 @@ export type TableUpperProps = {
selectData ?:string; // type 이 seelct 일경우 selectarray 정하기 위해
row?:number;
mergeCell?:boolean // 셀을 합칠경우
maxLength?:number
readonly?:boolean
};
-185
View File
@@ -1,185 +0,0 @@
import { getFetch } from "@/components/lib/api";
export type wrMapType = wrMapState & wrMapActions;
export type wrMapState = {
wrMap: {
buildingSearchRes: any[]
} // 건물 검색 결과 데이터
};
type wrMapActions = {
buildingNmSearch: (
flg: string,
sigunCode: string,
searchNm: string | undefined
) => void;
buildingNmSearchMultiple: (
checkedLayers: string[],
sigunCode: string,
searchNm: string | undefined
) => void; // 여러 레이어 동시 검색 함수 추가
};
export const wrMapStateExport: wrMapState = {
wrMap: {
buildingSearchRes: []
}
};
// 레이어 타입과 플래그 매핑
const LAYER_FLAG_MAP: { [key: string]: string } = {
// '46': '???', // 하수처리시설
// '47': '???', // 하수재이용시설
'48': 'RNB', // 빗물이용시설
'49': 'RST', // 중수도시설
'50': 'HTB', // 온배수시설
};
const findBdst = async (flg: string, sggCd: string, searchTxt: string | undefined) => {
return await getFetch('wr', `/reuseFc/building/${flg}/${sggCd}` + (searchTxt ? `/${searchTxt}` : ''))
}
export const wrMapActionsExport: (set: any) => wrMapActions = (
set: any
) => {
return {
buildingNmSearch: async (
flg: string,
sigunCode: string,
searchNm: string | undefined
) => {
try {
// if (!searchNm || searchNm.length < 2) {
// set((state: wrMapState) => ({
// ...state,
// buildingSearchData: []
// }));
// return;
// }
console.log("건축물 코드, 시군구 코드, 검색어: ", flg, sigunCode, searchNm);
const response = await findBdst(flg, sigunCode, searchNm);
console.log("response: ", response);
// API 응답을 SearchInputText 형식으로 변환
const searchListFormatted = (response || []).map((building: any) => ({
searchNm: building.bdstNm,
searchPk: String(building.bdstInfoPk),
dmdCoNm: building.bdstNm,
layerType: flg,
...building
}));
// findBdst와 유사한 API 호출
// findBdst(flg, sigunCode || "", searchNm).then(() => {
// console.log("건물 검색 API 호출: ", sigunCode, searchNm, flg);
// // bdst.bdstBase를 SearchInputText 형식으로 변환
// const searchListFormatted = (state.bdst.bdstBase || []).map((building: any) => ({
// searchNm: building.bdstNm,
// searchPk: String(building.bdstInfoPk),
// dmdCoNm: building.bdstNm,
// layerType: flg,
// ...building
// }));
// set((state: any) => ({
// ...state,
// wrMap: {
// ...state.wrMap,
// buildingSearchData: searchListFormatted
// }
// }));
// });
set((state: wrMapState) => ({
...state,
wrMap: {
...state.wrMap,
buildingSearchRes: searchListFormatted
}
}));
} catch (error) {
console.error("건물 검색 중 오류:", error);
}
},
buildingNmSearchMultiple: async (
checkedLayers: string[],
sigunCode: string,
searchNm: string | undefined
) => {
try {
if (!searchNm || searchNm.length < 2) {
set((state: any) => ({
...state.wrMap,
buildingSearchData: []
}));
return;
}
// 체크된 레이어들에 대해 병렬로 API 호출
const searchPromises = checkedLayers
.filter(layer => LAYER_FLAG_MAP[layer]) // 매핑된 레이어만 필터링
.map(layer => {
const flg = LAYER_FLAG_MAP[layer];
return findBdst(flg, sigunCode, searchNm)
.then(response => {
console.log(`레이어 ${layer}(${flg}) API 응답:`, response);
const searchListFormatted = (state.bdst.bdstBase || []).map((building: any) => ({
searchNm: building.bdstNm,
searchPk: String(building.bdstInfoPk),
dmdCoNm: building.bdstNm,
layerType: flg,
...building
}));
return {
layerType: layer,
flg: flg,
data: bdstNames
};
})
.catch(error => {
console.error(`레이어 ${layer}(${flg}) 검색 중 오류:`, error);
return { layerType: layer, flg: flg, data: [] };
});
});
const results = await Promise.all(searchPromises);
console.log("다중 레이어 검색 결과:", results);
// 모든 결과를 하나의 배열로 합치기
const allSearchResults = results.reduce((acc, result) => {
const formatted = result.data.map((building: any) => ({
searchNm: building.bdstNm,
searchPk: String(building.bdstInfoPk),
dmdCoNm: building.bdstNm,
layerType: result.layerType,
flg: result.flg,
...building.originalData
}));
return [...acc, ...formatted];
}, [] as any[]);
console.log("최종 합쳐진 검색 결과:", {
totalCount: allSearchResults.length,
sampleData: allSearchResults.slice(0, 3)
});
set((state: any) => ({
...state.wrMap,
buildingSearchData: allSearchResults
}));
} catch (error) {
console.error("다중 레이어 검색 중 오류:", error);
set((state: any) => ({
...state,
buildingSearchData: []
}));
}
}
};
};
@@ -1,4 +1,4 @@
import type { CommonTableProps, TableUpperProps } from "../../common/type/header";
import type { CommonTableProps } from "../../common/type/header";
+4 -3
View File
@@ -1,13 +1,13 @@
import { fetchType, getFetchWithCount, putFectch } from "@/components/lib/api";
import toast from "react-hot-toast";
import type { CommonTableProps } from "../../common/type/header";
import {
constCostHeadListExport,
coRvwHeadListExport,
coRvwNodeListExport,
rateFeeHeadListExport,
} from "./headList";
import type { CommonTableProps } from "../../common/type/header";
import type { DedMatUpdateType, DmdCoReqType } from "./type";
import { fetchType, getFetch, getFetchWithCount, putFectch } from "@/components/lib/api";
import toast from "react-hot-toast";
const coRvwHeadList = coRvwHeadListExport;
const coRvwNodeList = coRvwNodeListExport;
@@ -139,6 +139,7 @@ export const coRvwActionsExport: (set: any) => coRvwActions = (set: any) => {
}
} catch (e) {
toast.error("매칭 검토 저장 오류입니다.");
console.error("coMatRvwUpdate error", e);
}
},
coMatRvwSearch: async (
+6 -6
View File
@@ -2,7 +2,7 @@ import { z } from "zod";
const DemandInfoSchema = z.object({
dmdInfoSn: z.number(),
dmdInfoFk: z.string().nullish(),
dmdInfoId: z.string().nullish(),
dmndTmng: z.coerce.date().nullish(),
dmndQty: z.number().nullish(),
wntUntprc: z.number().nullish(),
@@ -22,10 +22,10 @@ const DemandInfoSchema = z.object({
});
const DemandMatchingSchema = z.object({
dmdInfoFk: z.string().nullish(),
splyFcltFk: z.string().nullish(),
dmdInfoId: z.string().nullish(),
pbnstRuseFcltId: z.string().nullish(),
splyFcltFlg: z.string().nullish(),
pbnstRuseFcltBizFk: z.number().nullish(),
pbnstRuseFcltBizSn: z.number().nullish(),
splyBgngDay: z.coerce.date().nullish(),
splyEndDay: z.coerce.date().nullish(),
splyCpct: z.number().nullish(),
@@ -38,7 +38,7 @@ const DemandMatchingSchema = z.object({
});
const DemandCoSchema = z.object({
dmdInfoPk: z.string().nullish(),
dmdInfoId: z.string().nullish(),
dmdCoNm: z.string().nullish(),
ctpvCd: z.string().nullish(),
sggCd: z.string().nullish(),
@@ -70,7 +70,7 @@ export const DmdCoReqSchema = z.object({
cityText: z.string().nullish(),
sggText: z.string().nullish(),
dmdInfoSn: z.number().default(0),
dmdInfoFk: z.string().default(''),
dmdInfoId: z.string().default(''),
dmndTmng: z.coerce.date().nullish(),
dmndQty: z.number().nullish(), // null 또는 undefined 허용
blgcOxygDmndQnt: z.number().nullish(),
+8 -7
View File
@@ -1,16 +1,17 @@
import type { customCoSttnBdst } from ".";
import type { SelectDataType } from "@common/business_components/ui";
import moment from "moment";
export const excelCoSttnParsing = (data: customCoSttnBdst[]): string[][] => {
export const excelCoSttnParsing = (data: any[],sidoCode:SelectDataType[] , sggCode:SelectDataType[]): string[][] => {
const excelExportData: string[][] = [];
data.forEach((item) => {
excelExportData.push([
String(item.ctpvCd),
String(item.sggCd),
sidoCode.find((sido) => sido.val === item.ctpvCd.toString().trim() )?.text ?? "",
sggCode.find((sgg) => sgg.val === item.sggCd.toString().trim() )?.text ?? "",
item.dmdCoNm ?? "",
item.daddr ?? "",
String(item.dmdInfoPk ?? ""),
item.telno ?? ""
String(item.dmdInfoId ?? ""),
item.telno ?? "",
moment(item.regDt).format("YYYY-MM-DD") ?? ""
]);
});
return excelExportData;
+2 -2
View File
@@ -35,7 +35,7 @@ export const coSttHeadListExport: z.infer<typeof sttnHeadListType> = [
visible: true,
},
{
id: "dmdInfoPk",
id: "dmdInfoId",
title: "사업자번호",
visible: true,
},
@@ -85,7 +85,7 @@ export const coSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "dmdInfoPk",
id: "dmdInfoId",
title: "사업자번호",
visible: true,
row: 1,
+9 -8
View File
@@ -1,8 +1,7 @@
import type { CommonTableProps } from "@/app/store/common/type/header";
import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api";
import { coSttHeadListExport, coSttNodeListExport } from "./headList";
import { excelCoSttnParsing } from "./excel";
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import { coSttHeadListExport, coSttNodeListExport } from "./headList";
// 테이블 헤드 리스트
const coSttNodeList = coSttNodeListExport;
@@ -53,6 +52,8 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
`/reuseFc/request/${pageNo}/${pageCnt}/${con}`
);
console.log('coSttnRes ', coSttnRes)
set((state: coSttnState) => {
return {
...state,
@@ -75,14 +76,13 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
`/reuseFc/request/${pageNo}/${pageCnt}/${con}`
);
if (Number(pageCnt) >= 10000) {
const coExcel = excelCoSttnParsing(coSttnRes.data);
set((state: coSttnState) => {
return {
...state,
coSttn: {
...state.coSttn,
excelList: coExcel,
isInit: false,
excelList: coSttnRes.data,
//isInit: false,
},
};
});
@@ -104,7 +104,7 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
},
coSttnTxtSearch: async (pageNo:string, pageCnt:string, con: string, txt: string) => {
try {
const coSttnRes = await getFetch(
const coSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/request/${pageNo}/${pageCnt}/${con}/${txt}`)
set((state: coSttnState) => {
@@ -112,7 +112,8 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
...state,
coSttn: {
...state.coSttn,
coSttnRes: coSttnRes,
coSttnRes: coSttnRes.data,
coSttnResCount: coSttnRes.count,
isInit: false,
}}})
} catch (erTxt) {
+5 -6
View File
@@ -1,7 +1,7 @@
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import type { z } from "zod";
import type { CommonTableProps } from "../../common/type/header";
import { drgtHeadListExport, drgtZod } from "./headList";
import type { z } from "zod";
const drgtHeadList = drgtHeadListExport;
@@ -21,7 +21,7 @@ export type drgtState = {
type drgtActions = {
drgtInit: () => void
drgtSearch: (fromDate: string, toDate: string, sido: string[]) => void
drgtModalSearch: (fromDate: string, toDate: string, sgg: string) => void
drgtModalSearch: (fromDate: string, toDate: string, sgg?: string) => void
};
export type drgtType = drgtState & drgtActions;
@@ -57,11 +57,11 @@ console.log("sido",sido)
}, {});
const data = Object.values(statusMap);
const formatStatus = data.map((item) => {
const formatStatus = data.map((item: any) => {
const attention = item['관심'] || 0;
const caution = item['주의'] || 0;
return {
sggNm: item.sggNm,
sggNm: item['sggNm'],
normal: String(item['정상'] || 0),
caution: String(caution),
attention: String(attention),
@@ -99,7 +99,6 @@ export const drgtActionsExport: (set: any) => drgtActions = (
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const formatted = `${year}${month}`;
const fromDate = formatted;
const toDate = formatted;
//FIXME: 페이지 처음 로딩될때 데이터 보려고 6월로 박아놓음 이거 fromDate로 고치기
@@ -135,7 +134,7 @@ export const drgtActionsExport: (set: any) => drgtActions = (
console.log(e)
}
},
drgtModalSearch: async (fromDate: string, toDate: string, sgg: string) => {
drgtModalSearch: async (fromDate: string, toDate: string, sgg?: string) => {
try {
const drgtMoData = await getFetch(
fetchType.WR,
+41 -43
View File
@@ -1,55 +1,53 @@
import type { SelectDataType } from "@common/business_components/ui";
const selectSido = [
{ text: '서울', val: "1" },
{ text: "인천", val: "2" },
{ text: "부산", val: "3" },
];
{ text: "서울", val: "1" },
{ text: "인천", val: "2" },
{ text: "부산", val: "3" },
];
const selectSgg = [
{ text: '종로구', val: "1" },
{ text: "성북구", val: "2" },
{ text: "강남구", val: "3" },
];
const selectUsg = [
{ text: '민간', val: "1" },
{ text: "공공", val: "2" },
];
const selectYN= [
{ text: 'Y', val: "1" },
{ text: 'N', val: "2" },
];
{ text: "종로구", val: "1" },
{ text: "성북구", val: "2" },
{ text: "강남구", val: "3" },
];
const selectUsg = [
{ text: "민간", val: "1" },
{ text: "공공", val: "2" },
];
const selectYN = [
{ text: "Y", val: "1" },
{ text: "N", val: "2" },
];
export type matDmdState ={ dmd:{
export type matDmdState = {
dmd: {
isInit: boolean;
selectSido:SelectDataType[];
selectSgg:SelectDataType[];
selectUsg:SelectDataType[];
selectYN:SelectDataType[];
}}
selectSido: SelectDataType[];
selectSgg: SelectDataType[];
selectUsg: SelectDataType[];
selectYN: SelectDataType[];
};
};
type matDmdActions = {
decrementList: () => void
}
decrementList: () => void;
};
export type matDmdType = matDmdState & matDmdActions;
export const matDmdStateExport:matDmdState= {dmd:{
isInit:false,
selectSido:selectSido,
export const matDmdStateExport: matDmdState = {
dmd: {
isInit: false,
selectSido: selectSido,
selectSgg: selectSgg,
selectUsg: selectUsg,
selectYN:selectYN,
}}
export const matDmdActionsExport:(set:any)=>matDmdActions=(set: any) => {
return {
decrementList:()=>set(
(state:matDmdState) => {
return (
{rain:{
}})}
)
}
}
selectYN: selectYN,
},
};
export const matDmdActionsExport: (set: any) => matDmdActions = (set: any) => {
return {
decrementList: () =>
set(() => {
return { rain: {} };
}),
};
};
@@ -1,4 +1,3 @@
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
type nameMap = {
[key: string]: string;
+70 -48
View File
@@ -1,6 +1,6 @@
import type { CommonTableProps } from "@/app/store/common/type/header";
import { deleteFectch, fetchType, getFetch, postFectch, putFectch } from "@/components/lib/api";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import { deleteFectch, fetchType, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import toast from "react-hot-toast";
import { z } from "zod";
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
import { ldrmntHeadListExport, ldrmntNodeListExport, ldrmntZod } from "./headList";
@@ -20,6 +20,8 @@ export type ldrmntState = {
excelList: ExcelType[];
isInit: boolean;
ldrmntRes: customLdrmnt[];
isLoading: boolean;
ldrmntResCount: number;
};
};
@@ -32,9 +34,10 @@ const excelDownList: ExcelType[] = [];
type ldrmntActions = {
ldrmntRegData: (data: any[]) => void,
ldrmntInit: (con: string) => void
ldrmntSearch: (page: number, sggCd: string, total: string, coNm: string) => void;
ldrmntSearch: (isExcel: boolean, page: number, sggCd: string, total: string, coNm: string) => void;
ldrmntUpdate: (ldrmntRes: customLdrmnt) => void;
ldrmntDelete: () => void;
loadingOpen: (isOpen: boolean) => void
};
export type ldrmntType = ldrmntState & ldrmntActions;
@@ -46,6 +49,8 @@ export const ldrmntStateExport: ldrmntState = {
excelList: [],
isInit: false,
ldrmntRes: ldrmntRes,
isLoading: false,
ldrmntResCount: 1,
},
};
@@ -55,7 +60,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
return {
ldrmntInit: async (con: string) => {
try {
const ldrmntRes = await getFetch(
const ldrmntRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/request/temp/1/20/${con}`
);
@@ -65,7 +70,8 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
...state,
ldrmnt: {
...state.ldrmnt,
ldrmntRes: ldrmntRes,
ldrmntRes: ldrmntRes.data,
ldrmntResCount: ldrmntRes.count,
isInit: false,
excelList: excelDownList,
},
@@ -75,33 +81,32 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
console.log(e)
}
},
ldrmntRegData: async (data) => {
try {
const response = await postFectch(
"/reuseFc/request/temp",
data,
fetchType.WR
);
console.log('response ', response)
if (response.status === 200) {
ToastFormUi({
body: "잠재수요처 등록이 완료되었습니다. ",
title: "잠재수요처 등록",
});
}
} catch (e) {
console.log(e)
ToastFormUi({
body: "잠재수요처 등록이 실패하였습니다. ",
title: "잠재수요처 등록",
});
}
loadingOpen: (isOpen) => {
return set((state: ldrmntState) => {
return {
...state,
ldrmnt: {
...state.ldrmnt,
isLoading: isOpen,
},
};
});
},
ldrmntSearch: async (page: number, total: string, sggCd: string, coNm: string) => {
ldrmntRegData: async (data) => {
await deleteFectch(
`/reuseFc/request/temp`,
);
const response = await postFectch(
"/reuseFc/request/temp",
data,
fetchType.WR
);
console.log('response ', response)
},
ldrmntSearch: async (isExcel: boolean, page: number, total: string, sggCd: string, coNm: string) => {
let searchUrl = "";
if (sggCd !== "") {
@@ -112,14 +117,14 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
}
}
try {
const ldrmntRes = await getFetch(
const ldrmntRes = await getFetchWithCount(
fetchType.WR,
searchUrl
);
if (Number(total) > 5000) {
let excelDownList: ExcelType[] = [];
ldrmntRes.forEach((item: customLdrmnt) => {
console.log("알이에스", ldrmntRes)
if (isExcel) {
const excelDownList: ExcelType[] = [];
ldrmntRes.data.forEach((item: customLdrmnt) => {
excelDownList.push({
ctpvCd: item.ctpvCd,
sggCd: item.sggCd,
@@ -135,7 +140,7 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
ldrmnt: {
...state.ldrmnt,
excelList: excelDownList,
ldrmntResCount: ldrmntRes.count,
},
};
});
@@ -146,7 +151,8 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
...state,
ldrmnt: {
...state.ldrmnt,
ldrmntRes: ldrmntRes,
ldrmntRes: ldrmntRes.data,
ldrmntResCount: ldrmntRes.count,
isInit: false,
},
};
@@ -157,32 +163,48 @@ export const ldrmntActionsExport: (set: any) => ldrmntActions = (
}
},
ldrmntUpdate: async (ldrmntRes: customLdrmnt) => {
if(ldrmntRes)
try {
ldrmntRes.rgtr = TEST_UUID;
const response = await putFectch(
const res = await putFectch(
`/reuseFc/request/temp`,
ldrmntRes
);
return set((state: ldrmntState) => ({
...state,
ldrmnt: {
...state.ldrmnt,
ldrmntRes: ldrmntRes,
},
}));
if (res.ok) {
toast.success("잠재수요처 상세정보가 수정되었습니다.",)
}
} catch (error) {
console.error("Error ldrmntUpdate:", error);
toast.error("잠재수요처 상세정보 수정에 실패하였습니다.")
}
},
ldrmntDelete: async () => {
try {
const response = await deleteFectch(
set((state: ldrmntState) => {
return {
...state,
ldrmnt: {
...state.ldrmnt,
isLoading: true,
},
};
});
await deleteFectch(
`/reuseFc/request/temp`,
);
} catch (error) {
console.log("error", error)
set((state: ldrmntState) => {
return {
...state,
ldrmnt: {
...state.ldrmnt,
isLoading: false,
},
};
});
console.error("Error ldrmntDelete:", error);
}
},
@@ -1,7 +1,7 @@
import { fetchType, getFetch, getFetchWithCount, postFectch } from "@/components/lib/api";
import { fetchType, getFetchWithCount, postFectch } from "@/components/lib/api";
import { toast } from "react-hot-toast";
import type { TableUpperProps } from "../../common/type/header";
import { ruseCaseHeadListExport } from "./headList";
import { toast } from "react-hot-toast";
export type ruseCaseState = {
ruseCaseMng: {
ruseHeadList:TableUpperProps[];
@@ -1,14 +1,11 @@
import type { z } from "zod";
import type { sttnHeadListType } from "../coSttn/headList";
import type {
CommonTableProps,
TableUpperProps,
} from "../../common/type/header";
import { ruseHstryHeadListExport } from "./headList";
import { fetchType, getFetch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import type { DmdCoReqType } from "../coMatRvw/type";
import { fetchType, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import toast from "react-hot-toast";
import type {
TableUpperProps
} from "../../common/type/header";
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
import type { DmdCoReqType } from "../coMatRvw/type";
import { ruseHstryHeadListExport } from "./headList";
const ruseHistHeadList = ruseHstryHeadListExport;
@@ -72,7 +69,7 @@ type ruseHstryActions = {
endYear: string,
sggCd: string
) => void;
ruseRvwComplete:( data: Number[]) => void;
ruseRvwComplete:( data: number[]) => void;
};
const irvwHistInit = async (
@@ -81,7 +78,7 @@ const irvwHistInit = async (
startYear: string,
endYear: string,
) => {
let url = `/reuseFc/request/infoList/Matched/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
const url = `/reuseFc/request/infoList/Matched/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
// console.log("sggCd ", sggCd);
// if (sggCd) {
@@ -102,7 +99,6 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (
pageCnt: number,
startYear: string,
endYear: string,
sggCd?: string
) => {
const rvwHistRes = await irvwHistInit(
pageNo,
@@ -213,7 +209,7 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (
console.log(" error ", e);
}
},
ruseRvwComplete: async (data: Number[]) => {
ruseRvwComplete: async (data: number[]) => {
try {
const complet = await postFectch(
`/reuseFc/request/completeCheck`,
@@ -1,7 +1,6 @@
import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type { SelectDataType } from "@common/business_components";
import type { rainChkZodType } from ".";
import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { buildingType } from "../../../common/code/index";
export const useTypes = [
"조경용수",
"청소화장실용수",
@@ -13,7 +12,7 @@ export const useTypes = [
];
export type Buildingtype = {
bdstInfoPk: number;
bdstInfoSn: number;
ctpvCd: 1;
sggCd: 1001;
daddr: "string3";
@@ -35,7 +34,7 @@ export const buildingToExcelType = (
buildings.forEach((building) => {
useTypes.forEach((useType) => {
excelData.push([
building.bdstInfoPk.toString(),
building.bdstInfoSn.toString(),
sidoCode.find((sido) => sido.val === building.ctpvCd.toString())
?.text || "",
sggCdoe.find((sido) => sido.val === building.sggCd.toString())
@@ -85,6 +84,7 @@ export const buildingToExcelType = (
};
export const excelToRainChkData = (excelData: any, year: string) => {
// const errors: string[] = [];
const rainChkgdData: rainChkZodType[] = excelData.map((item: any) => {
if (item["점검일"] !== undefined) {
const checkYmd = item["점검일"].replace(/\./g, "")
@@ -106,10 +106,9 @@ export const excelToRainChkData = (excelData: any, year: string) => {
flg: "RNB",
};
});
return {
bdstRuseFcltFk: Number(item["NO"]),
bdstNm:item["시설명"] ?? "",
bdstRuseFcltSn: Number(item["NO"]),
chckYmd: checkYmd,
spwtPositn: item["유량측정방법"] ?? "",
rgtr: TEST_UUID,
@@ -133,5 +132,69 @@ export const excelToRainChkData = (excelData: any, year: string) => {
};
}
}).filter((el: any) => el !== undefined);
return rainChkgdData;
// // ✨ 오류 검사 - 가공된 데이터 기준
// const isInvalidNumber = (val: any) =>
// val !== undefined && val !== null && val !== "" && isNaN(Number(val));
// const isInvalidDate = (val: any) =>
// typeof val === "string" && !/^\d{4}\.\d{2}\.\d{2}$/.test(val.trim());
// const buildErrorMessage = (item: any, issues: string[]): string => {
// const 시설명 = item.bdstNm ?? "";
// const 점검일 = item.chckYmd ?? "";
// const 이용용도 = item.utztnUsgCd ?? "";
// return `시설명: ${시설명}, 점검일: ${점검일}, 이용용도: ${이용용도} (=> ${issues.join(", ")})`;
// };
// if (rainChkgdData.length > 0) {
// rainChkgdData.forEach((rain: any) => {
// const item = rain.__origin; // 원본 item
// const issues: string[] = [];
// if (rain.chckYmd && isInvalidDate(rain.chckYmd)) {
// issues.push(`점검일: 날짜 형식 아님 (${rain.chckYmd})`);
// }
// if (rain.vltnDt && isInvalidDate(rain.vltnDt)) {
// issues.push(`과태료 부과일(위반일): 날짜 형식 아님 (${rain.vltnDt})`);
// }
// // [
// // "연간운영비(원/년)", "PH", "탁도", "총대장균군수", "과태료부과금액(천원)"
// // ].forEach((key) => {
// // if (isInvalidNumber(item[key])) {
// // issues.push(`${key}: 숫자 형식 아님 (${item[key]})`);
// // }
// // }
// // );
// for (let i = 1; i <= 12; i++) {
// const month = `${i}월`;
// if (isInvalidNumber(item[`대체_${month}`])) {
// issues.push(`대체_${month}: 숫자 형식 아님 (${item[`대체_${month}`]})`);
// }
// if (isInvalidNumber(item[`빗물_${month}`])) {
// issues.push(`빗물_${month}: 숫자 형식 아님 (${item[`빗물_${month}`]})`);
// }
// }
// if (issues.length > 0) {
// errors.push(buildErrorMessage(item, issues));
// }
// });
// }
// if (errors.length > 0) {
// return { rainChkgdData: [], errors };
// }
// return { rainChkgdData, errors: [] };
// return rainChkgdData;
};
@@ -2,7 +2,7 @@ import type { TableUpperProps } from "@/app/store/common/type/header";
import { z } from "zod";
export const chkgdRegExcel = z.object({
bdstInfoPk: z.number().default(111111111),
bdstInfoSn: z.number().default(111111111),
chckYr: z
.string()
.default("")
@@ -21,7 +21,7 @@ export const chkgdRegExcel = z.object({
});
export const guideDetail = z.object({
chkgdnFk: z.number().nullable(),
chkgdnSn: z.number().nullable(),
utztnUsgCd: z.string(),
chckYmd: z.string(),
ym: z.string(),
@@ -30,8 +30,8 @@ export const guideDetail = z.object({
flg: z.string(),
});
export const rainChkZod = z.object({
chkgdnPk: z.number().nullable(),
bdstRuseFcltFk: z.number(),
chkgdnSn: z.number().nullable(),
bdstRuseFcltSn: z.number(),
chckYmd: z.string(),
cityText:z.string().nullish(),
sggText:z.string().nullish(),
@@ -45,7 +45,7 @@ export const rainChkZod = z.object({
guideDetails: z.array(guideDetail),
building: z
.object({
bdstInfoPk: z.number(),
bdstInfoSn: z.number(),
ctpvCd: z.number(),
sggCd: z.number(),
daddr: z.string().nullable(),
@@ -60,7 +60,7 @@ export const rainChkZod = z.object({
.nullable(),
rainyDetails: z.array(
z.object({
chkgdnFk: z.number().nullable(),
chkgdnSn: z.number().nullable(),
utztnUsgCd: z.string(),
ph: z.number().nullable(),
trbt: z.number().nullable(),
@@ -68,14 +68,14 @@ type rainChkgdnActions = {
sggCd: string,
searchTxt: string
) => void;
rainChkDetilUpdate(rainChk: rainChkZodType[]): Promise<void>;
rainChkDetilUpdate(rainChk: rainChkZodType[] ,year:string) : Promise<void>;
rainChkGuidUpdate(rainChk: rainChkZodType): Promise<void>;
rainChkExcelDownload(
sidoCode: SelectDataType[],
sggCode: SelectDataType[]
): Promise<void>;
rainChkExcelDataUPload(excelData: rainChkZodType[]): Promise<void>;
rainChkDelete(chkgdnPks: number[]): Promise<void>;
rainChkExcelDataUPload(excelData: rainChkZodType[] ,year :string) : Promise<void>;
rainChkDelete(chkgdnSns: number[] ,year :string): Promise<void>;
rainChkHeadChange: (rainChkgdn: rainChkgdnState, isEdit: boolean) => void;
rainChkNmSearch: (
pageNo: number,
@@ -107,7 +107,7 @@ export const rainChkgdnStateExport: rainChkgdnState = {
},
};
const makeMdfrChk = (data: rainChkZodType[], type: string, toDo: string) => {
const makeMdfrChk = (data: rainChkZodType[], type: string) => {
const chData = data.map((item) => {
item.mdfr = TEST_UUID;
item.rgtr = TEST_UUID;
@@ -165,17 +165,16 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = (
},
}));
},
rainChkExcelDataUPload: async (excelData: rainChkZodType[]) => {
rainChkExcelDataUPload: async (excelData: rainChkZodType[] ,year:string) => {
set((state: rainChkgdnType) => (
{ rainChkgdn: { ...state.rainChkgdn, isLoading: true } }));
try {
const res = await postFectch("/reuseChk/rainy", excelData);
if (res.status === 200) {
const currentYear = new Date().getFullYear().toString();
const rainChkRes = await initFetch(
1,
rainPageSize,
currentYear,
year,
commonCd
);
set((state: rainChkgdnState) => ({
@@ -255,20 +254,19 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = (
console.log(error);
}
},
rainChkDetilUpdate: async (rainChk: rainChkZodType[]) => {
rainChkDetilUpdate: async (rainChk: rainChkZodType[] ,year:string) => {
try {
const chData = await makeMdfrChk(rainChk, "rain", "rainDetil");
const chData = await makeMdfrChk(rainChk, "rain");
const res = await putFectch("/reuseChk/rainy/list", chData);
if (res) {
toast.success(
"지도점검 대체수 및 밋물이용량 수정이 완료되었습니다. "
);
const currentYear = new Date().getFullYear().toString();
const rainChkRes = await initFetch(
1,
rainPageSize,
currentYear,
year,
"41"
);
return set((state: rainChkgdnState) => ({
@@ -314,21 +312,21 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = (
}
} catch (error) {
console.log(' 지도점검 수질 및 과태료 수정 오류', error)
toast.error("지도점검 수질 및 과태료 수정 오류입니다.");
}
},
rainChkDelete: async (chkgdnPks: number[]) => {
rainChkDelete: async (chkgdnSns: number[] ,year :string) => {
try {
const res = await deleteFectch(`/reuseChk/rainy`, chkgdnPks);
const res = await deleteFectch(`/reuseChk/rainy`, chkgdnSns);
if (res) {
toast.success("삭제가 완료되었습니다. ");
const currentYear = new Date().getFullYear().toString();
const rainChkRes = await initFetch(
1,
rainPageSize,
currentYear,
year,
"41"
);
return set((state: rainChkgdnState) => ({
@@ -344,6 +342,8 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = (
}
} catch (error) {
console.log(' 삭제시 오류가 발생하였습니다', error)
toast.error("삭제시 오류가 발생하였습니다.. ");
}
},
@@ -16,7 +16,7 @@ export const rswtMakeExcelSample = (
buildings.forEach((building) => {
useTypes.forEach((useType) => {
excelSite.guideDetail.push([
building.bdstInfoPk.toString(),
building.bdstInfoSn.toString(),
sidoCode.find((sido) => sido.val === building.ctpvCd.toString())
?.text || "",
sggCdoe.find((sido) => sido.val === building.sggCd.toString())?.text ||
@@ -62,7 +62,7 @@ export const rswtMakeExcelSample = (
buildings.forEach((building) => {
useTypes.forEach((useType) => {
excelSite.polutions.push([
building.bdstInfoPk.toString(),
building.bdstInfoSn.toString(),
sidoCode.find((sido) => sido.val === building.ctpvCd.toString())
?.text || "",
sggCdoe.find((sido) => sido.val === building.sggCd.toString())?.text ||
@@ -146,7 +146,7 @@ export const excelToRswtGuideData = (excelData: any, year: string) => {
});
return {
bdstRuseFcltFk: Number(item["NO"]),
bdstRuseFcltSn: Number(item["NO"]),
operMngCd: item["운영관리형태"],
anlOperCst: Number(item["연간운영비(원/년)"]) ?? 0,
prcsCpct: item["처리용량(m³)"],
@@ -164,7 +164,7 @@ export const excelToRswtGuideData = (excelData: any, year: string) => {
return rainChkgdData;
};
export const excelToRswtPolution = (excelData: any, year: string) => {
export const excelToRswtPolution = (excelData: any) => {
const rainChkgdData: rswtChkZodType[] = excelData
.map((item: any) => {
if (item["점검일"] !== undefined) {
@@ -177,7 +177,7 @@ export const excelToRswtPolution = (excelData: any, year: string) => {
const makePoluttion = Array.from({ length: 4 }, (_, i) => {
let quarter = `${i+1}`;
const quarter = `${i+1}`;
const grssClfgUswtr = item[`${quarter}분기_총대장균군수`];
const combResdch = item[`${quarter}분기_결합잔류염소`];
const trbt = item[`${quarter}분기_탁도`];
@@ -209,7 +209,7 @@ export const excelToRswtPolution = (excelData: any, year: string) => {
});
return {
bdstRuseFcltFk: Number(item["NO"]),
bdstRuseFcltSn: Number(item["NO"]),
chckYmd: checkYmd,
utztnUsgCd: item["이용용도"],
operMngCd: item["운영관리형태"],
@@ -19,8 +19,8 @@ export type polutionType = {
edit?:boolean
};
const reuseBuildingZod = z.object({
bdstRuseFcltPk: z.number().nullish(),
bdstInfoFk: z.number().nullish(),
bdstRuseFcltSn: z.number().nullish(),
bdstInfoSn: z.number().nullish(),
instlCmptnDt: z.string().nullable(), // Assuming it's a date string or null
instlCst: z.number(),
operMngCd: z.string().nullable(),
@@ -41,7 +41,7 @@ const reuseBuildingZod = z.object({
});
const buildingZod = z.object({
bdstInfoPk: z.number().nullable(),
bdstInfoSn: z.number().nullable(),
ctpvCd: z.number(),
sggCd: z.number(),
daddr: z.string().nullable(),
@@ -75,7 +75,7 @@ export const rswtrPolutionsZode = z.object({
export const rswtrDetailsZod = z.object({
chkgdnDtlPk: z.string().nullish(),
chkgdnFk: z.string().nullish(),
chkgdnSn: z.string().nullish(),
utztnUsgCd: z.string(),
vltnDt: z.string(),
vltnMttr: z.string(),
@@ -87,8 +87,8 @@ export const rswtrDetailsZod = z.object({
})
export const rswtChkgdZod = z.object({
chkgdnPk: z.number().nullish(),
bdstRuseFcltFk: z.number().nullish(),
chkgdnSn: z.number().nullish(),
bdstRuseFcltSn: z.number().nullish(),
chckYmd: z.string(),
prcsCpct: z.number(),
dtfcltCpct: z.number(),
@@ -78,9 +78,9 @@ type rswtChkgdnActions = {
sggCode: SelectDataType[]
): Promise<void>;
rswtChkExceDataUpload: (excelData: rswtChkZodType[]) => void;
rswtChkDelete: (chkgdnPks: number[]) => void;
rswtChkDetilsUpdate: (rswtChkDetails: rswtrChkDetailsZodType[]) => void;
rswtChkPolAndGuide: (chkGdnPk: number) => void;
rswtChkDelete: (chkgdnSns: number[] ,year:string) => void;
rswtChkDetilsUpdate: (rswtChkDetails: rswtrChkDetailsZodType[] ,year:string) => void;
rswtChkPolAndGuide: (chkgdnSn: number) => void;
rswtChkPolInit: () => void;
rwstPolAndGuideUpdate: (rswtChk: rswtChkZodType[]) => void;
rswtChkHeadChange: (rswtChkgdn: rswtChkgdnState, isEdit: boolean) => void;
@@ -189,7 +189,6 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
try {
const rswtChkRes = await initFetch(pageNo, cnt, year, sggCd);
console.log("rswtChkRes", rswtChkRes)
set((state: rswtChkgdnState) => ({
...state,
@@ -201,7 +200,7 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
},
}));
} catch (error) {
// console.log(error);
console.error(error);
// set((state: rswtChkgdnType) => ({
// rswtChkgdn: { ...state.rswtChkgdn, isInit: true },
// }));
@@ -271,7 +270,7 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
}
},
rswtChkDetilsUpdate: async (rswtChk: rswtrChkDetailsZodType[]) => {
rswtChkDetilsUpdate: async (rswtChk: rswtrChkDetailsZodType[] ,year:string) => {
try {
const chData = await makeMdfrChk(rswtChk);
@@ -279,8 +278,7 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
if (res.ok) {
toast.success("지도점검 과태료 수정이 완료되었습니다. ",)
}
const currentYear = new Date().getFullYear().toString();
const rswtChkRes = await initFetch(1, rswtPageSize, currentYear, "0");
const rswtChkRes = await initFetch(1, rswtPageSize, year, "0");
return set((state: rswtChkgdnState) => ({
...state,
rswtChkgdn: {
@@ -295,15 +293,14 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
}
},
rswtChkDelete: async (chkgdnPks: number[]) => {
rswtChkDelete: async (chkgdnSns: number[] ,year:string) => {
try {
const res = await deleteFectch(`/reuseChk/reuseWater`, chkgdnPks);
const res = await deleteFectch(`/reuseChk/reuseWater`, chkgdnSns);
if (res) {
toast.success("삭제가 완료되었습니다.")
}
const currentYear = new Date().getFullYear().toString();
const rswtChkRes = await initFetch(1, rswtPageSize, currentYear, "0");
const rswtChkRes = await initFetch(1, rswtPageSize, year, "0");
return set((state: rswtChkgdnState) => ({
...state,
rswtChkgdn: {
@@ -314,13 +311,14 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
}));
} catch (error) {
toast.error("삭제 오류입니다.")
console.error(error);
}
},
rswtChkPolAndGuide: async (chkGdnPk: number) => {
rswtChkPolAndGuide: async (chkgdnSn: number) => {
try {
const rswtChkPolGuide = await getFetch(
"wr",
`/reuseChk/reuseWater/${chkGdnPk}`
`/reuseChk/reuseWater/${chkgdnSn}`
);
return set((state: rswtChkgdnState) => ({
@@ -331,9 +329,7 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
},
}));
} catch (error) {
console.error(error);
}
},
rswtChkPolInit: () => {
@@ -345,13 +341,15 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
rswtChkPolGuide: undefined,
},
}));
} catch (error) {}
} catch (error) {
console.error(error);
}
},
rwstPolAndGuideUpdate: async (rswtChk: rswtChkZodType[]) => {
try {
const chData = await makeMdfrChk(rswtChk);
const res = await putFectch(
`/reuseChk/reuseWater/${rswtChk[0]?.chkgdnPk}`,
`/reuseChk/reuseWater/${rswtChk[0]?.chkgdnSn}`,
chData[0]
);
if (res.ok) {
@@ -391,7 +389,9 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
rswtDetailHeadList: rswtDetailHeadList,
},
}));
} catch (e) {}
} catch (e) {
console.error(e);
}
},
};
};
@@ -23,7 +23,7 @@ type NameMap = {
};
export const excelToPbnPrfData = (excelData: JSON[], year: string,pbnstRuseFcltFk:string) => {
export const excelToPbnPrfData = (excelData: JSON[], year: string,pbnstRuseFcltId:string) => {
// 월별 데이터 하나로 병합
const merged = {} as any;
excelData.forEach((item: any) => {
@@ -46,7 +46,7 @@ export const excelToPbnPrfData = (excelData: JSON[], year: string,pbnstRuseFcltF
return({
...(item as object),
pbnstRuseFcltFk:pbnstRuseFcltFk,
pbnstRuseFcltId:pbnstRuseFcltId,
rgtr: TEST_UUID,
mdfr: TEST_UUID,
})
@@ -4,7 +4,7 @@ import type { TableUpperProps } from "../../common/type/header";
export const pbnPrfRegExcelZod = z.object({
ym: z.string().default(""),
bscFctNm: z.string().default(""),
pbnstRuseFcltFk: z.string(),
pbnstRuseFcltId: z.string(),
pbnstRuseFcltNm: z.string().default(""),
file: z.instanceof(File).optional(),
});
@@ -14,7 +14,7 @@ export const pbnstPrfmncHeadListExport: TableUpperProps[] = [
{ id: "gugun", title: "시군구" },
{ id: "bscFctNm", title: "시설명" },
{ id: "ruseUtztnFcltNm", title: "재이용시설명" },
{ id: "pbnstRuseFcltPk", title: "재이용시설코드" },
{ id: "pbnstRuseFcltId", title: "재이용시설코드" },
];
export const monthHeadListExport: TableUpperProps[] = [
@@ -3,7 +3,6 @@ import { pbnstPrfmncHeadListExport, monthHeadListExport } from "./headList";
import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
import type { FcPrfType, PrfType } from "./type";
import type { TableUpperProps } from "../../common/type/header";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import toast from "react-hot-toast";
const pbnstPrfmncHeadList = pbnstPrfmncHeadListExport;
@@ -15,7 +14,8 @@ export type pbnstPrfmncState = {
pbnstPrfmncHeadList: TableUpperProps[];
monthHeadList: TableUpperProps[];
prfmncRes: FcPrfType[];
excelList: Number[];
prfmncResCount:number;
excelList: number[];
pageKey:number
};
};
@@ -26,6 +26,7 @@ export const pbnstPrfmncStateExport: pbnstPrfmncState = {
pbnstPrfmncHeadList: pbnstPrfmncHeadList,
monthHeadList: monthHeadList,
prfmncRes: [],
prfmncResCount:1,
excelList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
pageKey:1
},
@@ -34,27 +35,30 @@ export const pbnstPrfmncStateExport: pbnstPrfmncState = {
export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions;
type pbnstPrfmncActions = {
prfmncHasuInit: (page: number, sggOrCity: string) => void;
prfmnRegData: (page:number,sggOrCity:string, data: PrfType) => void;
prfmncHasuInit: (page: number, sggOrCity: string ,year:string) => void;
prfmncHasuNmSearch: (page: number, sggOrCity: string , txt:string ,year:string) => void;
prfmnRegData: (page:number,sggOrCity:string, data: PrfType,year:string) => void;
};
const checkWrRegList = async () => {
const wrRegList = await getFetch("wr", `/reuseFc/pubDetailList`);
const checkWrRegList = async (year:string) => {
const url =`/reuseFc/pubDetailList`
if(year&& year.length>0){
// url+=`/${year}`
}
const wrRegList = await getFetch("wr", url);
return wrRegList;
};
const hasuListFetch = async (page: number, sggOrCity: string) => {
const checkWrRegListRes = await checkWrRegList();
const hasuListFetch = async (page: number, sggOrCity: string , year:string,searchNm?:string ) => {
const checkWrRegListRes = await checkWrRegList(year);
const rainRes = await postFectch(
`/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`,
checkWrRegListRes?.fcltCds,
fetchType.COMMON
);
const findData = rainRes.data.map((item: pubHasuType) => {
let findData = rainRes.data.map((item: pubHasuType) => {
const data = checkWrRegListRes?.fcPrfList.find(
(fclt: FcPrfType) =>
fclt.pbnstRuseFcltPk.substring(0, 11) === item?.bscFctCd
fclt.pbnstRuseFcltId.substring(0, 11) === item?.bscFctCd
);
if(data !==undefined){
return( {
@@ -64,26 +68,32 @@ const hasuListFetch = async (page: number, sggOrCity: string) => {
bscFctNm: item.bscFctNm,
bscFctCd: item.bscFctCd,
ruseUtztnFcltNm: data.ruseUtztnFcltNm,
pbnstRuseFcltPk: data.pbnstRuseFcltPk,
pbnstRuseFcltId: data.pbnstRuseFcltId,
prfList: data.prfList,
});
}
});
}).filter(Boolean); // undefined 값을 제거합니다.
return findData;
if(searchNm){
findData= findData.filter((ruse:any) => ruse.ruseUtztnFcltNm.includes(searchNm))
}
return {data:findData, count:findData.length};
};
export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
set: any
) => {
return {
prfmncHasuInit: async (page: number, sggOrCity: string) => {
prfmncHasuInit: async (page: number, sggOrCity: string,year:string) => {
try {
const prfmncRes = await hasuListFetch(page, sggOrCity);
const prfmncRes = await hasuListFetch(page, sggOrCity, year);
return set((state: pbnstPrfmncState) => ({
...state,
prfmnc: {
...state.prfmnc,
prfmncRes: prfmncRes,
prfmncRes: prfmncRes.data,
prfmncResCount: prfmncRes.count,
isInit: false,
},
}));
@@ -91,7 +101,23 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
console.log(errorHasu);
}
},
prfmnRegData: async (page:number,sggOrCity:string,data: PrfType) => {
prfmncHasuNmSearch: async (page: number, sggOrCity: string,fcltNm:string ,year:string)=> {
try {
const prfmncRes = await hasuListFetch(page, sggOrCity,fcltNm ,year);
return set((state: pbnstPrfmncState) => ({
...state,
prfmnc: {
...state.prfmnc,
prfmncRes: prfmncRes.data,
prfmncResCount: prfmncRes.count,
isInit: false,
},
}));
} catch (errorHasu) {
console.log(errorHasu);
}
},
prfmnRegData: async (page:number,sggOrCity:string,data: PrfType,year:string) => {
try {
const ressponse = await postFectch(
"/reuseFc/pubFcPrf",
@@ -102,12 +128,15 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
if (ressponse.status === 200) {
toast.success("하수재이용 시설 실적 등록이 완료되었습니다.");
const prfmncRes = await hasuListFetch(page, sggOrCity);
const prfmncRes = await hasuListFetch(page, sggOrCity,year) ;
return set((state: pbnstPrfmncState) => ({
...state,
prfmnc: {
...state.prfmnc,
prfmncRes: prfmncRes,
prfmncRes: prfmncRes.data,
prfmncResCount: prfmncRes.count,
isInit: false,
pageKey: state.prfmnc.pageKey + 1
},
@@ -1,9 +1,22 @@
import { z } from "zod";
import type { TableUpperProps } from "../../common/type/header";
import { fcOperSchema } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
type Month = `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12}월`;
export type PrfUsageSummary = {
구분?: string;
usage: string;
용수명?: string;
total: number;
edit?:boolean
} & Record<Month, number>;
export const PrfSchema = z.object({
pbnstRuseFcltFk: z.string(),
pbnstRuseFcltId: z.string(),
ym: z.string(), // 예: "202310"
wshwtr: z.number(),
coolUswtr: z.number(),
@@ -27,7 +40,7 @@ export const PrfSchema = z.object({
});
export const FcPrfSchema = z.object({
pbnstRuseFcltPk: z.string(),
pbnstRuseFcltId: z.string(),
ruseUtztnFcltNm: z.string(),
fcltCpct: z.number(),
ruseCpct: z.number(),
@@ -44,8 +57,9 @@ export const FcPrfSchema = z.object({
export type FcPrfType = z.infer<typeof FcPrfSchema>;
export type PrfType = z.infer<typeof PrfSchema>;
export const initValInUsage = [
export const initValInUsage:PrfUsageSummary[] = [
{
구분: "장내용수",
usage: "wshwtr",
용수명: "세척수",
total: 0,
@@ -63,6 +77,7 @@ export const initValInUsage = [
"12월": 0,
},
{
구분: "장내용수",
usage: "coolUswtr",
용수명: "냉각수",
total: 0,
@@ -80,6 +95,7 @@ export const initValInUsage = [
"12월": 0,
},
{
구분: "장내용수",
usage: "cleanUswtr",
용수명: "청소수",
total: 0,
@@ -97,6 +113,7 @@ export const initValInUsage = [
"12월": 0,
},
{
구분: "장내용수",
usage: "drwtUswtr",
용수명: "식수대",
total: 0,
@@ -114,6 +131,7 @@ export const initValInUsage = [
"12월": 0,
},
{
구분: "장내용수",
usage: "dltnUswtr",
용수명: "희석용수",
total: 0,
@@ -131,6 +149,7 @@ export const initValInUsage = [
"12월": 0,
},
{
구분: "장내용수",
usage: "ithlRswtr",
용수명: "중수도",
total: 0,
@@ -148,6 +167,7 @@ export const initValInUsage = [
"12월": 0,
},
{
구분: "장내용수",
usage: "ithlEtcUswtr",
용수명: "기타",
total: 0,
@@ -166,8 +186,9 @@ export const initValInUsage = [
},
];
export const initValOutUsage = [
export const initValOutUsage: PrfUsageSummary[] = [
{
구분: "장외용수",
usage: "resn",
용수명: "세척살수용수",
total: 0,
@@ -185,6 +206,7 @@ export const initValOutUsage = [
"12월": 0,
},
{
구분: "장외용수",
usage: "cleanToilUswtr",
용수명: "청소화장실용수",
total: 0,
@@ -202,6 +224,7 @@ export const initValOutUsage = [
"12월": 0,
},
{
구분: "장외용수",
usage: "lndwtr",
용수명: "조경용수",
total: 0,
@@ -219,6 +242,7 @@ export const initValOutUsage = [
"12월": 0,
},
{
구분: "장외용수",
usage: "hydUswtr",
용수명: "친수용수",
total: 0,
@@ -236,6 +260,7 @@ export const initValOutUsage = [
"12월": 0,
},
{
구분: "장외용수",
usage: "ugwtChr",
용수명: "지하수충전",
total: 0,
@@ -253,6 +278,7 @@ export const initValOutUsage = [
"12월": 0,
},
{
구분: "장외용수",
usage: "farmUswtr",
용수명: "농업용수",
total: 0,
@@ -271,6 +297,7 @@ export const initValOutUsage = [
},
{
구분: "장외용수",
usage: "rvrKeepUswtr",
용수명: "하천등유지용수",
total: 0,
@@ -289,6 +316,7 @@ export const initValOutUsage = [
},
{
구분: "장외용수",
usage: "indstUswtr",
용수명: "공업용수",
total: 0,
@@ -307,7 +335,7 @@ export const initValOutUsage = [
},
];
export const subTotalObj = {
export const subTotalObj:PrfUsageSummary = {
usage: "subtotal",
용수명: "소계",
edit: false,
@@ -326,7 +354,7 @@ export const subTotalObj = {
"12월": 0,
};
export const totalObj = {
export const totalObj:PrfUsageSummary = {
usage: "total",
용수명: "총합계",
edit: false,
@@ -1,21 +1,7 @@
import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
type rainSttnExcelType = {
bdstInfoPk: number;
ctpvCd: 1;
sggCd: 1001;
daddr: "string3";
bdstNm: "string";
frstArchPrmsnDt: "2025-03-25";
archArea: 0;
regDt: "2025-04-16";
rgtr: null;
mdfcnDt: "2025-04-16";
mdfr: null;
};
export const buildingExcelRainSttn = (excelList: any[]) => {
const excelData: string[][] = [];
excelList.forEach((item, index) => {
excelList.forEach((item) => {
excelData.push([
String(item.cityText) ?? "",
String(item.sggText) ?? "",
@@ -1,7 +1,7 @@
export const buildingExcelRswtSttn = (excelList: any[]) => {
const excelData: string[][] = [];
excelList.forEach((item, index) => {
excelList.forEach((item) => {
excelData.push([
String(item.cityText) ?? "",
String(item.sggText) ?? "",
@@ -2,7 +2,7 @@ import type { TableUpperProps } from "@/app/store/common/type/header";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn";
import { rswtHeadNmExport } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList";
import { getFetch, getFetchWithCount } from "@/components/lib/api";
import { getFetchWithCount } from "@/components/lib/api";
import { buildingExcelRswtSttn } from "./excel";
import { rswtChkSttnHeadListExport, rswtDetailSttnHeadListExport } from "./headList";
@@ -1,5 +1,4 @@
import { z } from "zod";
import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg";
import type { TableUpperProps } from "../../common/type/header";
export const pbnstPrfmncSttnHeadListExport: TableUpperProps[] = [
{
@@ -37,6 +36,7 @@ export const pbnstPrfmncSttnHeadListExport: TableUpperProps[] = [
export const pbnstYearHeadListExport: TableUpperProps[] = [
{
id: "year",
title: "년도",
colSpan: 3,
row: 0
@@ -57,3 +57,25 @@ export const pbnstYearHeadListExport: TableUpperProps[] = [
row: 1
},
]
export const monthSttnHeadListExport: TableUpperProps[] = [
{ id: "구분", title: "구분", mergeCell: true },
{ id: "용수명", title: "용수명" },
{ id: "total", title: "계" },
{ id: "1월", title: "1월" },
{ id: "2월", title: "2월" },
{ id: "3월", title: "3월" },
{ id: "4월", title: "4월" },
{ id: "5월", title: "5월" },
{ id: "6월", title: "6월" },
{ id: "7월", title: "7월" },
{ id: "8월", title: "8월" },
{ id: "9월", title: "9월" },
{ id: "10월", title: "10" },
{ id: "11월", title: "11월" },
{ id: "12월", title: "12월", },
];
@@ -1,6 +1,6 @@
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import type { TableUpperProps } from "../../common/type/header";
import { pbnstPrfmncSttnHeadListExport, pbnstYearHeadListExport } from "./headList";
import { monthSttnHeadListExport, pbnstPrfmncSttnHeadListExport, pbnstYearHeadListExport } from "./headList";
import type { FcPrfType, PrfType } from "../../prfmncReg/pbnstPrfmncReg/type";
import type { pubHasuType, selectLabel } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
import type { ReturnType } from "@common/business_components";
@@ -22,6 +22,7 @@ export type pbnstPrfmncSttnState = {
isInit: boolean;
rawData: any[];
selectYearList: selectLabel[]
monthSttnHeadList:TableUpperProps[];
}
}
@@ -34,7 +35,8 @@ export const pbnstPrfmncSttnExport: pbnstPrfmncSttnState = {
prfmncRes: prfmncRes,
isInit: false,
rawData: [],
selectYearList: []
selectYearList: [],
monthSttnHeadList:monthSttnHeadListExport
}
}
@@ -52,14 +54,14 @@ const hasuListFetch = async (page: string, sggOrCity: string) => {
const data = checkWrRegListRes.fcPrfList.map((item: FcPrfType) => {
const findData = rainRes.data.find(
(fclt: pubHasuType) =>
fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11)
fclt.bscFctCd === item.pbnstRuseFcltId.substring(0, 11)
);
return {
sido: findData?.sido,
gugun: findData?.gugun,
bscFctNm: findData?.bscFctNm,
ruseUtztnFcltNm: item.ruseUtztnFcltNm,
pbnstRuseFcltPk: item.pbnstRuseFcltPk,
pbnstRuseFcltId: item.pbnstRuseFcltId,
};
});
return data;
@@ -78,9 +80,7 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
yearHead.forEach((item: { id?: string; }) => {
if (item.id) {
item.id = i + item.id;
}
})
if (yearHead[0])
yearHead[0].title = i + "년도"
@@ -145,17 +145,16 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
)
let inUsageSum = 0;
let outUsageSum = 0;
let usageSum = 0;
let year = "";
const yearsData = []
const yearsData = [] as any
res.data.forEach((item) => {
res.data.forEach((item : any) => {
if (item.prfList.length === 0) {
const year = ""; // 연도 정보가 없으면 빈 문자열, 필요시 item에서 추출
const yearVal = { year: year, pbnstRuseFcltPk: item.pbnstRuseFcltPk ?? "", ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" };
yearVal[year + "inUsage"] = 0;
yearVal[year + "outUsage"] = 0;
yearVal[year + "total"] = 0;
const year: string = ""; // 연도 정보가 없으면 빈 문자열, 필요시 item에서 추출.
const yearVal: { [key: string]: any } = { year: year, pbnstRuseFcltId: item.pbnstRuseFcltId ?? "", ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" };
yearVal[`${year}inUsage`] = 0;
yearVal[`${year}outUsage`] = 0;
yearVal[`${year}total`] = 0;
yearsData.push(yearVal);
}
item.prfList.forEach((acc) => {
@@ -180,29 +179,30 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
const yearData = yearsData.find(
(yearItem) =>
yearItem.year === year &&
yearItem.pbnstRuseFcltPk == acc.pbnstRuseFcltFk
yearItem.pbnstRuseFcltId == acc.pbnstRuseFcltId
);
if (yearData) {
yearData[year + "inUsage"] += inUsageSum;
yearData[year + "outUsage"] += outUsageSum;
yearData[year + "total"] += (inUsageSum + outUsageSum);
yearData[`${year}inUsage`] += inUsageSum;
yearData[`${year}outUsage`] += outUsageSum;
yearData[`${year}total`] += (inUsageSum + outUsageSum);
} else {
const yearVal = { year: year, pbnstRuseFcltPk: acc.pbnstRuseFcltFk, ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" };
yearVal[year + "inUsage"] = inUsageSum;
yearVal[year + "outUsage"] = outUsageSum;
yearVal[year + "total"] = inUsageSum + outUsageSum;
const yearVal: { [key: string]: any } = { year: year, pbnstRuseFcltId: acc.pbnstRuseFcltId, ruseUtztnFcltNm : item.ruseUtztnFcltNm ?? "" };
yearVal[`${year}inUsage`] = inUsageSum;
yearVal[`${year}outUsage`] = outUsageSum;
yearVal[`${year}total`] = inUsageSum + outUsageSum;
yearsData.push(yearVal);
}
});
});
const resData: any[] = []
pbnstRes.forEach((acc) => {
let data = yearsData.find((item) => item.pbnstRuseFcltPk.substring(0, 11) === acc.bscFctCd)
const data = yearsData.find((item) => item.pbnstRuseFcltId.substring(0, 11) === acc.bscFctCd)
if (data) {
resData.push({ ...acc, ...data })
}
})
console.log("resData", resData)
return set((state: pbnstPrfmncSttnState) => ({
...state,
pbnstPrfmncSttn: {
@@ -3,7 +3,7 @@ import type { TableUpperProps } from "@/app/store/common/type/header";
export const htdTableHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도" },
{ id: "sggText", title: "시군구" },
{ id: "bdstNm", title: "발전소명" },
{ id: "bdstNm", title: "시설명" },
{ id: "daddr", title: "위치" },
{ id: "frstArchPrmsnDt", title: "준공년도" },
{ id: "archArea", title: "건축면적" },
@@ -1,21 +1,18 @@
import { getFetch, postFectch, putFectch } from "@/components/lib/api";
import { upHeadList, type chgBuilding } from "../rainReg";
import { getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import type { TableUpperProps } from "@/app/store/common/type/header";
import toast from "react-hot-toast";
import { z } from "zod";
import { makeMdfr, makeRstr } from "../bdstReg";
import {
baseReuseBuildingSchema,
chgBuildingSchema,
htdflReuseBuildingSchema,
validationMessages,
validationMessages
} from "../rainReg/type"; // Import baseReuseBuildingSchema, chgBuildingSchema, validationMessages
import type { TableUpperProps } from "@/app/store/common/type/header";
import { htdTableHeadList } from "./headList";
import toast from "react-hot-toast";
const hdtflObjSchema = z.object({
htdflFcltPk: z.number().nullish(),
bdstRuseFcltFk: z.number().nullish(),
bdstRuseFcltSn: z.number().nullish(),
etgtType: z
.string()
.min(1, { message: validationMessages.required("에너지원 종류") }),
@@ -64,7 +61,7 @@ const hdtflObjSchema = z.object({
});
export const hdtflZod = z.object({
bdstInfoPk: z.number().nullish(),
bdstInfoSn: z.number().nullish(),
ctpvCd: z.number().default(0),
sggCd: z.number().default(0),
cityText: z.string().nullish(),
@@ -96,6 +93,7 @@ export type htdflFacState = {
isInit: boolean;
upHeadList: TableUpperProps[];
htdflRes: customHtdflBdst[];
htdflResCount:number
};
};
type htdflFacSActions = {
@@ -114,19 +112,18 @@ export const htdflFacStateExport: htdflFacState = {
isInit: false,
upHeadList: htdTableHeadList,
htdflRes: htdflRes,
htdflResCount:1,
},
};
const initFetch = async (code: string) => {
console.log(' initFetch code ', code)
let url = `/drain/facilityList/1/20`
let url = `/drain/facilityList/1/10`
url+=`/${code}`
const rswtRes = await getFetch("wr", url);
const rswtRes = await getFetchWithCount("wr", url);
return rswtRes;
};
export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
@@ -135,15 +132,16 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
return {
getHtdflBdstData: async (pageNation: number, code: string | number) => {
try {
const rswtRes = await getFetch(
const htdflRes = await getFetchWithCount(
"wr",
`/drain/facilityList/${pageNation}/20/${code}`
`/drain/facilityList/${pageNation}/10/${code}`
);
return set((state: htdflFacState) => ({
...state,
htdfl: {
...state.htdfl,
htdflRes: rswtRes,
htdflRes: htdflRes.data,
htdflResCount:htdflRes.count,
isInit: false,
},
}));
@@ -159,7 +157,8 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
...state,
htdfl: {
...state.htdfl,
htdflRes: htdflRes,
htdflRes: htdflRes.data,
htdflResCount:htdflRes.count,
isInit: false,
},
};
@@ -170,29 +169,27 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
},
htdflBdstUpdate: async (data: customHtdflBdst, code: string | number) => {
try {
const chData = await makeMdfr(data);
const res = await putFectch("/drain/facility", chData);
if (res.status) {
toast.success("온배수 건축물 수정이 완료되었습니다.");
toast.success("온배수 시설물 수정이 완료되었습니다.");
}
const htdflRes = await getFetch(
const htdflRes = await getFetchWithCount(
"wr",
`/drain/facilityList/1/20/${code}`
`/drain/facilityList/1/10/${code}`
);
set((state: htdflFacState) => ({
...state,
htdfl: {
...state.htdfl,
htdflRes: htdflRes,
htdflRes: htdflRes.data,
htdflResCount:htdflRes.count,
isInit: false,
},
}));
} catch (errorUpdate) {
toast.error("온배수 건축물 수정 오류입니다..");
toast.error("온배수 시설물 수정 오류입니다..");
console.log(errorUpdate);
}
},
htdflBdstReg: async (data: customHtdflBdst, code: string | number) => {
@@ -203,31 +200,33 @@ export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
const chData = makeRstr(data);
const res = await postFectch("/drain/facility", chData);
if (res.status ===200) {
toast.success("온배수 건축물 등록이 완료되었습니다.");
toast.success("온배수 시설 등록이 완료되었습니다.");
}
const htdflRes = await initFetch(String(code));
set((state: htdflFacState) => ({
...state,
htdfl: {
...state.htdfl,
htdflRes: htdflRes,
htdflRes: htdflRes.data,
htdflResCount:htdflRes.count,
isInit: false,
},
}));
} catch (errorReg) {
toast.error("온배수 건축물 등록 오류입니다..");
toast.error("온배수 시설물 등록 오류입니다..");
console.log(errorReg);
}
},htdflNmSearch :async(code:string | number, fcltNm:string) =>{
try {
const htdflRes = await getFetch("wr", `/drain/facilityList/1/20/${code}/${fcltNm}`);
const htdflRes = await getFetchWithCount("wr", `/drain/facilityList/1/10/${code}/${fcltNm}`);
set((state: htdflFacState) => {
return {
...state,
htdfl: {
...state.htdfl,
htdflRes: htdflRes,
htdflRes: htdflRes.data,
htdflResCount:htdflRes.count,
isInit: false,
},
};
@@ -7,15 +7,15 @@ export const pubFacHeadListExport: TableUpperProps[] = [
{ id: "bscFctNm", title: "시설명" },
{ id: "addr", title: "위치" },
{ id: "efflWqltStndrdNm", title: "지역구분" },
{ id: "fctCpc", title: "시설용량" },
{ id: "fctCpc", title: "시설용량(m³/일)" },
{ id: "ruse", title: "재이용여부" },
{ id: "rswtrYn", title: "등록여부" },
];
export const pbnstMngUpHeadListExport: TableUpperProps[] = [
{ id: "choose", title: "선택", type: "checkbox" },
{ id: "operMthd", title: "운영방식",type: "select", selectData: "ruseMngMtd" },
{ id: "rprtvBzenty", title: "대행업체", edit: true },
{ id: "operMthd", title: "운영방식",type: "select", selectData: "ruseMngMtd" },
{ id: "rprtvBzenty", title: "대행업체", edit: true ,maxLength:10 },
{
id: "bgngDt",
title: "시작일",
@@ -47,10 +47,10 @@ export const pbnstDemandHeadListExport: TableUpperProps[] = [
export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [
{ id: "ruseUtztnFcltNm", title: "하수처리장명" },
{ id: "orgwtWtritQnt", title: "원수취수량" },
{ id: "orgwtWtritQnt", title: "원수취수량" , type:'number'},
{ id: "tmsYn", title: "하수처리량TMS 전후" },
{ id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​" },
{ id: "dtlPstnExpln", title: "상세위치 설명" },
{ id: "dtlPstnExpln", title: "상세위치", edit: true },
];
export const fcOrgwtsHeadListExport: TableUpperProps[] = [
{ id: "choose", title: "선택", type: "checkbox" },
@@ -55,20 +55,17 @@ export type pubFacState = {
fcOrgwtsNmList:pubHasuType[];
dmdComList: any[];
apiMessage:string;
pbnstHasuResCount:number
};
};
type pubFacActions = {
pubHasuInit: (page: string, sggOrCity: string) => void;
pbnstRegClick: (pubHasuRes: pubHasuType) => void;
pbnstReg: (txt: string | undefined) => void;
//pbnstReg: (txt: string | undefined) => void;
pbnstInsert(pbnstRes: customPbnst): Promise<void>;
appendRuseFclt(array: customPbnst[]): void;
fileDelete: (atflCd: string) => void;
fileDownLoad: (atflCd: string) => void;
//pbnstMngData: (data: customPbnst[]) => void;
//pbnstBizData(data: fcBizType): void;
// getBizCycle: (pbnstObj: customPbnst) => void;
getpbnstInsertIndex: (data: pbnstInsertIndex) => void;
pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void;
pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void;
pubHasuSearch :(page: string, sggOrCity: string , searchTxt:string) => void
@@ -95,7 +92,8 @@ export const pubFacStateExport: pubFacState = {
pbnsUpdateIndex: {} as pbnstInsertIndex,
fcOrgwtsNmList:[],
dmdComList: [],
apiMessage:''
apiMessage:'',
pbnstHasuResCount:1
},
};
@@ -124,11 +122,12 @@ if(searchTxt){
const hasuList = rainRes.data.map((item: any) => {
return {
...item,
fctCpc: Number(item.fctCpc) || 0,
ruse: item.ruse === false ? "N" : "Y",
};
});
return hasuList;
return {data: hasuList, count:rainRes.count};
};
const initFetch = async (ruseFcltPk: string | undefined) => {
@@ -179,13 +178,12 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
pubHasuInit: async (page: string, sggOrCity: string) => {
try {
const pbnstHasuRes = await hasuListFetch(page, sggOrCity);
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
pbnstHasuRes: pbnstHasuRes,
pbnstHasuRes: pbnstHasuRes.data,
pbnstHasuResCount:pbnstHasuRes.count,
isInit: false,
},
}));
@@ -200,7 +198,8 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
...state,
pbnst: {
...state.pbnst,
pbnstHasuRes: pbnstHasuRes,
pbnstHasuRes: pbnstHasuRes.data,
pbnstHasuResCount:pbnstHasuRes.count,
isInit: false,
},
}));
@@ -223,22 +222,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
console.log(errorHasu);
}
},
pbnstReg: async (txt: string | undefined) => {
try {
const pbnstRes = await hasuListFetch("11", "11");
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
pbnstRes: pbnstRes,
isInit: false,
},
}));
} catch (errorHasu) {
console.log(errorHasu);
}
},
pbnstInsert: async (pbnstRes: customPbnst) => {
try {
@@ -250,13 +233,12 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
toast.success(`${pbnstRes.ruseUtztnFcltNm} 하수재이용 시설이 등록되었습니다.`);
}
const pbnstHasuRes = await hasuListFetch('1', '0');
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
pbnstRes: pbnstHasuRes,
pbnstHasuRes: pbnstHasuRes.data,
pbnstHasuResCount:pbnstHasuRes.count,
isInit: false,
},
}));
@@ -266,44 +248,24 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
},pbnstRuseFcltUpdate : async(ruseRes:customPbnst[])=>{
try {
const response = await putFectch(
await putFectch(
`/reuseFc/pubFc`,
ruseRes
);
if(response){
toast.success(` 하수재이용 시설 정보가 수정되었습니다.`);
}
} catch (error) {
console.error("Error pbnstRuseFcltUpdate:", error);
toast.error(` 하수재이용 시설 정보가 수정오류입니다.`);
}
} ,pbnstRuseBizUpdate : async(ruseRes:fcBizType[])=>{
try {
console.log('ruseRes ', ruseRes)
const response = await putFectch(
await putFectch(
`/reuseFc/pubFcBiz`,
ruseRes
);
if(response){
toast.success(` 하수재이용 시설 사업이 수정되었습니다.`);
}
const pbnstRes = await hasuListFetch("11", "11");
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
pbnstRes: pbnstRes,
isInit: false,
},
}));
} catch (error) {
console.error("Error pbnstRuseFcltUpdate:", error);
toast.error(` 하수재이용 시설 사업이 수정이 실패되엇습니다..`);
}
} ,
getBizCycle: async (pbnstObj: customPbnst) => {
@@ -346,60 +308,17 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
},
fileDownLoad: async (atflCd: string) => {
try {
const response = await getFetch(
await getFetch(
fetchType.CS,
`/attach-service/api/v1/atflcd/download/${atflCd}`
);
if (!response.ok) {
throw new Error(`Error downloading file: ${response.statusText}`);
}
} catch (error) {
console.error("Error downloading file:", error);
throw new Error(`Error downloading file: ${error}`);
}
},
// pbnstMngData: (data: customPbnst[]) => {
// if (data.length > 0) {
// }
// return set((state: pubFacState) => {
// state.pbnst.pbnstMngRegData = data;
// state.pbnst.pbnstBizCycle =
// data.length <= 0
// ? [{ text: "없음", val: "1" }]
// : state.pbnst.pbnstBizCycle;
// return state;
// });
// },
// pbnstBizData: (data: fcBizType) => {
// return set((state: pubFacState) => {
// if (state.pbnst.pbnstMngRegData) {
// const regData = state.pbnst.pbnstMngRegData.find(
// (item) => data.pbnstRuseFcltFk === item.pbnstRuseFcltPk
// );
// if (regData) {
// const bizIdx = regData.fcBizs.findIndex(
// (item) => item.pbnstRuseFcltBizPk == data.pbnstRuseFcltBizPk
// );
// if (bizIdx >= 0) {
// regData.fcBizs[bizIdx] = data;
// const pbnstData = state.pbnst.pbnstMngRegData
// state.pbnst.pbnstMngRegData= [...pbnstData]
// }
// }
// }
// return state;
// });
// },
getpbnstInsertIndex: async (data: pbnstInsertIndex) => {
return set((state: pubFacState) => {
state.pbnst.pbnsUpdateIndex = data;
return state;
});
},
appendRuseFclt: async (array: customPbnst[]) => {
try {
return set((state: pubFacState) => ({
@@ -414,10 +333,9 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
console.log(e);
}
},getFcOrgwts : async (fcltPkList: string[] ,size:number) => {
let url = `/prcsFclt/ruseInfo/1/${size}/A/0/0/1/SW`;
const fcOrgwtsNmList = await postFectch(
url,
`/prcsFclt/ruseInfo/1/${size}/A/0/0/1/SW`,
fcltPkList,
fetchType.COMMON
);
@@ -429,9 +347,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
fcOrgwtsNmList:fcOrgwtsNmList.data??[]
},
}));
}
};
};
@@ -1,5 +1,4 @@
import { z } from "zod";
import { TEST_UUID } from "../rainReg";
export type customPbnst = z.infer<typeof pbnstRegZod>;
@@ -31,12 +30,12 @@ export type publicReuseFacilityType = {
area?: string;
reuse?: string;
register?: string;
swtrmtFcltFk: string;
swtrmtFcltId: string;
};
export type ruseFcltType = {
swtrmtFcltFk: string;
pbnstRuseFcltPk: string;
swtrmtFcltId: string;
pbnstRuseFcltId: string;
fcltNm: string;
fcltCpct: number;
swtrmtCpct: number;
@@ -45,7 +44,7 @@ export type ruseFcltType = {
};
export type PbnstDemandComType = {
dmdInfoPk: string | "";
dmdInfoId: string | "";
bzmnNo: string | "";
dmdCoNm: string | "";
daddr: string | "";
@@ -57,10 +56,10 @@ export type PbnstDemandComType = {
dmdAplyPswd: string | "";
splyCpct: number | 0;
splyFmYn: string | "Y";
// dmdInfoFk:string|''
// dmdInfoId:string|''
};
const pubHasuZod = z.object({
export const pubHasuZod = z.object({
choose: z.boolean().default(false),
bscFctCd: z.string(),
sido: z.string().default(""),
@@ -86,7 +85,7 @@ const zNumNullish = zNum.nullish();
const zNumDefaultZero = zNum.default(0).nullish();
const pplInstlSchema = z.object({
ruseFcltBizFk: zNumNullish,
pbnstRuseFcltBizSn: zNumNullish,
choose: z.boolean().default(false),
pdmt: z.string().default(""),
ppMqlt: z.string().default(""),
@@ -94,7 +93,7 @@ const pplInstlSchema = z.object({
});
const fcFileSchema = z.object({
ruseFcltFk: z.string().nullish(),
pbnstRuseFcltId: z.string().nullish(),
fileTkn: z.string(),
filePath: z.string(),
fileKnd: z.string(),
@@ -105,8 +104,8 @@ const fcFileSchema = z.object({
});
export const fcOperSchema = z.object({
pbnstRuseFcltOperInfoPk: zNumNullish,
pbnstRuseFcltFk: z.string().nullish(),
pbnstRuseFcltOperInfoSn: zNumNullish,
pbnstRuseFcltId: z.string().nullish(),
operMthd: z.string(),
rprtvBzenty: z.string(),
bgngDt: zDateDefaultNow,
@@ -119,8 +118,8 @@ export const fcOperSchema = z.object({
});
const fcOrgwtSchema = z.object({
pbnstRuseFcltBizFk: zNumNullish,
swtrmtFcltFk: z.string().nullish(),
pbnstRuseFcltBizSn: zNumNullish,
swtrmtFcltId: z.string().nullish(),
orgwtWtritQnt: zNum,
tmsYn: z.enum(["Y", "N"]).default("N"),
dschgFmYn: z.enum(["Y", "N"]).default("N"),
@@ -134,7 +133,7 @@ const fcOrgwtSchema = z.object({
});
const dmdColist = z.object({
dmdInfoPk: z.string().default(""),
dmdInfoId: z.string().default(""),
dmdCoNm: z.string().default(""),
daddr: z.string(),
useUsgCd: z.string().nullish(),
@@ -144,14 +143,13 @@ const dmdColist = z.object({
splyFmYn: z.string().nullish(),
rgtr: z.string().nullish(),
mdfr: z.string().nullish(),
pbnstRuseFcltBizPk: zNumDefaultZero,
pbnstRuseFcltFk: z.string().nullish(),
pbnstRuseFcltBizSn: zNumDefaultZero,
pbnstRuseFcltId: z.string().nullish(),
});
export const fcBizSchema = z.object({
pbnstRuseFcltBizPk: zNumNullish,
pbnstRuseFcltFk: z.string().nullish(),
superkey: z.string().default("").nullish(),
pbnstRuseFcltBizSn: zNumNullish,
pbnstRuseFcltId: z.string().nullish(),
cycl: zNum.default(1),
seCd: z.string().max(10, "구분은 10자를 초과할 수 없습니다.").default(""),
bizMthdCd: z.string().default(""),
@@ -234,27 +232,33 @@ export const fcBizSchema = z.object({
});
export const pbnstRegZod = z.object({
pbnstRuseFcltPk: z.string().default(""),
swtrmtFcltFk: z.string().default(""),
ruseUtztnFcltNm: z
.preprocess(
pbnstRuseFcltId: z.string().default(""),
swtrmtFcltId: z.string().default(""),
ruseUtztnFcltNm: //z.string().default(''),
z.preprocess(
(v) => (v !== null && v !== undefined ? String(v).trim() : ""), // null/undefined → "", 공백 제거
z.string().min(1, "시설 이름을 입력하세요")),
fcltCpct: zNumDefaultZero,
ruseCpct: zNumDefaultZero,
splyExtraCpct: zNumDefaultZero,
fcltCpct: z.preprocess(
(v) => (v !== null && v !== undefined ? Number(v) : v),
z.number().gte(0, { message: "재이용시설 용량은 0보다 크거나 같아야 합니다" })
),
ruseCpct: z.preprocess(
(v) => (v !== null && v !== undefined ? Number(v) : v),
z.number().gte(0, { message: "재이용시설 재이용수 공급량은 0보다 크거나 같아야 합니다" })
),
splyExtraCpct: z.preprocess(
(v) => (v !== null && v !== undefined ? Number(v) : v),
z.number().gte(0, { message: "재이용시설 공급가능량은 0보다 크거나 같아야 합니다" })
),
regDt: zDateDefaultNow,
rgtr: z.string().default("test"),
mdfcnDt: zDateDefaultNow,
mdfr: z.string().default("test"),
fcFiles: z.array(fcFileSchema).default([]).nullish(),
fcBizs: z.array(fcBizSchema).default([]),
fcOpers: z
.array(fcOperSchema)
.refine((val) => val.length >= 1, {
message: "재이용시설의 운영정보를 최소 하나를 등록해주세요",
})
.default([]), // 기본값 설정
fcOpers://z.array(fcOperSchema).default([]),
z .array(fcOperSchema)
.min(1, { message: "재이용시설의 운영정보를 최소 하나를 등록해주세요" })
});
export const pbnstRegArrayZod = z.array(pbnstRegZod);
@@ -1,8 +1,8 @@
import type { TableUpperProps } from "@/app/store/common/type/header";
import { getFetch, postFectch, putFectch } from "@/components/lib/api";
import { getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import toast from "react-hot-toast";
import { z } from "zod";
import { makeMdfr, makeRstr } from "../bdstReg";
import toast from "react-hot-toast";
import { baseReuseBuildingSchema, chgBuildingSchema, validationMessages } from "./type";
export const TEST_UUID= '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e'
@@ -27,9 +27,9 @@ const rainyObjSchema = z.object({
})
export const rainZod = z.object({
bdstInfoPk: z.number().optional(),
ctpvCd: z.number().default(0),
sggCd: z.number().default(0),
bdstInfoSn: z.number().optional(),
ctpvCd: z.number().optional(),
sggCd: z.number().optional(),
daddr: z.string().default(""),
bdstNm: z.string().default(""),
frstArchPrmsnDt: z.date().default(() => new Date()),
@@ -43,7 +43,7 @@ export const rainZod = z.object({
})
export type chgBuilding={
bdstInfoFk?: number|null,
bdstInfoSn?: number|null,
archChgPrmsnDt?: Date,
archChgArea?: string,
bdstChgNm?: string
@@ -74,6 +74,7 @@ export type rainFacState = {
isInit: boolean;
upHeadList: TableUpperProps[];
rainRes: customRainBdst[];
rainResCount:number;
};
};
type rainFacSActions = {
@@ -82,6 +83,7 @@ type rainFacSActions = {
rainSearch: (txt:string,pageNation:number,code:string|number) => void;
rainBdstReg: (data: customRainBdst, code:string|number) => void;
rainBdstUpdate: (data: customRainBdst, code:string|number) => void;
};
export type rainFacType = rainFacState & rainFacSActions;
@@ -90,12 +92,14 @@ export const rainFacStateExport: rainFacState = {
rain: {
isInit: false,
rainRes: rainRes,
rainResCount:1,
upHeadList: upHeadList,
},
};
const initFetch = async (code:string|number) => {
const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/1/10/${code}`);
// const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/1/10/${code}`);
const rainRes =await getFetchWithCount("wr", `/reuseFc/rainyInfoList/1/10/${code}`);
return rainRes;
};
export const rainFacActionsExport: (set: any) => rainFacSActions = (
@@ -104,15 +108,15 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
return {
getRainData: async(pageNation:number, code:string|number) =>{
try{
const rainRes =await getFetch("wr", `/reuseFc/rainyInfoList/${pageNation}/10/${code}`);
const rainRes =await getFetchWithCount("wr", `/reuseFc/rainyInfoList/${pageNation}/10/${code}`);
// 여기서 상태 업데이트
return set((state: rainFacState) => ({
...state,
rain: {
...state.rain,
rainRes: rainRes,
rainRes: rainRes.data,
rainResCount:rainRes.count,
isInit: false,
},
}));
@@ -132,7 +136,8 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
...state,
rain: {
...state.rain,
rainRes: rainRes,
rainRes: rainRes.data,
rainResCount:rainRes.count,
isInit: false,
},
}));
@@ -143,12 +148,15 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
rainSearch: async(txt:string,pageNation:number) =>{
try{
const rainRes = await getFetch('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:''))
// const rainRes = await getFetch('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:''))
const rainRes = await getFetchWithCount('wr' , `/reuseFc/rainyInfoList/${pageNation}/20/41` +(txt? `/${txt}`:''))
console.log("rainRes", rainRes)
set((state: rainFacState) => {
return {
rain: {
...state.rain,
rainRes: rainRes,
rainRes: rainRes.data,
rainResCount:rainRes.count,
isInit: false,
},
};
@@ -165,11 +173,11 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
if(res.status===200){
if(data.chgBuilding.length > 0){
const chPK = res?.data?.bdstInfoPk
const chPK = res?.data?.bdstInfoSn
const makeCh= res.data.chgBuilding.map((item: chgBuilding) =>
( {
...item,
bdstInfoFk: chPK,
bdstInfoSn: chPK,
})
);
const chch= await postFectch("/reuseFc/chgBuilding", makeCh);
@@ -190,7 +198,8 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
...state,
rain: {
...state.rain,
rainRes: rainRes,
rainRes: rainRes.data,
rainResCount:rainRes.count,
isInit: false,
},
}));
@@ -213,7 +222,8 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
...state,
rain: {
...state.rain,
rainRes: rainRes,
rainRes: rainRes.data,
rainResCount:rainRes.count,
isInit: false,
},
}));
@@ -8,10 +8,13 @@ export const validationMessages = {
};
export const baseReuseBuildingSchema = z.object({
bdstRuseFcltPk: z.number().nullish(),
bdstInfoFk: z.number().nullish(),
bdstRuseFcltSn: z.number().nullish(),
bdstInfoSn: z.number().nullish(),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish(),
instlCst: z
.number()
.max(9_999_999, { message: "최대 9,999,999까지 입력 가능합니다." })
.nullish(),
operMngCd: z.string().optional().default(""),
anlOperCst: z.number().default(0),
instlCstSprtYn: z.string().default("Y"),
@@ -44,7 +47,7 @@ export const baseReuseBuildingSchema = z.object({
});
export const chgBuildingSchema = z.object({
bdstInfoFk: z.number().nullish(),
bdstInfoSn: z.number().nullish(),
archChgPrmsnDt: z.coerce.date({required_error: validationMessages.required("허가일")}),
archChgArea: z.string().default("-"),
bdstChgNm: z.string().min(1, { message: validationMessages.requiredSelect("구분") }),
@@ -55,8 +58,8 @@ export const chgBuildingSchema = z.object({
export const htdflReuseBuildingSchema = z.object({
bdstRuseFcltPk: z.number().nullish(),
bdstInfoFk: z.number().nullish(),
bdstRuseFcltSn: z.number().nullish(),
bdstInfoSn: z.number().nullish(),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish(),
operMngCd: z.string().optional().nullish(),
@@ -1,14 +1,14 @@
import { getFetch, postFectch, putFectch } from "@/components/lib/api";
import { upHeadList, type chgBuilding } from "../rainReg";
import { getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import { upHeadList, type chgBuilding } from "../rainReg";
import type { TableUpperProps } from "@/app/store/common/type/header";
import { z } from "zod";
import { baseReuseBuildingSchema, chgBuildingSchema, validationMessages } from "../rainReg/type";
import { makeMdfr, makeRstr } from "../bdstReg";
import toast from "react-hot-toast";
import { z } from "zod";
import { makeMdfr, makeRstr } from "../bdstReg";
import { baseReuseBuildingSchema, chgBuildingSchema, validationMessages } from "../rainReg/type";
const rswtrObjSchema = z.object({
bdstRuseFcltFk: z.number().nullish(),
bdstRuseFcltSn: z.number().nullish(),
//wtrUsqty: z.number({ required_error: validationMessages.required("물사용량(m³)") }).positive({ message: validationMessages.required("물사용량(m³)") }),
//oblgTrgtWtrUsqty: z.number().nullish().default(0),
orgwtKndCd: z.string({ required_error: validationMessages.requiredSelect("원수 종류") }).min(1, { message: validationMessages.requiredSelect("원수 종류") }),
@@ -29,9 +29,9 @@ import toast from "react-hot-toast";
})
export const rswtZod = z.object({
bdstInfoPk: z.number().nullish(),
ctpvCd: z.number().default(0),
sggCd: z.number().default(0),
bdstInfoSn: z.number().nullish(),
ctpvCd: z.number({ required_error: '시도를 선택하세요.' }),
sggCd: z.number({ required_error: '시군구를 선택하세요.' }),
daddr: z.string().default(""),
bdstNm: z.string().default(""),
frstArchPrmsnDt: z.date().default(() => new Date()),
@@ -57,6 +57,7 @@ export type rswtFacState = {
isInit: boolean;
upHeadList: TableUpperProps[];
rswtRes: customRswtBdst[];
rswtResCount:number;
};
};
type rswtFacSActions = {
@@ -78,11 +79,12 @@ export const rswtFacStateExport: rswtFacState = {
isInit: false,
upHeadList: upHeadList,
rswtRes: rswtRes,
rswtResCount:1,
},
};
const initFetch = async (code: string | number) => {
const rswtRes = await getFetch("wr", `/reuseFc/waterreuseFc/1/10/${code}`);
const rswtRes = await getFetchWithCount("wr", `/reuseFc/waterreuseFc/1/10/${code}`);
return rswtRes;
};
export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
@@ -95,9 +97,9 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
code: string | number
) => {
try {
const rswtRes = await getFetch(
const rswtRes = await getFetchWithCount(
"wr",
`/reuseFc/waterreuseFc/${pageNation}/20/${code}` +
`/reuseFc/waterreuseFc/${pageNation}/10/${code}` +
(txt ? `/${txt}` : "")
);
set((state: rswtFacState) => {
@@ -105,7 +107,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
...state,
rswt: {
...state.rswt,
rswtRes: rswtRes,
rswtRes: rswtRes.data,
rswtResCount:rswtRes.count,
isInit: false,
},
};
@@ -116,7 +119,7 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
},
getRswtBdstData: async (pageNation: number, code: string | number) => {
try {
const rswtRes = await getFetch(
const rswtRes = await getFetchWithCount(
"wr",
`/reuseFc/waterreuseFc/${pageNation}/10/${code}`
);
@@ -126,7 +129,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
...state,
rswt: {
...state.rswt,
rswtRes: rswtRes,
rswtRes: rswtRes.data,
rswtResCount:rswtRes.count,
isInit: false,
},
}));
@@ -141,7 +145,8 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
...state,
rswt: {
...state.rswt,
rswtRes: rswtRes,
rswtRes: rswtRes.data,
rswtResCount:rswtRes.count,
isInit: false,
},
}));
@@ -160,14 +165,15 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
...state,
rswt: {
...state.rswt,
rswtRes: rswtRes,
rswtRes: rswtRes.data,
rswtResCount:rswtRes.count,
isInit: false,
},
}));
}
} catch (errorUpdate) {
toast.error("중수도 건축물 수정 오류입니다. ");
console.error(errorUpdate);
} finally {
}
},
@@ -176,34 +182,37 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
const chData = await makeRstr(data);
const res = await postFectch("/reuseFc/waterreuseFc", chData);
if (res.status===200) {
if(data.chgBuilding.length > 0){
if(data.chgBuilding.length>0 ){
const chPK = res?.data?.bdstInfoPk
const chPK = res?.data?.bdstInfoSn
const makeCh= res.data.chgBuilding.map((item: chgBuilding) =>
( {
...item,
bdstInfoFk: chPK,
bdstInfoSn: chPK,
})
);
const chch= await postFectch("/reuseFc/chgBuilding", makeCh);
if(chch.status ===200) {
toast.success("건축물 등록이 완료되었습니다.");
console.log('chch.status' , chch.status)
toast.success("건축물(중수도) 및 증축/개축/중축 등록이 완료되었습니다.");
}else{
toast.error("건축물 증축/개축/중축 오류입니다.");
toast.error("건축물(중수도 증축/개축/중축 오류입니다.");
}
} else {
toast.success("건축물 등록이 완료되었습니다.");
toast.success("건축물(중수도 등록이 완료되었습니다.");
}
}else{
toast.error("건축물 등록이 완료되었습니다.");
toast.error("건축물(중수도) 등록이 완료하였습니다.");
}
const rainRes = await initFetch(code);
const rswtRes = await initFetch(code);
set((state: rswtFacState) => ({
...state,
rain: {
...state.rswt,
rswtRes: rswtRes,
rswtRes: rswtRes.data,
rswtResCount:rswtRes.count,
isInit: false,
},
}));
@@ -2,13 +2,13 @@ import type { SelectDataType } from "@common/business_components/ui";
import type { customHtdflBdst } from "../../fcltReg/htdflReg";
export const excelHtdflSttnParsing = (
data: customHtdflBdst[],
excel: { data: customHtdflBdst[] },
sidoCode: SelectDataType[],
sggCode: SelectDataType[]
): string[][] => {
const excelExportData: string[][] = [];
data.forEach((item) => {
excel.data.forEach((item) => {
excelExportData.push([
sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "",
sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "",
@@ -105,7 +105,7 @@ export const htdflSttHeadListExport: z.infer<typeof sttnHeadListType> = [
export const htdflSttNodeListExport: CommonTableProps[] = [
{
id: "bdnstInfo",
title: "1.건축물정보",
title: "건축물정보",
visible: true,
row: 1,
rowSpan: 1,
@@ -113,7 +113,7 @@ export const htdflSttNodeListExport: CommonTableProps[] = [
},
{
id: "htdflFcltInfo",
title: "2.온배수 시설현황",
title: "온배수 시설현황",
visible: true,
row: 1,
rowSpan: 1,
@@ -121,11 +121,11 @@ export const htdflSttNodeListExport: CommonTableProps[] = [
},
{
id: "htdflMngInfo",
title: "3.온배수운영현황",
title: "온배수운영현황",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 11,
colSpan: 10,
},
{
@@ -255,7 +255,7 @@ export const htdflSttNodeListExport: CommonTableProps[] = [
{
id: "prcsProcsYn",
title: "처리공정여부",
upName: "prcsProcs",
upName: "htdflMngInfo",
visible: true,
row: 2,
rowSpan: 2,
@@ -1,11 +1,12 @@
import type { CommonTableProps } from "@/app/store/common/type/header";
import { htdflSttHeadListExport, htdflSttNodeListExport } from "./headList";
import type { sttnHeadListType } from "../rainSttn/headList";
import type { z } from "zod";
import { controlHeadView } from "../rainSttn";
import type { customHtdflBdst } from "../../fcltReg/htdflReg";
import { fetchType, getFetch } from "@/components/lib/api";
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { SelectDataType } from "@common/business_components/ui";
import type { z } from "zod";
import type { customHtdflBdst } from "../../fcltReg/htdflReg";
import { controlHeadView } from "../rainSttn";
import type { sttnHeadListType } from "../rainSttn/headList";
import { excelHtdflSttnParsing } from "./excel";
import { htdflSttHeadListExport, htdflSttNodeListExport } from "./headList";
const htdflSttHeadList = htdflSttHeadListExport;
const htdflSttNodeList = htdflSttNodeListExport;
@@ -17,16 +18,16 @@ export type htdflSttnState = {
htdflSttNodeList: CommonTableProps[];
htdflSttnRes: customHtdflBdst[]
excelList: [];
htdflSttnResCount: number;
};
};
type htdflSttnActions = {
initHtdfl: (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
htdflSttnSearch: (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
initHtdfl: (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
htdflSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
htdflChSttnHead: (
headList: z.infer<typeof sttnHeadListType>,
) => void;
@@ -41,12 +42,11 @@ export const htdflSttnStateExport: htdflSttnState = {
htdflSttnRes: [],
excelList: [],
isInit: false,
htdflSttnResCount: 1,
},
};
const initFetch = async (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
const htdflRes = await getFetch(
const initFetch = async (page: number, total: string, con: string, txt: string) => {
const htdflRes = await getFetchWithCount(
"wr",
`/drain/facilityList` +
(page ? `/${page}` : "/1") +
@@ -62,31 +62,44 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = (
set: any
) => {
return {
initHtdfl: async (page: number, total: string, con: string, txt: string,
initHtdfl: async (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const htdflSttnRes = await initFetch(page, total, con, txt, sidoCode, sggCode);
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
htdflSttnRes: htdflSttnRes,
isInit: false,
},
};
});
const htdflSttnRes = await initFetch(page, total, con, txt);
if (isExcel) {
const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode);
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
excelList: htdflExcel,
},
};
});
} else {
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
htdflSttnRes: htdflSttnRes.data,
htdflSttnResCount: htdflSttnRes.count,
isInit: false,
},
};
});
}
} catch (error) {
console.log(error);
}
},
htdflSttnSearch: async (page: number, total: string, con: string, txt: string,
htdflSttnSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
console.log("page", page)
const htdflSttnRes = await getFetch(
const htdflSttnRes = await getFetchWithCount(
fetchType.WR,
`/drain/facilityList` +
(page ? `/${page}` : "/1") +
@@ -95,13 +108,14 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = (
(txt ? `/${txt}` : "")
);
if (Number(total) > 9000) {
if (isExcel) {
const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode);
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
excelList: htdflSttnRes,
excelList: htdflExcel,
},
};
});
@@ -111,7 +125,8 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = (
...state,
htdflSttn: {
...state.htdflSttn,
htdflSttnRes: htdflSttnRes,
htdflSttnRes: htdflSttnRes.data,
htdflSttnResCount: htdflSttnRes.count,
isInit: false,
},
};
@@ -1,4 +1,3 @@
import type { customPbnst } from "../../fcltReg/pbnstReg/type";
export const excelPbnstSttnParsing = (data: any[]): string[][] => {
const excelExportData: string[][] = [];
@@ -13,15 +12,19 @@ export const excelPbnstSttnParsing = (data: any[]): string[][] => {
String(item.gugun ?? ""),
String(item.bscFctNm ?? ""),
String(item.efflWqltStndrdNm ?? ""),
String(item.fctCpc ?? ""),
String(item.tel ?? ""),
String(item.fctCpc ?? ""),
String(item.ruseUtztnFcltNm ?? ""),
String(item.fcltCpct ?? ""),
String(item.splyExtraCpct ?? ""),
String(item.ruseCpct ?? ""),
String(item.usageTotal ?? ""),
String(item.inUsage ?? ""),
String(item.outUsage ?? ""),
String(item.outUsage ?? ""),
String(item.operMthd ?? ""),
String(item.rprtvBzenty ?? ""),
String(item.bgngDt ?? ""),
String(item.endDt ?? ""),
])
})
return excelExportData;
@@ -100,7 +100,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 3,
},
{
id: "operMngCd",
id: "rgnNm",
title: "환경청",
visible: true,
row: 1,
@@ -116,7 +116,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 2,
},
{
id: "bdnstNm",
id: "bscFctNm",
title: "시설명",
visible: true,
row: 1,
@@ -124,7 +124,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "locDiv",
id: "efflWqltStndrdNm",
title: "지역구분",
visible: true,
row: 1,
@@ -148,7 +148,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "rusNm",
id: "ruseUtztnFcltNm",
title: "재이용시설명",
visible: true,
row: 1,
@@ -180,7 +180,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 4,
},
{
id: "a",
id: "rvbsn",
title: "권역",
upName: "catchment",
visible: true,
@@ -189,7 +189,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "aaa",
id: "lgbsn",
title: "단위유역",
upName: "catchment",
visible: true,
@@ -198,7 +198,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "aaaa",
id: "mdmbsn",
title: "중권역",
upName: "catchment",
visible: true,
@@ -207,7 +207,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "cityText",
id: "sido",
title: "시도",
upName: "adminDiv",
visible: true,
@@ -216,7 +216,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "sggText",
id: "gugun",
title: "시군구",
upName: "adminDiv",
visible: true,
@@ -234,7 +234,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "trbt",
id: "splyExtraCpct",
title: "하수처리량(m³/일)",
upName: "rusSup",
visible: true,
@@ -252,7 +252,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "total",
id: "usageTotal",
title: "합계",
upName: "yearResult",
visible: true,
@@ -261,7 +261,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "ithlWtr",
id: "inUsage",
title: "장내용수",
upName: "yearResult",
visible: true,
@@ -270,7 +270,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "othlWtr",
id: "outUsage",
title: "장외용수",
upName: "yearResult",
visible: true,
@@ -279,7 +279,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "mngMeth",
id: "operMthd",
title: "운영방식",
upName: "mngInfo",
visible: true,
@@ -297,7 +297,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "firstDay",
id: "bgngDt",
title: "시작일",
upName: "mngInfo",
visible: true,
@@ -306,7 +306,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [
colSpan: 1,
},
{
id: "LastDay",
id: "endDt",
title: "종료일",
upName: "mngInfo",
visible: true,
@@ -1,15 +1,15 @@
import type { CommonTableProps, TableUpperProps } from "@/app/store/common/type/header";
import type { z } from "zod";
import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList";
import type { FcPrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import type { ReturnType } from "@common/business_components/ui";
import moment from "moment";
import { type z } from "zod";
import type { customPbnst, pubHasuType } from "../../fcltReg/pbnstReg/type";
import { controlHeadView } from "../rainSttn";
import type { sttnHeadListType } from "../rainSttn/headList";
import type { customPbnst, pubHasuType } from "../../fcltReg/pbnstReg/type";
import { excelPbnstSttnParsing } from "./excel";
import type { FcPrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
import type { ReturnType } from "@common/business_components/ui";
import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList";
import type { WaterReuseFacility } from "./type";
import moment from "moment";
const pbnstSttHeadList = pbnSttHeadListExport;
const pbnstSttNodeList = pbnstSttNodeListExport;
@@ -21,13 +21,15 @@ export type pbnstSttnState = {
pbnstSttHeadList: CommonTableProps[];
pbnstSttNodeList: CommonTableProps[];
pbnstDetail: customPbnst;
ruseFcltNodeList:TableUpperProps[]
ruseSplyHeadList:TableUpperProps[]
rusePplHeadList:TableUpperProps[]
ruseGuranteeHeadList:TableUpperProps[]
ruseDmdHeadList:TableUpperProps[]
ruseFcltHeadList:TableUpperProps[]
ruseFcltNodeList: TableUpperProps[]
ruseSplyHeadList: TableUpperProps[]
rusePplHeadList: TableUpperProps[]
ruseGuranteeHeadList: TableUpperProps[]
ruseDmdHeadList: TableUpperProps[]
ruseFcltHeadList: TableUpperProps[]
pbnstSttnResCount:number;
excelList: [];
fclts:string[]
isInit: boolean;
};
};
@@ -35,25 +37,30 @@ export type pbnstSttnState = {
type pbnstSttnActions = {
pbnstChSttnHead: (headList: z.infer<typeof sttnHeadListType>) => void;
pbnstSttnSearch: (
isExcel: boolean,
page: string,
total: string,
reurnValue: ReturnType,
searchNm: string | undefined,
year: string
year: string,
fclts:string[]
) => void;
getFlcts:()=>void;
pbnSttnInit: (
page: string,
total: string,
reurnValue: ReturnType,
year: string
year: string,
flcts:string[]
) => void;
getPbnStnDetail: (pbnstRuseFcltPk: string) => void;
getPbnStnDetail: (pbnstRuseFcltId: string) => void;
pbnNmSearch: (
page: string,
total: string,
reurnValue: ReturnType,
searchNm: string | undefined,
year: string
year: string,
flcts:string[]
) => void;
};
@@ -63,16 +70,18 @@ export const pbnstSttnStateExport: pbnstSttnState = {
pbnstSttn: {
pbnstSttHeadList: pbnstSttHeadList,
pbnstSttNodeList: pbnstSttNodeList,
ruseFcltNodeList:ruseFcltNodeListExport,
ruseSplyHeadList:ruseSplyHeadListExport,
rusePplHeadList:rusePplHeadListExport,
ruseGuranteeHeadList:ruseGuranteeHeadListExport,
ruseDmdHeadList:ruseDmdHeadListExport,
ruseFcltHeadList:ruseFcltHeadListExport,
ruseFcltNodeList: ruseFcltNodeListExport,
ruseSplyHeadList: ruseSplyHeadListExport,
rusePplHeadList: rusePplHeadListExport,
ruseGuranteeHeadList: ruseGuranteeHeadListExport,
ruseDmdHeadList: ruseDmdHeadListExport,
ruseFcltHeadList: ruseFcltHeadListExport,
pbnstSttnRes: [],
pbnstSttnResCount:1,
pbnstDetail: {} as customPbnst,
pbnstSearchData: [],
excelList: [],
fclts:[],
isInit: false,
},
};
@@ -82,99 +91,118 @@ const hasuListFetch = async (
total: string,
reurnValue: ReturnType,
searchNm: string | undefined,
year: string
year: string,
flcts:string[]
) => {
let url = "";
let url = `/prcsFclt/ruseInfo/`;
if (reurnValue.partValue === "A") {
url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${
reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue
url+=`${page}/${total}/${reurnValue.partValue}/${
// reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue
reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue
}/0/1/SW`
} else if (reurnValue.partValue === "R") {
url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${
reurnValue.regionValue
? reurnValue.regionValue
: reurnValue.unitWaterShedValue
? reurnValue.unitWaterShedValue
: reurnValue.middleRegionValue
url += `${page}/${total}/${reurnValue.partValue}/${reurnValue.regionValue
? reurnValue.regionValue
: reurnValue.unitWaterShedValue
? reurnValue.unitWaterShedValue
: reurnValue.middleRegionValue
}/0/1/SW`
} else {
url = `/prcsFclt/info/${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue}/0/1/SW`
} else if( reurnValue.partValue === 'G'){
url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW`
}else{
url += `1/2/A/0/0/1/SW`
}
if( searchNm&& searchNm?.length>0){
url+="/"+searchNm
if (searchNm && searchNm?.length > 0) {
url += "/" + searchNm
}
const pbnList = await getFetch(fetchType.COMMON, url);
const arrayList = pbnList.map((item: pubHasuType) => item.bscFctCd);
console.log(' flcts ' ,flcts)
const pbnList = await postFectch(url, flcts,fetchType.COMMON);
const getRuseList = await postFectch(
`/reuseFc/pubDetailList/${year}`,
arrayList,
flcts,
fetchType.WR
);
const checkWrRegListRes = getRuseList.data;
const data: WaterReuseFacility[] = checkWrRegListRes.map(
(item: FcPrfType) => {
const findData = pbnList.find(
const findData = pbnList.data.find(
(fclt: pubHasuType) =>
fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11)
fclt.bscFctCd === item.pbnstRuseFcltId.substring(0, 11)
);
const usage = item.prfList.reduce(
(acc, cur) => {
acc.inUsage +=
cur.wshwtr +
cur.coolUswtr +
cur.cleanUswtr +
cur.drwtUswtr +
cur.dltnUswtr +
cur.ithlRswtr +
cur.ithlEtcUswtr +
cur.cleanToilUswtr +
cur.resn;
acc.outUsage +=
cur.lndwtr +
cur.hydUswtr +
cur.ugwtChr +
cur.farmUswtr +
cur.rvrKeepUswtr +
cur.indstUswtr;
acc.total = acc.inUsage + acc.outUsage;
if(findData){
return acc;
},
{ total: 0, inUsage: 0, outUsage: 0 }
);
const usage = item.prfList.reduce(
(acc, cur) => {
acc.inUsage +=
cur.wshwtr +
cur.coolUswtr +
cur.cleanUswtr +
cur.drwtUswtr +
cur.dltnUswtr +
cur.ithlRswtr +
cur.ithlEtcUswtr +
cur.cleanToilUswtr +
cur.resn;
acc.outUsage +=
cur.lndwtr +
cur.hydUswtr +
cur.ugwtChr +
cur.farmUswtr +
cur.rvrKeepUswtr +
cur.indstUswtr;
acc.total = acc.inUsage + acc.outUsage;
return acc;
},
{ total: 0, inUsage: 0, outUsage: 0 }
);
console.log('findData ', findData)
return {
rvbsn: findData?.rvbsn ||'-',
lgbsn: findData?.lgbsn||'-',
mdmbsn: findData?.mdmbsn||'-',
rgnNm: findData?.rgnNm||'-',
sido: findData?.sido||'-',
gugun: findData?.gugun||'-',
bscFctNm: findData?.bscFctNm||'-',
efflWqltStndrdNm: findData?.efflWqltStndrdNm||'-',
fctCpc: Number(findData?.fctCpc)||0,
tel: findData?.tel ?? "-",
ruseUtztnFcltNm: item?.ruseUtztnFcltNm||'-',
fcltCpct: item?.fcltCpct||'-',
splyExtraCpct: item?.splyExtraCpct||'-',
ruseCpct: item?.ruseCpct||'-',
pbnstRuseFcltId: item.pbnstRuseFcltId||'-',
usageTotal: usage?.total,
inUsage: usage?.inUsage,
outUsage: usage?.outUsage,
operMthd: item.operList[0]?.operMthd||'-',
rprtvBzenty: item.operList[0]?.rprtvBzenty,
bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "",
endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "",
searchNm: findData?.bscFctNm||'-',
searchPk: findData?.bscFctCd||'-',
prfList: item?.prfList ?? []
};
}
return {
rvbsn: findData?.rvbsn,
lgbsn: findData?.lgbsn,
mdmbsn: findData?.mdmbsn,
rgnNm: findData?.rgnNm,
sido: findData?.sido,
gugun: findData?.gugun,
bscFctNm: findData?.bscFctNm,
efflWqltStndrdNm: findData?.efflWqltStndrdNm,
fctCpc: findData.fctCpc,
tel: findData?.tel ?? "-",
ruseUtztnFcltNm: item.ruseUtztnFcltNm,
fcltCpct: item.fcltCpct,
splyExtraCpct: item.splyExtraCpct,
ruseCpct: item.ruseCpct,
pbnstRuseFcltPk: item.pbnstRuseFcltPk,
usageTotal: usage.total,
inUsage: usage.inUsage,
outUsage: usage.outUsage,
operMthd: item.operList[0]?.operMthd,
rprtvBzenty: item.operList[0]?.rprtvBzenty,
bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "",
endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "",
searchNm: findData.bscFctNm,
searchPk: findData.bscFctCd,
prfList:item?.prfList??[]
};
}
);
).filter(Boolean);
console.log( ' checkWrRegListRes ', getRuseList.data)
console.log( ' data ', data)
return data;
};
@@ -182,6 +210,15 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
set: any
) => {
return {
getFlcts:async ()=>{
const fclts= await getFetch(fetchType.WR,'/reuseFc/pubFc')
return set((state: pbnstSttnState) => ({
pbnstSttn: {
...state.pbnstSttn,
fclts:fclts
},
}));
},
pbnstChSttnHead: async (
headList: z.infer<typeof sttnHeadListType>
): Promise<void> => {
@@ -196,22 +233,28 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
}));
},
pbnstSttnSearch: async (
isExcel: boolean,
page: string,
total: string,
reurnValue: ReturnType,
searchNm: string | undefined,
year: string
year: string,
fclts:string[]
) => {
try {
const pbnstSttnRes = await hasuListFetch(
page,
total,
reurnValue,
searchNm,
year
year,
fclts,
);
console.log("pbnstSttnRes", pbnstSttnRes);
if (Number(total) > 9000) {
// if (Number(total) > 9000) {
if (isExcel) {
const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes);
set((state: pbnstSttnState) => {
return {
@@ -222,44 +265,48 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
},
};
});
} else
} else{
set((state: pbnstSttnState) => {
return {
...state,
pbnstSttn: {
...state.pbnstSttn,
pbnstSttnRes: pbnstSttnRes,
isInit: false,
pbnstSttnResCount:pbnstSttnRes.length
// isInit: false,
},
};
});
}
} catch (erTxt) {
console.log("error", erTxt);
}
},
pbnSttnInit: async (
pbnSttnInit: async(
page: string,
total: string,
reurnValue: ReturnType,
year: string
year: string,
fclts:string[]
) => {
try {
const pbnstSttnRes = await hasuListFetch(
page,
total,
reurnValue,
undefined,
year
);
console.log('pbnstSttnRes ', pbnstSttnRes)
set((state: pbnstSttnState) => {
page,
total,
reurnValue,
undefined,
year,
fclts
);
console.log('pbnstSttnRes ' , pbnstSttnRes)
set( (state: pbnstSttnState) => {
return {
...state,
pbnstSttn: {
...state.pbnstSttn,
pbnstSttnRes: pbnstSttnRes,
pbnstSttnResCount:pbnstSttnRes.length,
isInit: false,
},
};
@@ -268,13 +315,12 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
console.log("error", erTxt);
}
},
getPbnStnDetail: async (pbnstRuseFcltPk: string) => {
getPbnStnDetail: async (pbnstRuseFcltId: string) => {
try {
let pbnstDetail = await getFetch("wr", `/reuseFc/pubFc/${pbnstRuseFcltPk}`);
if(pbnstDetail.length>=0){
pbnstDetail= pbnstDetail.find((item: customPbnst) =>item.pbnstRuseFcltPk === pbnstRuseFcltPk)
let pbnstDetail = await getFetch("wr", `/reuseFc/pubFc/${pbnstRuseFcltId}`);
if (pbnstDetail.length >= 0) {
pbnstDetail = pbnstDetail.find((item: customPbnst) => item.pbnstRuseFcltId === pbnstRuseFcltId)
}
console.log( 'pbnstDetail ', pbnstDetail)
set((state: pbnstSttnState) => {
return {
...state,
@@ -293,17 +339,19 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
total: string,
reurnValue: ReturnType,
searchNm: string | undefined,
year: string
) => {
year: string,
flcts:string[]
) => {
try {
const pbnstSttnRes = await hasuListFetch(
page,
total,
reurnValue,
searchNm,
year
);
const pbnstSttnRes = await hasuListFetch(
page,
total,
reurnValue,
searchNm,
year,
flcts
);
set((state: pbnstSttnState) => {
return {
@@ -311,6 +359,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
pbnstSttn: {
...state.pbnstSttn,
pbnstSearchData: pbnstSttnRes,
pbnstSttnResCount:pbnstSttnRes.length,
},
};
});
@@ -10,7 +10,7 @@ export type WaterReuseFacility = {
lgbsn: string; // 대수계 (예: "한강본류")
mdmbsn: string; // 중권역 (예: "한강서울")
outUsage: number; // 유출량 (예: 900)
pbnstRuseFcltPk: string; // 공공하수 재이용 시설 PK (예: "11000SW001R1")
pbnstRuseFcltId: string; // 공공하수 재이용 시설 PK (예: "11000SW001R1")
rgnNm: string; // 관할 기관명 (예: "한강유역환경청")
ruseCpct: number; // 재이용 가능 용량 (예: 123)
ruseUtztnFcltNm: string; // 재사용 활용 시설명 (예: "난지 재사용")
@@ -2,19 +2,19 @@ import type { SelectDataType } from "@common/business_components/ui";
import type { customRainBdst } from "../../fcltReg/rainReg";
export const excelRainSttnParsing = (
data: customRainBdst[],
excel: { data: customRainBdst[] },
sidoCode: SelectDataType[],
sggCode: SelectDataType[]
): string[][] => {
const excelExportData: string[][] = [];
data.forEach((item) => {
excel.data.forEach((item) => {
excelExportData.push([
sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "",
sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "",
sidoCode.find((sido) => sido.val === item.ctpvCd?.toString())?.text ?? "",
sggCode.find((sgg) => sgg.val === item.sggCd?.toString())?.text ?? "",
item.bdstNm ?? "",
item.daddr ?? "",
String(item.bdstInfoPk ?? ""),
String(item.bdstInfoSn ?? ""),
String(item.frstArchPrmsnDt ?? ""),
String(item.archArea ?? ""),
String(item.chgBuilding.length > 0 ? "Y" : "N"),
@@ -136,7 +136,7 @@ export const rainSttHeadListExport: z.infer<typeof sttnHeadListType> = [
export const rainSttNodeListExport: CommonTableProps[] = [
{
id: "bdnstInfo",
title: "1.건축물정보",
title: "건축물정보",
visible: true,
row: 1,
rowSpan: 1,
@@ -144,7 +144,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [
},
{
id: "rainFcltInfo",
title: "2.빗물이용시설정보",
title: "빗물이용시설정보",
visible: true,
row: 1,
rowSpan: 1,
@@ -152,7 +152,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [
},
{
id: "insenInfo",
title: "3.인센티브 정보",
title: "인센티브 정보",
visible: true,
row: 1,
rowSpan: 1,
@@ -343,7 +343,7 @@ export const rainSttNodeListExport: CommonTableProps[] = [
id: "filtrTrtmfct",
title: "여과등 처리시설",
visible: true,
upName: "insenInfo",
upName: "rainFcltInfo",
row: 2,
rowSpan: 1,
colSpan: 3,
@@ -1,5 +1,5 @@
import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
import { fetchType, getFetch } from "@/components/lib/api";
import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api";
import {
type customRainBdst,
} from "../../fcltReg/rainReg";
@@ -96,15 +96,16 @@ export type rainSttnState = {
rainChkRes: rainChkZodType
excelList: [];
isInit: boolean;
rainSttnResCount: number;
};
};
type rainSttnActions = {
rainSttnInit: (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void
rainSttnSearch: (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
rainSttnInit: (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void
rainSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
rainChSttnHead: (
headList: z.infer<typeof sttnHeadListType>,
) => void;
@@ -123,6 +124,7 @@ export const rainSttnStateExport: rainSttnState = {
rainChkRes: rainChkRes,
excelList: [],
isInit: false,
rainSttnResCount: 1,
},
};
@@ -130,12 +132,12 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = (
set: any
) => {
return {
rainSttnInit: async (page: number, total: string, con: string, txt: string,
rainSttnInit: async (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const rainSttnRes = await getFetch(
const rainSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
@@ -143,33 +145,7 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = (
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
rainSttnRes: rainSttnRes,
isInit: false,
},
};
});
} catch (e) {
console.log(e)
}
},
rainSttnSearch: async (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const rainSttnRes = await getFetch(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (Number(total) > 9000) {
if (isExcel) {
const rainExcel = excelRainSttnParsing(rainSttnRes, sidoCode, sggCode);
set((state: rainSttnState) => {
return {
@@ -180,13 +156,54 @@ export const rainSttnActionsExport: (set: any) => rainSttnActions = (
},
};
});
} else {
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
rainSttnRes: rainSttnRes.data,
isInit: false,
},
};
});
}
} catch (e) {
console.log(e)
}
},
rainSttnSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const rainSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rainExcel = excelRainSttnParsing(rainSttnRes, sidoCode, sggCode);
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
excelList: rainExcel,
rainSttnResCount: rainSttnRes.count,
},
};
});
} else
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
rainSttnRes: rainSttnRes,
rainSttnRes: rainSttnRes.data,
rainSttnResCount: rainSttnRes.count,
isInit: false,
},
};
@@ -1,35 +1,35 @@
import { bdstUsgCd } from "@/app/store/common/code/basicCode";
import type { SelectDataType } from "@common/business_components/ui";
import type { customRswtBdst } from "../../fcltReg/rswtReg";
import { useWrStore } from "@/app/store";
export const excelRSwtSttnParsing = (
data: customRswtBdst[],
excel: { data: customRswtBdst[] },
sidoCode: SelectDataType[],
sggCode: SelectDataType[]
): string[][] => {
const excelExportData: string[][] = [];
data.forEach((item) => {
excel.data.forEach((item) => {
console.log("item", item)
excelExportData.push([
sidoCode.find((sido) => sido.val === item.ctpvCd.toString())?.text ?? "",
sggCode.find((sgg) => sgg.val === item.sggCd.toString())?.text ?? "",
item.bdstNm ?? "",
item.daddr ?? "",
String(item.bdstUsgText ?? ""),
bdstUsgCd.find((cd)=> cd.val === item.reuseBuilding?.[0]?.bdstUsgCd.toString())?.text ?? "", //건축물용도
String(item.frstArchPrmsnDt ?? ""),
String(item.archArea ?? ""),
String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량
String(item.archArea.split('.')[0] === '-1' ? '확인불가' : item.archArea.split('.')[0]),
// String(item.reuseBuilding?.[0]?.rswtrObj.wtrUsqty ?? "0"), //물사용량
String(item.chgBuilding.length > 0 ? "Y" : "N"), //중축・개축・재축여부
String(item.reuseBuilding?.[0]?.lawTrgtYn ?? ""), //법적의무대상여부
String(item.reuseBuilding?.[0]?.rswtrObj.oblgTrgtWtrUsqty ?? ""), //의무대상물사용량
// String(item.reuseBuilding?.[0]?.rswtrObj.oblgTrgtWtrUsqty ?? ""), //의무대상물사용량
String(item.reuseBuilding?.[0]?.instlCmptnDt ?? ""), //설치완료일시
String(item.reuseBuilding?.[0]?.instlCst ?? ""), //설치비용
String(item.reuseBuilding?.[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding?.[0]?.instlCst ?? ""), //설치비용
item.reuseBuilding?.[0]?.rswtrObj?.orgwtKndCd ?? "", //원수종류
String(item.reuseBuilding?.[0]?.rswtrObj.filtrTrtmfctCpct ?? ""), //처리시설용량
String(item.reuseBuilding?.[0]?.rswtrObj?.filtrTrtmfctProcs ?? ""), //주요처리공정
String(item.reuseBuilding?.[0]?.rswtrObj?.filtrTrtmfctUsgCd ?? ""), //이용용도
String(item.reuseBuilding?.[0]?.instlCstSprtYn ?? ""), //설치지원비용여부
String(item.reuseBuilding?.[0]?.instlCstSprtAmt ?? ""), //설치지원비용
String(item.reuseBuilding?.[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding?.[0]?.instlCstSprtAmt ?? ""), //설치지원비용
String(item.reuseBuilding?.[0]?.grntchBdstCertYn ?? ""),
String(item.reuseBuilding?.[0]?.grntchBdstCertYr ?? ""),
String(item.reuseBuilding?.[0]?.grntchBdstCertNo ?? ""),
@@ -38,11 +38,11 @@ export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [
title: "건축면적",
visible: true,
},
{
id: "wtrUsqty",
title: "물사용량",
visible: true,
},
// {
// id: "wtrUsqty",
// title: "물사용량",
// visible: true,
// },
{
id: "chBuildingYn",
title: "중축・개축・재축여부",
@@ -54,12 +54,11 @@ export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [
title: "법적의무대상여부",
visible: true,
},
{
id: "oblgTrgtWtrUsqty",
title: "의무대상물사용량 ",
visible: true,
},
// {
// id: "oblgTrgtWtrUsqty",
// title: "의무대상물사용량 ",
// visible: true,
// },
{
id: "instlCmptnDt",
title: "설치완료일시",
@@ -130,15 +129,15 @@ export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [
export const rswtSttNodeListExport: CommonTableProps[] = [
{
id: "bdnstInfo",
title: "1.건축물정보",
title: "건축물정보",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 12,
colSpan: 10,
},
{
id: "rswtFcltInfo",
title: "2.중수도시설정보",
title: "중수도시설정보",
visible: true,
row: 1,
rowSpan: 1,
@@ -146,7 +145,7 @@ export const rswtSttNodeListExport: CommonTableProps[] = [
},
{
id: "insenInfo",
title: "3.인센티브 정보",
title: "인센티브 정보",
visible: true,
row: 1,
rowSpan: 1,
@@ -229,15 +228,15 @@ export const rswtSttNodeListExport: CommonTableProps[] = [
rowSpan: 2,
colSpan: 1,
},
{
id: "wtrUsqty",
title: "물사용량",
upName: "bdnstInfo",
visible: true,
row: 2,
rowSpan: 2,
colSpan: 1,
},
// {
// id: "wtrUsqty",
// title: "물사용량",
// upName: "bdnstInfo",
// visible: true,
// row: 2,
// rowSpan: 2,
// colSpan: 1,
// },
{
id: "chBuildingYn",
title: "중축・개축・재축여부",
@@ -257,15 +256,15 @@ export const rswtSttNodeListExport: CommonTableProps[] = [
rowSpan: 2,
colSpan: 1,
},
{
id: "oblgTrgtWtrUsqty",
title: "의무대상물사용량",
upName: "bdnstInfo",
visible: true,
row: 2,
rowSpan: 2,
colSpan: 1,
},
// {
// id: "oblgTrgtWtrUsqty",
// title: "의무대상물사용량",
// upName: "bdnstInfo",
// visible: true,
// row: 2,
// rowSpan: 2,
// colSpan: 1,
// },
{
id: "instlCmptnDt",
title: "설치완료일시",
@@ -1,12 +1,12 @@
import type { CommonTableProps } from "@/app/store/common/type/header";
import { fetchType, getFetch } from "@/components/lib/api";
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import type { SelectDataType } from "@common/business_components/ui";
import type { z } from "zod";
import type { customRswtBdst } from "../../fcltReg/rswtReg";
import { controlHeadView } from "../rainSttn";
import type { sttnHeadListType } from "../rainSttn/headList";
import { excelRSwtSttnParsing } from "./excel";
import { rswtSttHeadListExport, rswtSttNodeListExport } from "./headList";
import type { SelectDataType } from "@common/business_components/ui";
@@ -24,16 +24,17 @@ export type rswtSttnState = {
rswtSttNodeList: CommonTableProps[];
excelList: [];
isInit: boolean;
rswtSttnResCount: number;
};
};
type rswtSttnActions = {
rswtSttnInit: (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
rswtSttnSearch: (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
rswtSttnInit: (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
rswtSttnSearch: (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
rswtChSttnHead: (
headList: z.infer<typeof sttnHeadListType>,
) => void;
@@ -48,6 +49,7 @@ export const rswtSttnStateExport: rswtSttnState = {
rswtSttnRes: rswtSttnRes,
excelList: [],
isInit: false,
rswtSttnResCount: 1,
},
};
@@ -57,12 +59,11 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = (
set: any
) => {
return {
rswtSttnInit: async (page: number, total: string, con: string, txt: string,
rswtSttnInit: async (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const rswtSttnRes = await getFetch(
const rswtSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
@@ -70,34 +71,7 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = (
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
rswtSttnRes: rswtSttnRes,
isInit: false,
},
};
});
} catch (e) {
console.log(e)
}
},
rswtSttnSearch: async (page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
console.log("헐", page)
const rswtSttnRes = await getFetch(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (Number(total) > 9000) {
if (isExcel) {
const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode);
set((state: rswtSttnState) => {
return {
@@ -115,7 +89,48 @@ export const rswtSttnActionsExport: (set: any) => rswtSttnActions = (
...state,
rswtSttn: {
...state.rswtSttn,
rswtSttnRes: rswtSttnRes,
rswtSttnRes: rswtSttnRes.data,
rswtSttnResCount: rswtSttnRes.count,
isInit: false,
},
};
});
} catch (e) {
console.log(e)
}
},
rswtSttnSearch: async (isExcel: boolean, page: number, total: string, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const rswtSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, sidoCode, sggCode);
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
excelList: rswtExcel,
},
};
});
} else
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
rswtSttnRes: rswtSttnRes.data,
rswtSttnResCount: rswtSttnRes.count,
isInit: false,
},
};
@@ -1,68 +0,0 @@
import type { TableUpperProps } from "../../common/type/header";
export const matStatHeadListExport :TableUpperProps[]=[
{
id: "시도",
title: "시도",
row:0,
rowSpan:2
},
{
id: "개소",
title: "개소",
row:0,
rowSpan:2
},
{
id: "요구수량",
title: "요구수량",
row:0,
rowSpan:2
},
{
id: "용도",
title: "용도",
row:0,
colSpan:6
},
{
id: "조경용수",
title: "조경용수",
row:1,
},
{
id: "청소화장실용수",
title: "청소화장실용수",
row:1,
},
{
id: "농업용수",
title: "농업용수",
row:1,
},
{
id: "공업용수",
title: "공업용수",
row:1,
},
{
id: "친수용수",
title: "친수용수",
row:1,
},
{
id: "기타",
title: "기타",
row:1,
},
{
id: "사업비",
title: "사업비(천원)",
row:0,
rowSpan:2
},
]
-28
View File
@@ -1,28 +0,0 @@
import type { TableUpperProps } from "../../common/type/header";
import { matStatHeadListExport } from "./headList";
type matStatActions = {
}
export type matStatState = {
matStat: {
matStatHeadList:TableUpperProps[]
}
}
export type matStatType = matStatState & matStatActions;
export const matStatExport: matStatState = {
matStat: {
matStatHeadList:matStatHeadListExport
}
}
export const matStatActionsExport: (set: any) => matStatActions = (
set: any
) => {
return {
}
}
@@ -4,6 +4,7 @@ import { excelRainStat } from "./excel";
import { rainStatHeadListExport } from "./headList";
export type RainStatProps = {
cityText: string
ctpvCd: string //시도
sggCd: string //시군구
areaNm: string //행정구역명
+1 -1
View File
@@ -25,7 +25,7 @@ export const excelRswtStat = (excelList:RswtStatProps[]) : (string | number)[][]
//String(item.instlCst) ?? "",
"",
//건축물면적
item.archArea ?? "",
// item.archArea ?? "",
//처리용량
item.filtrTrtmfctCpct ?? "",
//물사용량
+13 -12
View File
@@ -13,21 +13,22 @@ export const rswtStatHeadListExport :TableUpperProps[]=[
row:0,
rowSpan:2
},
{
id: "a",
title: "시설현황",
row:0,
colSpan:2
},
{
id: "archArea",
title: "건축연면적(m³)",
row:1,
},
// {
// id: "a",
// title: "시설현황",
// row:0,
// colSpan:2
// },
// {
// id: "archArea",
// title: "건축연면적(m³)",
// row:1,
// },
{
id: "filtrTrtmfctCpct",
title: "처리용량(m³)",
row:1,
row:0,
rowSpan:2
},
{
id: "wtrUsqty",
+1 -1
View File
@@ -4,6 +4,7 @@ import { rswtStatHeadListExport } from "./headList";
import { excelRswtStat } from "./excel";
export type RswtStatProps = {
cityText: string //시도명
ctpvCd: string //시도
sggCd : string //시군구
areaNm: string //행정구역명
@@ -72,7 +73,6 @@ export const rswtStatActionsExport: (set: any) => rswtStatActions = (
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) => {
+26 -31
View File
@@ -11,12 +11,19 @@ import {
type comCodeState,
type comCodeType,
} from "./common/code";
import { comFcltSearchAction, comFcltStateExport, type comFcltState, type comFcltType } from "./common/searchCode";
import {
matDmdActionsExport,
matDmdStateExport,
type matDmdState,
type matDmdType,
} from "./matDmd";
import { coRvwActionsExport, coRvwStateExport, type coRvwState, type coRvwType } from "./matDmd/coMatRvw";
import { coSttnActionsExport, coSttnStateExport, type coSttnState, type coSttnType } from "./matDmd/coSttn"; // 옮겨야함
import { drgtActionsExport, drgtStateExport, type drgtState, type drgtType } from "./matDmd/drgtSttn";
import { ldrmntActionsExport, ldrmntStateExport, type ldrmntState, type ldrmntType } from "./matDmd/ldrmntCoSttn";
import { ruseCaseActionsExport, ruseCaseStateExport, type ruseCaseState, type ruseCaseType } from "./matDmd/ruseCaseMng";
import { ruseHstryActionsExport, ruseHstryStateExport, type ruseHstryState, type ruseHstryType } from "./matDmd/ruseRvwHstry";
import {
rainChkgdnActionsExport,
rainChkgdnStateExport,
@@ -29,6 +36,15 @@ import {
type rswtChkgdnState,
type rswtChkgdnType,
} from "./prfmncReg/chkgdnReg/rswrtChkgdn";
import { pbnstPrfmncActionsExport, pbnstPrfmncStateExport, type pbnstPrfmncState, type pbnstPrfmncType } from "./prfmncReg/pbnstPrfmncReg";
import {
rainChkSttnActionsExport,
rainChkSttnStateExport,
type rainChkSttnState,
type rainChkSttnType,
} from "./prfmncSttn/chkgdnSttn/rainChkgdnSttn";
import { rswtChkStateExport, rswtChkSttnActionsExport, type rswtChkSttnState, type rswtChkSttnType } from "./prfmncSttn/chkgdnSttn/rswtChkgdnSttn";
import { pbnstPrfmncSttnActionsExport, pbnstPrfmncSttnExport, type pbnstPrfmncSttnState, type pbnstPrfmncSttnType } from "./prfmncSttn/pbnstPrfmncSttn";
import {
bdstActionsExport,
bdstStateExport,
@@ -59,6 +75,13 @@ import {
type rswtFacState,
type rswtFacType,
} from "./ruseFcltMng/fcltReg/rswtReg";
import {
htdflSttnActionsExport,
htdflSttnStateExport,
type htdflSttnState,
type htdflSttnType,
} from "./ruseFcltMng/fcltSttn/htdflSttn";
import { pbnstSttnActionsExport, pbnstSttnStateExport, type pbnstSttnState, type pbnstSttnType } from "./ruseFcltMng/fcltSttn/pbnstSttn";
import {
rainSttnActionsExport,
rainSttnStateExport,
@@ -71,32 +94,8 @@ import {
type rswtSttnState,
type rswtSttnType,
} from "./ruseFcltMng/fcltSttn/rswtSttn";
import {
htdflSttnActionsExport,
htdflSttnStateExport,
type htdflSttnState,
type htdflSttnType,
} from "./ruseFcltMng/fcltSttn/htdflSttn";
import {
rainChkSttnActionsExport,
rainChkSttnStateExport,
type rainChkSttnState,
type rainChkSttnType,
} from "./prfmncSttn/chkgdnSttn/rainChkgdnSttn";
import { rswtChkStateExport, rswtChkSttnActionsExport, type rswtChkSttnState, type rswtChkSttnType } from "./prfmncSttn/chkgdnSttn/rswtChkgdnSttn";
import { pbnstSttnActionsExport, pbnstSttnStateExport, type pbnstSttnState, type pbnstSttnType } from "./ruseFcltMng/fcltSttn/pbnstSttn";
import { coSttnActionsExport, coSttnStateExport, type coSttnState, type coSttnType } from "./matDmd/coSttn"; // 옮겨야함
import { comFcltStateExport, comFcltSearchAction, type comFcltState, type comFcltType } from "./common/searchCode";
import { pbnstPrfmncActionsExport, pbnstPrfmncStateExport, type pbnstPrfmncState, type pbnstPrfmncType } from "./prfmncReg/pbnstPrfmncReg";
import { coRvwActionsExport, coRvwStateExport, type coRvwState, type coRvwType } from "./matDmd/coMatRvw";
import { ruseHstryActionsExport, ruseHstryStateExport, type ruseHstryState, type ruseHstryType } from "./matDmd/ruseRvwHstry";
import { pbnstPrfmncSttnActionsExport, pbnstPrfmncSttnExport, type pbnstPrfmncSttnState, type pbnstPrfmncSttnType } from "./prfmncSttn/pbnstPrfmncSttn";
import { drgtActionsExport, drgtStateExport, type drgtState, type drgtType } from "./matDmd/drgtSttn";
import { ruseCaseActionsExport, ruseCaseStateExport, type ruseCaseType, type ruseCaseState } from "./matDmd/ruseCaseMng";
import { rainStatActionsExport, rainStatExport, type rainStatState, type rainStatType } from "./stats/rainStat";
import { type rswtStatType, type rswtStatState, rswtStatExport, rswtStatActionsExport } from "./stats/rswtStat";
import { matStatActionsExport, matStatExport, type matStatState, type matStatType } from "./stats/matStat";
import { ldrmntActionsExport, ldrmntStateExport, type ldrmntState, type ldrmntType } from "./matDmd/ldrmntCoSttn";
import { rswtStatActionsExport, rswtStatExport, type rswtStatState, type rswtStatType } from "./stats/rswtStat";
export type WrStore = comCodeType &
pubFacType &
@@ -123,7 +122,6 @@ export type WrStore = comCodeType &
ruseCaseType&
rainStatType&
rswtStatType&
matStatType&
comFcltType
;
@@ -153,8 +151,7 @@ export const StoreZus = (
drgtState&
ruseCaseState&
rainStatState&
rswtStatState&
matStatState
rswtStatState
= {
...comCodeStateExport,
...pubFacStateExport,
@@ -181,7 +178,6 @@ export const StoreZus = (
...ruseCaseStateExport,
...rainStatExport,
...rswtStatExport,
...matStatExport,
...comFcltStateExport
}
) => {
@@ -219,8 +215,7 @@ export const StoreZus = (
...drgtActionsExport(set),
...ruseCaseActionsExport(set),
...rainStatActionsExport(set),
...rswtStatActionsExport(set),
...matStatActionsExport(set)
...rswtStatActionsExport(set)
};
});
};
+16 -4
View File
@@ -1,6 +1,6 @@
//8880
import { CS_URL, DEV_URL_FO, DEV_URL_WR, LOCAL_URL } from "../config/";
import { DEV_URL_FO, DEV_URL_WR, LOCAL_URL } from "../config/";
export const fetchType = { COMMON: "common", WR: "wr", LOCAL: "LOCAL" , CS: "CS" };
@@ -66,11 +66,14 @@ export const getFetchWithCount = async (type: string, url: string) => {
if (!response.ok) {
console.log(`오류 발생: ${response.status}`);
}
const contentType = response.headers.get("content-type") ?? "";
if (contentType.includes("application/json")) {
// JSON 응답 처리
const res = await response.json();
return res;
} else {
// 파일 응답 처리 (ex. PDF, Excel 등)
@@ -105,8 +108,18 @@ export const postFectch = async (url: string, params: any, type?: string) => {
return await response.json();
};
export const putFectch = async (url: string, params: any) => {
const response = await fetch(DEV_URL_WR + url, {
export const putFectch = async (url: string, params: any,type?:string) => {
const div =
type === fetchType.COMMON
? DEV_URL_FO
: type === fetchType.LOCAL
? LOCAL_URL
: type === fetchType.CS
? ''
: DEV_URL_WR;
const response = await fetch(div + url, {
method: "PUT",
headers: {
"Content-Type": "application/json",
@@ -129,7 +142,6 @@ export const deleteFectch = async (url: string, params?: any, type?: string) =>
? ''
: DEV_URL_WR;
console.log("deleteFectch url", div + url);
const response = await fetch(div + url, {
method: "DELETE",
headers: {
+54 -39
View File
@@ -1,15 +1,15 @@
import { numSize } from "@/app/store/common/code/basicCode";
import type { TableUpperProps } from "@/app/store/common/type/header";
import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn";
import { Checkbox, Input, TableCell, TableRow } from "@common/components/ui";
import { useEffect } from "react";
export const rainChkTableData = (chkData: rainChkZodType[]) => {
// 1. chkgdnFk + utztnUsgCd 기준 누계 정보 만들기
// 1. chkgdnSn + utztnUsgCd 기준 누계 정보 만들기
const maketotal = chkData.map((item: rainChkZodType) => {
const selectTotal = item.guideDetails.reduce((acc: any, cur: any) => {
const code = cur.utztnUsgCd;
const fk = cur.chkgdnFk;
const fk = cur.chkgdnSn;
const key = `${fk}_${code}`;
acc[key] = acc[key] || {
@@ -22,7 +22,7 @@ export const rainChkTableData = (chkData: rainChkZodType[]) => {
return acc;
}, {});
return selectTotal; // 모든 키: `${chkgdnFk}_${utztnUsgCd}` 형태
return selectTotal; // 모든 키: `${chkgdnSn}_${utztnUsgCd}` 형태
});
// 2. 누계 정보들을 하나의 객체로 합치기 (평탄화)
@@ -33,7 +33,7 @@ export const rainChkTableData = (chkData: rainChkZodType[]) => {
const updatedRainyDetails: any[] = [];
chkData.forEach((rd: rainChkZodType) => {
rd.rainyDetails.forEach((rainyItem: any) => {
const key = `${rainyItem.chkgdnFk}_${rainyItem.utztnUsgCd}`;
const key = `${rainyItem.chkgdnSn}_${rainyItem.utztnUsgCd}`;
const totals = flatTotalMap[key] || {
totalSplyUswtrUtztnQnt: 0,
totalRuseFcltUtztnQnt: 0,
@@ -53,11 +53,11 @@ export const rainChkTableData = (chkData: rainChkZodType[]) => {
};
export const rswtChkTableData = (chkData: rswtChkZodType[]) => {
// 1. chkgdnFk + utztnUsgCd 기준 누계 정보 만들기
// 1. chkgdnSn + utztnUsgCd 기준 누계 정보 만들기
const makeRswtData: any[] = [];
if(chkData&&chkData.length>0){
if (chkData && chkData.length > 0) {
chkData?.forEach((root) => {
root.rswtrDetails.forEach((detail) => {
@@ -99,10 +99,11 @@ export const chRowspanTable = (
let order = 0
// rowspan된 셀 렌더링 여부 추적용
const renderedMap = new Map<string, Set<number>>();
return (
<>
{makeTableData.map((row, rowIndex) => (
{/* {makeTableData.map((row, rowIndex) => ( */}
{makeTableData && makeTableData.length > 0 ? (makeTableData.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{headList
.map((head) => {
@@ -132,9 +133,9 @@ export const chRowspanTable = (
>
{key === "checkBox" ? (
<Checkbox
checked={selectedIds.includes(row.chkgdnPk)}
checked={selectedIds.includes(row.chkgdnSn)}
onCheckedChange={(checked) =>
toggleSelection(row.chkgdnPk, checked === true)
toggleSelection(row.chkgdnSn, checked === true)
}
></Checkbox>
) : key === "order" ? (
@@ -161,7 +162,14 @@ export const chRowspanTable = (
handleChange(rowIndex, head.id, e.target.value);
}}
value={value || ""}
disabled={!selectedIds.includes(row.chkgdnPk)}
disabled={!selectedIds.includes(row.chkgdnSn)}
maxLength={numSize}
//input type number일때 slice 처리
onInput={(e: React.ChangeEvent<HTMLInputElement>) => {
if (head.type === 'number' && e.target.value.length > numSize) {
e.target.value = e.target.value.slice(0, numSize);
}
}}
/>
) : (
(head.id === "totalSplyUswtrUtztnQnt" || head.id === "totalRuseFcltUtztnQnt" || head.id === "splyUswtrUtztnQnt" || head.id === "ruseFcltUtztnQnt") ? (
@@ -177,7 +185,13 @@ export const chRowspanTable = (
})}
</TableRow>
))}
))) : (
<TableRow>
<TableCell colSpan={headList.length} className="h-24 text-center text-gray-500">
조회된 결과가 없습니다.
</TableCell>
</TableRow>
)}
</>
);
};
@@ -235,44 +249,44 @@ export const InputTableBody = (
}
return span;
};
return (
return (
<>
{chgRes.map((data, dataIndex) => {
// 소계/총합계 행 판별
const isSubTotal = data["용수명"] === "소계";
const isTotal = data["구분"] === 0;
const bgClass = isTotal
? "bg-[#d5e1eb] font-bold"
: isSubTotal
? "bg-[#e6eef5] font-semibold"
: "";
? "bg-[#e6eef5] font-semibold"
: "";
return (
<TableRow key={dataIndex + "row"}>
{headList.map((head, headIndex) => {
// 총합계 행이면 "구분"에서 colSpan=2로 병합
if (
data["구분"] === 0 &&
head.id === "구분"
) {
return (
<TableCell
key={head.id + headIndex}
colSpan={2}
className="font-bold text-center bg-[#d5e1eb]"
>
총합계
</TableCell>
);
}
// 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음
if (
data["구분"] === 0 &&
head.id === "용수명"
) {
return null;
}
// 총합계 행이면 "구분"에서 colSpan=2로 병합
if (
data["구분"] === 0 &&
head.id === "구분"
) {
return (
<TableCell
key={head.id + headIndex}
colSpan={2}
className="font-bold text-center bg-[#d5e1eb]"
>
총합계
</TableCell>
);
}
// 총합계(합계) 행이면 "용수명" 컬럼은 렌더링하지 않음
if (
data["구분"] === 0 &&
head.id === "용수명"
) {
return null;
}
// mergeCell 처리
if (head.mergeCell) {
const rowSpan = getRowSpan(chgRes, head.id, dataIndex);
@@ -292,6 +306,7 @@ export const InputTableBody = (
handleChange(dataIndex, head.id, e.target.value, setInputData)
}
value={data[head.id as keyof any] ?? ""}
maxLength={numSize}
/>
</TableCell>
) : (
+49 -19
View File
@@ -1,29 +1,31 @@
import type { comCodeState } from "@/app/store/common/code";
import {
filePickedBlob,
type SelectDataType,
type ReturnType,
filePickedBlobArray,
type ReturnType,
type SelectDataType,
type SheetParameter,
} from "@common/business_components/ui";
import { Button } from "@common/components/ui";
import type { RefObject } from "react";
import toast from "react-hot-toast";
export const getCity = (val: string, sggCd: SelectDataType[]) => {
let data:any
if(val !=='0'){
let data: any
if (val !== '0') {
data = sggCd
.filter((item) => String(item.val).substring(0, 2) === val)
.map((item) => ({
val: item.val,
text: item.text, // 한국어 텍스트
}));
}else{
.filter((item) => String(item.val).substring(0, 2) === val)
.map((item) => ({
val: item.val,
text: item.text, // 한국어 텍스트
}));
} else {
data = sggCd
.map((item) => ({
val: item.val,
text: item.text, // 한국어 텍스트
}));
.map((item) => ({
val: item.val,
text: item.text, // 한국어 텍스트
}));
}
data.unshift({ val: "0", text: "전체" });
return data;
@@ -92,7 +94,7 @@ export const excelDownload = (
export const excelArrayDownload = (
fileNm: string,
sampleFile: string,
sheetArray:SheetParameter []
sheetArray: SheetParameter[]
) => {
if (!sheetArray) return;
fetch(`/${sampleFile}`, {}).then(async (response) => {
@@ -113,7 +115,7 @@ export const handleCommaNumberChange = (
) => {
const raw = e.target.value.replace(/,/g, "");
if (!/^\d*$/.test(raw)) return;
onChange(raw === "" ? "" : Number(raw));
onChange(raw === "" ? "" : Number(raw));
};
@@ -124,7 +126,7 @@ export const handleMinusNumberChange = (
) => {
const raw = e.target.value.replace(/,/g, "");
if (!/^\d*$/.test(raw)) return;
onChange(raw === "" ? -1 : Number(raw));
onChange(raw === "" ? -1 : Number(raw));
};
// 숫자입력시 , 삽입
@@ -175,14 +177,14 @@ export const getdmdMatFlag = (flag: string | undefined | null) => {
case "Matched":
return "매칭완료";
case "Checked":
return '검토완료';
return '검토완료';
default:
return "신청";
}
};
export const formatPhoneNumber=(tel:string) => {
export const formatPhoneNumber = (tel: string) => {
const onlyNums = tel.replace(/[^0-9]/g, '');
if (onlyNums.length === 10) {
return onlyNums.replace(/(\d{2})(\d{4})(\d{4})/, '$1-$2-$3');
@@ -191,4 +193,32 @@ export const formatPhoneNumber=(tel:string) => {
} else {
return tel; // 유효하지 않으면 빈 문자열
}
}
export const confirmToast = (content: string, saveFunc: () => void) => {
toast((t) => (
<span className="flex flex-col items-center">
<div className="mb-6">
{content}
</div>
<div className="flex flex-row space-x-2">
<Button
size={"sm"}
onClick={() => {
saveFunc();
toast.dismiss(t.id);
}}
>
확인
</Button>
<Button
size={"sm"}
onClick={() => toast.dismiss(t.id)}>취소</Button>
</div>
</span>
),
{
id: "global-confirm-toast", // 중복 토스트 방지
duration: Infinity, // 자동 사라짐 방지
});
}
+34 -10
View File
@@ -1,12 +1,14 @@
import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
import toast from "react-hot-toast";
import {
Upload,
type DetailedError,
type HttpRequest,
type HttpResponse,
type OnSuccessPayload,
type DetailedError,
} from "tus-js-client";
import { CS_TUS_UPLOAD, CS_URL } from "../config";
import type { FilesType } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm";
import { fetchType, putFectch } from "../api";
import { CS_TUS_UPLOAD } from "../config";
type UploadOptions = {
handleUploadStart?: (upload: Upload) => void;
@@ -23,16 +25,14 @@ export type ReturnFileType = {
lnkgDmnId: string | null;
lnkgDmnNm: string | null;
regDt: Date | null;
atflCd: String;
atflCd: string;
atflSn: number;
atflId: String;
physFileNm: String;
atflId: string;
physFileNm: string;
};
export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) =>
new Promise<ReturnFileType>((resolve, reject) => {
try {
const Authorization = "Authorization";
const AUTH_USER_ID = "token-id";
let fileInfo: string | undefined;
//CS_URL
const uploader = new Upload(oFile.file, {
@@ -60,8 +60,30 @@ export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) =>
onSuccess(payload: OnSuccessPayload) {
options?.handleSuccess?.(payload);
if (fileInfo) {
console.log('fileInfo', fileInfo);
resolve(JSON.parse(fileInfo) as ReturnFileType);
const WrTableInfo = {
lnkgDmnNm: "tbWrRuseFcltFile",
lnkgDmnId: "fileTkn",
};
console.log('fileInfo ', fileInfo)
const fileParse = JSON.parse(fileInfo) as ReturnFileType;
putFectch(
`/attach-service/api/v1/atfl/attachments/${fileParse.atflCd}/info`,
WrTableInfo,
fetchType.CS
)
.then(() => {
resolve(fileParse);
})
.catch(() => {
reject({
causingError: {
cause: "파일 업로드 업데이트 실패",
},
} as DetailedError);
});
} else reject({} as DetailedError);
},
});
@@ -71,6 +93,8 @@ export const TusClientUpload = (oFile: FilesType, options?: UploadOptions) =>
} catch (e) {
console.log(e);
reject(e as DetailedError);
toast.error(String(e));
}
// setUpload(uploader);
});

Some files were not shown because too many files have changed in this diff Show More