Merge branch 'iipbs/sn/dev'

This commit is contained in:
dongsilove
2026-01-30 21:38:13 +09:00
18 changed files with 425 additions and 220 deletions
@@ -30,18 +30,18 @@ export default function CalcRainEffect(data: any, weather = 'ALL') {
rtnDataSunny.push(item);
} else if (rainEffectStd >= 0) { // 강우일 + 강우영향일
item.rainEffectDay = 1;
if (idx > 1) {
// 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정
if (data[idx - 1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx - 1]!.infoRnDay;
}
}
if (idx > 2) {
// 전전날 비가 왔고 오늘 강우량 3미만인 경우 전전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전전날 강우량으로 설정
if (data[idx - 2]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 2]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx - 2]!.infoRnDay;
}
}
if (idx > 1) {
// 전날 비가 왔고 오늘 강우량 3미만인 경우 전날 강우량이 3이상이면 오늘 toBeInfoRnDay을 전날 강우량으로 설정
if (data[idx - 1]?.infoRnDay && Number(data[idx]?.infoRnDay) < 3 && Number(data[idx - 1]?.infoRnDay.toString().trim()) >= 3) {
data[idx]!.toBeInfoRnDay = data[idx - 1]!.infoRnDay;
}
}
rtnDataRain.push(item);
}
@@ -96,7 +96,9 @@ export default function FacilityPrecipitation() {
const [operationValue, setOperationValue] = useState<string>("0");
// 조회기간
const [searchYear, setSearchYear] = useState<string>(defaultSearchYear);
// 엑셀다운로드 트리거
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
/**
* 페이지 함수
*/
@@ -144,6 +146,17 @@ export default function FacilityPrecipitation() {
}, [isInit, initializeCommonData, searchFacilityPrecipitationList, defaultSearchYear]);
useEffect(() => {
if (!isExcelDownClick) return;
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
@@ -151,8 +164,12 @@ export default function FacilityPrecipitation() {
sheetNameArray: ['시설별 강수현황'],
headerRange: 'A1:N1'
});
} else {
alert("조회된 결과가 없습니다.");
}
}, [excelList]);
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
useEffect(() => {
if (facilityPrecipitation.length > 0) {
@@ -196,23 +213,25 @@ export default function FacilityPrecipitation() {
// 엑셀다운로드
const excelDownload = useCallback((searchReturn: ReturnType) => {
if (ref.current.partValue === 'A') { // 행정별
if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'R') { // 유역별
if (!ref.current.regionValue || ref.current.regionValue === '0') {
alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'G') { // 환경청별
if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
return;
}
}
// if (ref.current.partValue === 'A') { // 행정별
// if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
// alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'R') { // 유역별
// if (!ref.current.regionValue || ref.current.regionValue === '0') {
// alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'G') { // 환경청별
// if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
// alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// }
excelWaitRef.current = false;
searchFacilityPrecipitation(searchReturn, 1, 10000);
setIsExcelDownClick(true);
}, [searchFacilityPrecipitation]);
// 페이지 변경
@@ -447,7 +447,9 @@ export default function WaterQualityModal({ fcltyName = '', facilityCd = '', sea
</div>
<div className="card-header border-t mt-1">
<h3 className="text-2xl font-medium text-label">수질 TMS</h3>
<h3 className="text-2xl font-medium text-label text-right">({msrmtDate ? msrmtDate.substring(0, 4) + '-' + msrmtDate.substring(4, 6) + '-' + msrmtDate.substring(6, 8) : yesterDayStr})</h3>
<h3 className="text-2xl font-medium text-label text-right">
({msrmtDate ? msrmtDate.substring(0, 4) + '-' + msrmtDate.substring(4, 6) + '-' + msrmtDate.substring(6, 8) : yesterDayStr})
</h3>
</div>
<div className="overflow-y-auto h-[250px]">
<UiTable
@@ -54,7 +54,9 @@ export default function ProcessFacilitySearch() {
const mainList: FacilityWaterQltyProps[] = facilityWaterQltyList || [];
const [initTrigger, setInitTrigger] = useState<boolean>(false);
const [excelTrigger, setExcelTrigger] = useState<boolean>(false);
// 엑셀다운로드 트리거
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
// 그리드 관련
const [resetPage, setResetPage] = useState<boolean>(false);
const searchInputRef = useRef<HTMLDivElement & HTMLInputElement>(null);
@@ -152,7 +154,16 @@ export default function ProcessFacilitySearch() {
}, [isInit, initializeCommonData, searchFacilityWaterQltyList, searchFcltyQltyList, initTrigger]);
useEffect(() => {
if (!excelTrigger) return;
if (!isExcelDownClick) return;
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcelFormat(
@@ -165,8 +176,12 @@ export default function ProcessFacilitySearch() {
decimalArray3: [13, 14, 18, 19]
}
);
} else {
alert("조회된 결과가 없습니다.");
}
}, [excelList, excelTrigger]);
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
const chkVal = useCallback((returntype: ReturnType) => {
// setWidthSize(returntype.partValue=='A' ?"w-[120%]":"w-[130%]")
@@ -192,8 +207,9 @@ export default function ProcessFacilitySearch() {
}
}
setExcelTrigger(true);
excelWaitRef.current = false;
searchFcltyQltyList(ref.current, 1, 10000);
setIsExcelDownClick(true);
}, [searchFcltyQltyList]);
const handlePageChange = useCallback((page: number) => {
@@ -34,6 +34,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
const { btnClass } = Common;
const [copyYearList, setCopyYearList] = useState<FlowRateModalInterface[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [activeTab, setActiveTab] = useState<string>("tab_term_year");
const prevExcelListRef = useRef<modalExcelType[] | null>(null);
const { modalFlowRateListYear, upHeadListFlowRateModalYear, } = FlowRateModal;
@@ -183,10 +184,6 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
fetchData();
}, [props.facilityCd, props.searchYear, searchFlowRateModalList]);
if (isLoading) {
return <div>로딩 중...</div>;
}
const excelDownload = () => {
const excelDownList: modalExcelType[] = [];
if (copyYearList.length > 0) {
@@ -206,14 +203,45 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
if (excelDownList && excelDownList.length > 0) {
downloadExcel({ data: JSON.parse(JSON.stringify(excelDownList)), fileName: props.searchYear + '년 ' + props.fcltyName + ' 유량현황', sheetNameArray: [props.fcltyName + ' 유량현황'], headerRange: 'A1:H1' });
} else if (prevExcelListRef.current && prevExcelListRef.current.length > 0) {
alert('다운받을 데이터가 없습니다.');
alert('조회된 결과가 없습니다.');
}
prevExcelListRef.current = excelDownList;
}
// const rainCellClassName = useCallback(
// (row: FlowRateModalInterface, headId: string, rowIndex: number) => {
// if (activeTab !== "tab_term_rain") return "";
// if (headId !== "infoRnDay") return "";
// if (rowIndex < 3) return "";
// const raw = row.infoRnDay;
// const value = typeof raw === "string" ? Number(raw.replace(/,/g, "").trim()) : Number(raw);
// if (!Number.isFinite(value)) return "";
// return value > 3 ? "bg-red-50 font-semibold" : "";
// },
// [activeTab],
// );
const rainRowClassName = useCallback(
(row: FlowRateModalInterface, rowIndex: number) => {
if (activeTab !== "tab_term_rain") return "";
if (rowIndex < 3) return "";
const raw = row.infoRnDay;
const value = typeof raw === "string" ? Number(raw.replace(/,/g, "").trim()) : Number(raw);
if (!Number.isFinite(value)) return "";
return value > 3 ? "bg-slate-50" : "";
},
[activeTab],
);
if (isLoading) {
return <div>로딩 중...</div>;
}
return (
<>
<UITab tabList={tabList} defaultValue="tab_term_year">
<UITab tabList={tabList} defaultValue="tab_term_year" onValueChange={setActiveTab}>
<Button className={btnClass} style={{ float: 'right' }} color="green" onClick={excelDownload}>
{"엑셀다운로드"}
</Button>
@@ -337,7 +365,8 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
/>
<div className="h-[370px] overflow-y-auto overflow-x-hidden">
<UiTable headName="유량현황" tableData={copyYearList} headlist={upHeadListFlowRateModalYear} pageSize={0} total={0}
cellClick={undefined} onPageChange={() => { }} className="h-[370px]" boldArray={[0, 1, 2]} />
cellClick={undefined} onPageChange={() => { }} className="h-[370px]" boldArray={[0, 1, 2]}
rowClassName={rainRowClassName} />
</div>
<div className="mt-20">
<UnderComment commentArray={["미처리하수 추정량 산식 =[(강우시 일별유입유량*강우시 일별유입BOD)-(청천시 연평균유입유량*청천시 연평균유입BOD)]/강우시 일별유입BOD)", "강우량 3mm 이상만 날과 강우영향일(강우일+2일)의 날"]} />
@@ -346,4 +375,4 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
</UITab>
</>
);
}
}
@@ -73,6 +73,7 @@ export default function ProcessFacilitySearch() {
const [fcltyNm, setFcltyNm] = useState<string>("");
const [fcltyCd, setFcltyCd] = useState<string>("");
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
const [initTrigger, setInitTrigger] = useState<boolean>(false);
const searchFlowRate = useCallback(({ partValue, regionValue, unitWaterShedValue, middleRegionValue, envPartValue, sidoValue, sigunValue }: ReturnType, pageNo: number, pageCnt:number=20) => {
@@ -154,15 +155,23 @@ export default function ProcessFacilitySearch() {
useEffect(() => {
if(!isExcelDownClick) return;
const timer = setTimeout(() => {
if (excelList && excelList.length > 0) {
downloadExcelFormat({ data: JSON.parse(JSON.stringify(excelList)), fileName: '시설별 유량현황', sheetNameArray: ['시설별 유량현황'], headerRange: 'A1:O1', decimalArray0: [9,10,11,12,13,14] });
} else {
alert('조회된 결과가 없습니다.');
}
}, 1000); // 약간의 지연을 두고 다운로드 실행
return () => clearTimeout(timer);
}, [excelList, isExcelDownClick]);
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcelFormat({ data: JSON.parse(JSON.stringify(excelList)), fileName: '시설별 유량현황', sheetNameArray: ['시설별 유량현황'], headerRange: 'A1:O1', decimalArray0: [9,10,11,12,13,14] });
} else {
alert('조회된 결과가 없습니다.');
}
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
const ref = useRef<ReturnType>({
partValue: '',
@@ -200,6 +209,7 @@ export default function ProcessFacilitySearch() {
}
}
excelWaitRef.current = false;
searchFlowRate(ref.current, 1, 10000);
setIsExcelDownClick(true);
}, [searchFlowRate]);
@@ -93,8 +93,10 @@ export default function PlanSewage() {
const [searchYear, setSearchYear] = useState<string>(defaultSearchYear);
const [initTrigger, setInitTrigger] = useState<boolean>(false);
// 엑셀다운로드 트리거
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
const [excelTrigger, setExcelTrigger] = useState<boolean>(false);
/**
* 페이지 함수
*/
@@ -119,7 +121,16 @@ export default function PlanSewage() {
}
useEffect(() => {
if (!excelTrigger) return;
if (!isExcelDownClick) return;
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({
@@ -128,8 +139,12 @@ export default function PlanSewage() {
sheetNameArray: ['계획하수량 산정지표 현황'],
headerRange: 'A1:M1'
});
} else {
alert("조회된 결과가 없습니다.");
}
}, [excelList, excelTrigger]);
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
/**
* 콜백함수
@@ -200,8 +215,9 @@ export default function PlanSewage() {
}
}
excelWaitRef.current = false;
searchPlanSewage(searchReturn, 1, 10000);
setExcelTrigger(true);
setIsExcelDownClick(true);
}, [searchPlanSewage]);
// 페이지 변경
@@ -70,6 +70,9 @@ export default function ProcessArea() {
const [resetPage, setResetPage] = useState<boolean>(false);
const [searchYearValue, setSearchYearValue] = useState<string>(defaultSearchYear);
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
const ref = useRef<ReturnType>({
partValue: '',
@@ -126,6 +129,17 @@ export default function ProcessArea() {
}, [isInit, initializeCommonData, searchProcessAreaList, defaultSearchYear]);
useEffect(() => {
if(!isExcelDownClick) return;
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
@@ -133,28 +147,34 @@ export default function ProcessArea() {
sheetNameArray: ['처리구역정보'],
headerRange: 'A1:W1'
});
} else {
alert('조회된 결과가 없습니다.');
}
}, [excelList]);
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
const excelDownload = useCallback(() => {
if (ref.current.partValue === 'A') { // 행정별
if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'R') { // 유역별
if (!ref.current.regionValue || ref.current.regionValue === '0') {
alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'G') { // 환경청별
if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
return;
}
}
// if (ref.current.partValue === 'A') { // 행정별
// if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
// alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'R') { // 유역별
// if (!ref.current.regionValue || ref.current.regionValue === '0') {
// alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'G') { // 환경청별
// if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
// alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// }
excelWaitRef.current = false;
searchProcessArea(ref.current, 1, 10000);
setIsExcelDownClick(true);
}, [searchProcessArea]);
const handlePageChange = useCallback((pageNo: number) => {
@@ -89,6 +89,8 @@ export default function ProcessFacilitySearch() {
const [partValue, setPartValue] = useState<string>("A");
// const [widthSize, setWidthSize] = useState<string>("w-[120%]");
const [upHeadList, setUpheadList] = useState(upHeadList1);
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
/**
* 모달 상태 변수
@@ -150,10 +152,25 @@ export default function ProcessFacilitySearch() {
}, [partValue, upHeadList1, upHeadList2, upHeadList3]);
useEffect(() => {
if (!isExcelDownClick) return;
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({ data: excelList as unknown as JSON[], fileName: '처리시설 시설정보', sheetNameArray: ['처리시설 시설정보'], headerRange: 'A1:P1' });
} else {
alert('조회된 결과가 없습니다.');
}
}, [excelList]);
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
const searchFcltyList = useCallback(({ partValue, regionValue, unitWaterShedValue, middleRegionValue, envPartValue, sidoValue, sigunValue }: ReturnType, pageNo: number, pageCnt:number=10) => {
let nameCd, partStr
@@ -236,24 +253,26 @@ export default function ProcessFacilitySearch() {
}
const excelDownload = useCallback(() => {
if (ref.current.partValue === 'A') { // 행정별
if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'R') { // 유역별
if (!ref.current.regionValue || ref.current.regionValue === '0') {
alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'G') { // 환경청별
if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
return;
}
}
// if (ref.current.partValue === 'A') { // 행정별
// if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
// alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'R') { // 유역별
// if (!ref.current.regionValue || ref.current.regionValue === '0') {
// alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'G') { // 환경청별
// if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
// alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// }
excelWaitRef.current = false;
searchFcltyList(ref.current, 1, 10000);
setIsExcelDownClick(true);
}, [searchFcltyList]);
// 모달 닫기
@@ -316,4 +335,4 @@ export default function ProcessFacilitySearch() {
)}
</MainDiv>
);
}
}
+37 -20
View File
@@ -90,7 +90,9 @@ export default function Rdi() {
// 조회기간
const [searchYear, setSearchYear] = useState<string>(defaultSearchYear);
// 엑셀 다운로드 트리거
const [isInitExcelDownload, setIsInitExcelDownload] = useState<boolean>(false);
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
const [initTrigger, setInitTrigger] = useState<boolean>(false);
/**
@@ -118,7 +120,17 @@ export default function Rdi() {
}
useEffect(() => {
if(!isInitExcelDownload) return ;
if(!isExcelDownClick) return ;
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
@@ -126,8 +138,12 @@ export default function Rdi() {
sheetNameArray: ['RDII추정'],
headerRange: 'A1:R1'
});
} else {
alert("조회된 결과가 없습니다.");
}
}, [excelList, isInitExcelDownload]);
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
/**
* 콜백함수
@@ -180,25 +196,26 @@ export default function Rdi() {
// 엑셀다운로드
const excelDownload = useCallback(() => {
if (ref.current.partValue === 'A') { // 행정별
if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'R') { // 유역별
if (!ref.current.regionValue || ref.current.regionValue === '0') {
alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
return;
}
} else if (ref.current.partValue === 'G') { // 환경청별
if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
return;
}
}
// if (ref.current.partValue === 'A') { // 행정별
// if (!ref.current.sidoValue || ref.current.sidoValue === '0') {
// alert('엑셀 다운로드는 시도 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'R') { // 유역별
// if (!ref.current.regionValue || ref.current.regionValue === '0') {
// alert('엑셀 다운로드는 유역 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// } else if (ref.current.partValue === 'G') { // 환경청별
// if (!ref.current.envPartValue || ref.current.envPartValue === '0') {
// alert('엑셀 다운로드는 환경청 조건을 선택한 후 이용 가능합니다.');
// return;
// }
// }
excelWaitRef.current = false;
searchRdi(ref.current, 1, 5000);
setIsInitExcelDownload(true);
setIsExcelDownClick(true);
}, [searchRdi]);
// 페이지 변경
@@ -101,6 +101,7 @@ export default function PlanSewage() {
const [searchYear, setSearchYear] = useState<string>(defaultSearchYear);
// 엑셀다운로드 트리거
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
/**
* 페이지 함수
@@ -151,21 +152,28 @@ export default function PlanSewage() {
useEffect(() => {
if(!isExcelDownClick) return ;
const timer = setTimeout(() => {
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
fileName: '오수발생량 추정',
sheetNameArray: ['오수발생량 추정'],
headerRange: 'A1:O1'
});
} else {
alert("조회된 결과가 없습니다.");
}
}, 500); // 약간의 지연을 두고 다운로드 실행
if (isLoading) {
excelWaitRef.current = true;
return;
}
return () => clearTimeout(timer);
}, [excelList, isInit, isExcelDownClick]);
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
fileName: '오수발생량 추정',
sheetNameArray: ['오수발생량 추정'],
headerRange: 'A1:O1'
});
} else {
alert("조회된 결과가 없습니다.");
}
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
/**
* 콜백함수
@@ -189,7 +197,8 @@ export default function PlanSewage() {
break;
}
if (partStr.length > 1 || fcltCpct !== '0' || operationValue!== '0' ||nameCd ||(fcltyName.trim() !== "" && fcltyName.trim() !== null)) {
searchSewageOccurList(pageNo, pageCnt, searchYear, partStr, nameCd || '0', fcltCpct, operationValue, fcltyName.trim() !== "" || fcltyName.trim() !== null ? fcltyName : undefined);
searchSewageOccurList(pageNo, pageCnt, searchYear, partStr, nameCd || '0', fcltCpct, operationValue
, fcltyName.trim() !== ""? fcltyName : undefined);
} else {
searchSewageOccurList(pageNo, pageCnt, searchYear);
}
@@ -219,6 +228,7 @@ export default function PlanSewage() {
return;
}
}
excelWaitRef.current = false;
searchFacilityPrecipitation(ref.current, 1, 5000);
setIsExcelDownClick(true);
}, [searchFacilityPrecipitation]);
@@ -106,6 +106,7 @@ export default function UnderWaterInput() {
const [searchYear, setSearchYear] = useState<string>(defaultSearchYear);
// 엑셀다운로드 트리거
const [isExcelDownClick, setIsExcelDownClick] = useState<boolean>(false);
const excelWaitRef = useRef<boolean>(false);
/**
* 페이지 함수
@@ -156,20 +157,28 @@ export default function UnderWaterInput() {
useEffect(() => {
if(!isExcelDownClick) return ;
const timer = setTimeout(() => {
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
fileName: '지하수유입량 추정',
sheetNameArray: ['지하수유입량 추정'],
headerRange: 'A1:O1'
});
} else {
alert("조회된 결과가 없습니다.");
}
}, 1000); // 약간의 지연을 두고 다운로드 실행
return () => clearTimeout(timer);
}, [excelList, isExcelDownClick]);
if (isLoading) {
excelWaitRef.current = true;
return;
}
if (!excelWaitRef.current) {
return;
}
if (excelList && excelList.length > 0) {
downloadExcel({
data: excelList as unknown as JSON[],
fileName: '지하수유입량 추정',
sheetNameArray: ['지하수유입량 추정'],
headerRange: 'A1:O1'
});
} else {
alert("조회된 결과가 없습니다.");
}
setIsExcelDownClick(false);
excelWaitRef.current = false;
}, [excelList, isExcelDownClick, isLoading]);
/**
* 콜백함수
@@ -193,7 +202,8 @@ export default function UnderWaterInput() {
break;
}
if (partStr.length > 1 || fcltCpct !== '0' || operationValue!== '0' ||nameCd ||(fcltyName.trim() !== "" && fcltyName.trim() !== null)) {
searchUnderWaterList(pageNo, pageCnt, searchYear, partStr, nameCd || '0', fcltCpct, operationValue, fcltyName.trim() !== "" || fcltyName.trim() !== null ? fcltyName : undefined);
searchUnderWaterList(pageNo, pageCnt, searchYear, partStr, nameCd || '0', fcltCpct, operationValue
, fcltyName.trim() !== ""? fcltyName : undefined);
} else {
searchUnderWaterList(pageNo, pageCnt, searchYear);
}
@@ -223,6 +233,7 @@ export default function UnderWaterInput() {
return;
}
}
excelWaitRef.current = false;
searchFacilityPrecipitation(ref.current, 1, 5000);
setIsExcelDownClick(true);
}, [searchFacilityPrecipitation]);
+31 -23
View File
@@ -28,9 +28,11 @@ export interface FacilityRdiiDetailProps {
export interface FacilityWaterQltyProps {
bscFctCd: string,
bscFctNm: string,
msrDt: string
sidoNm: string,
sggNm: string,
msrDt: string,
sido: string,
gugun: string,
// sidoNm: string,
// sggNm: string,
addr: string,
fctCpc: number,
inflAssctBfrWqltBod: string | '',
@@ -147,8 +149,8 @@ const mainLabelArray: string[] = ['구분', '시도', '시군구', '용량별',
// 시설수질리스트 헤더(행정별)
const upHeadList1: TableUpperProps[] = [
{ id: "C", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 },
{ id: "sidoNm", title: "시도", row: 1, widthPercent: 5 },
{ id: "sggNm", title: "시군구", row: 1, widthPercent: 5 },
{ id: "sido", title: "시도", row: 1, widthPercent: 5 },
{ id: "gugun", title: "시군구", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", rowSpan: 2, row: 0, widthPercent: 10 },
{ id: "addr", title: "주소", rowSpan: 2, row: 0 },
{ id: "fctCpc", title: "시설용량(m³/일)", align: "right", rowSpan: 2, row: 0, widthPercent: 10 },
@@ -197,8 +199,8 @@ const upHeadList3: TableUpperProps[] = [
{ id: "mdmbsn", title: "중권역", row: 1, widthPercent: 5 },
{ id: "rgnNm", title: "환경청", row: 0, rowSpan: 2, widthPercent: 7 },
{ id: "D", title: "행정명", colSpan: 2, row: 0, widthPercent: 10 },
{ id: "sidoNm", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "sggNm", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "sido", title: "시도", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "gugun", title: "시군구", upName: "upChangeRe2", row: 1, widthPercent: 5 },
{ id: "bscFctNm", title: "시설명", row: 0, rowSpan: 2, widthPercent: 8 },
{ id: "addr", title: "주소", row: 0, rowSpan: 2 },
{ id: "fctCpc", title: "시설용량(m³/L)", align: "right", row: 0, rowSpan: 2, widthPercent: 5 },
@@ -466,16 +468,22 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions
//---------
const waterQltyList: any[] = [];
let recordCount = 0;
for (let idx = 0; idx < pageSize; idx += 100) {
const tmpPageNo = Math.floor(idx / 100) + 1;
const tmpPageSize = Math.min(100, pageSize - idx);
const result = await fetchFacilityWaterQltyList(tmpPageNo, tmpPageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
if (result?.status === 200 && Array.isArray(result?.data)) {
waterQltyList.push(...result.data);
}
recordCount = result?.count || 0;
if (result?.count < tmpPageNo * tmpPageSize) {
break; // 더 이상 데이터가 없으면 중지
if (pageSize < 5000) {
const res = await fetchFacilityWaterQltyList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
waterQltyList.push(...res.data);
recordCount = res.count;
} else {
for (let idx = 0; idx < pageSize; idx += 100) {
const tmpPageNo = Math.floor(idx / 100) + 1;
const tmpPageSize = Math.min(100, pageSize - idx);
const result = await fetchFacilityWaterQltyList(tmpPageNo, tmpPageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
if (result?.status === 200 && Array.isArray(result?.data)) {
waterQltyList.push(...result.data);
}
recordCount = result?.count || 0;
if (result?.count < tmpPageNo * tmpPageSize) {
break; // 더 이상 데이터가 없으면 중지
}
}
}
//-------
@@ -527,8 +535,8 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions
waterQltyList.forEach(item => {
dataFormSetting(item)
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
// item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
// item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
item.inflAssctBfrWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.inflAssctBfrWqltToc + ")" : item.inflAssctBfrWqltToc;
item.efflWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.efflWqltToc + ")" : item.efflWqltToc;
excelDownList.push({
@@ -537,8 +545,8 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions
단위유역: item.lgbsn,
중권역: item.mdmbsn,
환경청: item.rgnNm,
시도: item.sidoNm,
시군구: item.sggNm,
시도: item.sido,
시군구: item.gugun,
시설이름: item.bscFctNm,
주소: item.addr,
"시설용량(m³/일)": CommaToNumber(item.fctCpc),
@@ -559,8 +567,8 @@ export const facilityWaterQltyReducer = (set: SetFunc): FacilityWaterQltyActions
waterQltyList.forEach((item: FacilityWaterQltyProps) => {
dataFormSetting(item)
item.fctCpc = parseFloat(item.fctCpc.toString().replace(/,/g, ''));
item.sidoNm = item.lclgvrnmntNm.split(' ')[0]?.toString() || '';
item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
// item.sidoNm = item.;
// item.sggNm = item.lclgvrnmntNm.split(' ')[1]?.toString() || '';
item.inflAssctBfrWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.inflAssctBfrWqltToc + ")" : item.inflAssctBfrWqltToc;
item.efflWqltToc = Number(searchYear) < COD_YEAR ? "(" + item.efflWqltToc + ")" : item.efflWqltToc;
});
+24 -17
View File
@@ -285,23 +285,30 @@ export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => Fl
//---------
const flowRateList: any[] = [];
const results: any[] = [];
for (let idx = 0; idx < pageSize; idx += 100) {
const tmpPageNo = Math.floor(idx / 100) + 1;
const tmpPageSize = Math.min(100, pageSize - idx);
const result = await fetchFlowRateList( tmpPageNo, tmpPageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
results.push(result);
if (result?.count < tmpPageNo * tmpPageSize) {
break; // 더 이상 데이터가 없으면 중지
}
}
console.log(results);
// 결과를 합치기
for (const res of results) {
if (res?.status === 200 && Array.isArray(res?.data)) {
flowRateList.push(...res.data);
if (pageSize < 5000) {
const res = await fetchFlowRateList(pageNo, pageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
flowRateList.push(...res.data);
results.push(res);
} else {
for (let idx = 0; idx < pageSize; idx += 100) {
const tmpPageNo = Math.floor(idx / 100) + 1;
const tmpPageSize = Math.min(100, pageSize - idx);
const result = await fetchFlowRateList( tmpPageNo, tmpPageSize, searchYear, partCd, nameCd, fcltCpct, operationValue, fcltyNm);
results.push(result);
if (result?.count < tmpPageNo * tmpPageSize) {
break; // 더 이상 데이터가 없으면 중지
}
}
// console.log(results);
// 결과를 합치기
for (const res of results) {
if (res?.status === 200 && Array.isArray(res?.data)) {
flowRateList.push(...res.data);
}
}
}
//---------
const recordCount = results[0]?.count || 0;
//-------
@@ -381,7 +388,7 @@ export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => Fl
const yearSunnyAmnt = sunnyDay > 0 ? sunnyInflAmnt / sunnyDay : 0; // 청천시 연평균유입유량
const yearSunnyBod = sunnyDay > 0 ? sunnyBod / sunnyDay : 0; // 청천시 연평균유입BOD
console.log(inflData);
//console.log(inflData);
const rtnData = inflData.map((item: FlowRateModalProps) => {
const targetWqItem = wqltData?.find(wqitem => wqitem.msrDt === item.msrDt.replaceAll('-', ''));
const dayBod = targetWqItem ? Number(targetWqItem.inflAssctBfrWqltBod) : 0;
@@ -397,7 +404,7 @@ export const flowRateSearchReducer: (set: (fn: (state: FlowRateSearchType) => Fl
: item.msrDt,
};
});
console.log(rtnData);
//console.log(rtnData);
set((state: FlowRateSearchType) => ({
...state,
FlowRateModal: {
+3 -1
View File
@@ -418,7 +418,9 @@ const gridListFcltyWaterQltyInfo: fcltyWaterQltyInfoProps[] = [
*/
export const fetchFacilityListInit = async (pageNo: number, pageSize: number, partValue?: string, nameCd?: string, fcltCpct?: string, oprtngSttsCd?: string, facilityPartValue?: string, facilityName?: string): Promise<{ data: facilityListProps[], count: number }> => {
try {
const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd + '/' + facilityPartValue + (facilityName && facilityName !== '' ? '/' + facilityName : '') : '';
const tailStr = partValue ? '/' + (partValue === 'G' ? 'A' : partValue) + '/' + nameCd + '/' + fcltCpct + '/' + oprtngSttsCd
+ (facilityPartValue && facilityPartValue !== ''? '/' + facilityPartValue : '')
+ (facilityName && facilityName !== ''? '/' + facilityName : '') : '';
const url = '/prcsFclt/info/' + pageNo + '/' + pageSize + tailStr;
const res = await getFetch('fo', url);
res.data.forEach((item: Record<string, unknown>) => {
+9 -1
View File
@@ -317,6 +317,14 @@ export type UnderWaterStore = UnderWaterType & UnderWaterActions;
export const underWaterReducer: (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => UnderWaterActions = (set: (fn: (state: UnderWaterType) => UnderWaterType) => void) => {
return {
searchUnderWaterList: async (pageNo: number, pageSize: number, searchYear: string, part?: string, nameCd?: string, fcltCpct?: string, operationValue?: string, fcltyNm?: string) => {
set((state: UnderWaterType) => ({
...state,
UnderWater: {
...state.UnderWater,
isLoading: true,
},
}));
const facilityInitData = await fetchFacilityListInit(pageNo, pageSize, part, nameCd, fcltCpct, operationValue, fcltyNm);
if (pageSize < 5000) {
@@ -724,4 +732,4 @@ export const underWaterReducer: (set: (fn: (state: UnderWaterType) => UnderWater
}))
}
}
}
}
@@ -1,3 +1,4 @@
"use client";
import { createContext, useState } from "react";
interface PromptContext {
@@ -16,14 +16,16 @@ export type ChkClass = {
chk: boolean;
readonly: boolean;
};
type UiTableProps = {
type UiTableProps<T extends object> = {
headName: React.ReactNode | undefined;
tableData: { [key: string]: any }[];
tableData: T[];
headlist: UiHeadProps[];
pageSize: number;
total: number;
cellClick: ((index: number | undefined, headId: string) => void) | undefined;
onPageChange: (page: number) => void;
cellClassName?: (row: T, headId: string, rowIndex: number) => string;
rowClassName?: (row: T, rowIndex: number) => string;
className?: string;
resetPageNo?: boolean;
children?: React.ReactNode | undefined;
@@ -46,7 +48,7 @@ type UiHeadProps = {
colSpan?: number;
};
export function UiTable({
export function UiTable<T extends object = Record<string, unknown>>({
tableData,
headlist,
pageSize,
@@ -55,6 +57,8 @@ export function UiTable({
children,
cellClick,
onPageChange,
cellClassName,
rowClassName,
className = "",
resetPageNo = false,
boldArray = [],
@@ -63,7 +67,7 @@ export function UiTable({
curPage = 1,
headButton = undefined,
widthFixed = false
}: UiTableProps) {
}: UiTableProps<T>) {
const [cur, setCur] = useState<number>(curPage);
const [idx, setIdx] = useState<number>(index);
const [headerHeight, setHeaderHeight] = useState<number>(0);
@@ -148,8 +152,8 @@ export function UiTable({
</TableHeader>
<TableBody className="text-center">
{tableData.length > 0 ? (
tableData?.map((el: Record<string, unknown>, index) => (
<TableRow key={`row-${index}`}>
tableData?.map((el: T, index) => (
<TableRow key={`row-${index}`} className={rowClassName ? rowClassName(el, index) : ""}>
{headlist
.filter((item) => item.visible != false)
.map(
@@ -163,29 +167,32 @@ export function UiTable({
: cellClick
? "cursor-pointer"
: ""
} sticky top-20 z-40 bg-secondary !font-bold whitespace-pre-line`}
} ${cellClassName ? cellClassName(el, head.id, index) : ""} sticky top-20 z-40 bg-secondary !font-bold whitespace-pre-line`}
style={{ top: `${headerHeight + index * 32 - 4}px` }}
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{typeof el[head.id] !== "number"
? String(el[head.id] ?? "")
: String(el[head.id]).includes(".")
? String(el[head.id])
.split(".")
.map((part, index) =>
index === 0
? part.replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)
: part,
)
.join(".")
: String(el[head.id] ?? "").replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)}
{(() => {
const cellValue = (el as Record<string, unknown>)[head.id];
return typeof cellValue !== "number"
? String(cellValue ?? "")
: String(cellValue).includes(".")
? String(cellValue)
.split(".")
.map((part, index) =>
index === 0
? part.replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)
: part,
)
.join(".")
: String(cellValue ?? "").replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
);
})()}
</TableCell>
) : (
<TableCell
@@ -194,47 +201,49 @@ export function UiTable({
: cellClick
? "cursor-pointer"
: ""
} mt-[${boldArray.length * 40}px] whitespace-pre-line`}
} ${cellClassName ? cellClassName(el, head.id, index) : ""} mt-[${boldArray.length * 40}px] whitespace-pre-line`}
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{
//체크박스 유형애서 readOnly가 필요한 경우를 위해서 ChkClass 를 사용해서 readOnly 처리함.
typeof el[head.id] === "object" &&
el[head.id] !== null &&
"chk" in (el[head.id] as object) &&
"readonly" in (el[head.id] as object) ? (
(() => {
const cellValue = (el as Record<string, unknown>)[head.id];
return typeof cellValue === "object" &&
cellValue !== null &&
"chk" in (cellValue as object) &&
"readonly" in (cellValue as object) ? (
<Checkbox
checked={
(el[head.id] as ChkClass)?.chk === true
(cellValue as ChkClass)?.chk === true
}
onCheckedChange={(checked) => {
{
console.log(el[head.id]);
console.log(cellValue);
}
if (
(el[head.id] as ChkClass).readonly == true
(cellValue as ChkClass).readonly == true
)
return;
(el[head.id] as ChkClass).chk =
(cellValue as ChkClass).chk =
Boolean(checked);
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>
) : typeof el[head.id] === "boolean" ? (
) : typeof cellValue === "boolean" ? (
<Checkbox
checked={el[head.id] === true}
checked={cellValue === true}
onCheckedChange={(checked) => {
el[head.id] = checked;
(el as Record<string, unknown>)[head.id] = checked;
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>
) : typeof el[head.id] !== "number" ? (
String(el[head.id] ?? "")
) : String(el[head.id]).includes(".") ? (
String(el[head.id])
) : typeof cellValue !== "number" ? (
String(cellValue ?? "")
) : String(cellValue).includes(".") ? (
String(cellValue)
.split(".")
.map((part, index) =>
index === 0
@@ -246,11 +255,12 @@ export function UiTable({
)
.join(".")
) : (
String(el[head.id] ?? "").replace(
String(cellValue ?? "").replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)
)
);
})()
}
</TableCell>
)),