Merge remote-tracking branch 'origin/iipbs/fo/dev'
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# turbo
|
||||
.turbo/
|
||||
.vscode/**/*
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
@@ -5,7 +5,8 @@ NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
|
||||
#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
|
||||
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
|
||||
#NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
|
||||
NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/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
|
||||
|
||||
+2
-1
@@ -5,7 +5,8 @@ NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
|
||||
#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
|
||||
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
|
||||
#NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
|
||||
NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/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
|
||||
|
||||
@@ -18,7 +18,8 @@ NEXT_PUBLIC_SERVER_API_URL = http://con.mind-one.co.kr:11082/api/v1
|
||||
#NEXT_PUBLIC_SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
NEXT_PUBLIC_WR_SERVER_API_URL = http://con.mind-one.co.kr:11080/api/v1
|
||||
NEXT_PUBLIC_CS_SERVER_API_URL = http://dev.onasys.co.kr:8000
|
||||
NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
|
||||
#NEXT_PUBLIC_GEOSERVER_URL = http://rsone.iptime.org:10010/geoserver
|
||||
NEXT_PUBLIC_GEOSERVER_URL = https://hasudo.geo.rsonesoft.com/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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Gis from "@common/business_components/ui/map/Gis";
|
||||
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { ProcSearchBar } from "@common/business_components/ui/map/searchBar";
|
||||
import { SearchBar } from "@common/business_components/ui/map/searchBar";
|
||||
|
||||
// OpenLayers overlay/extent 유틸
|
||||
import Overlay from "ol/Overlay";
|
||||
@@ -278,7 +278,19 @@ const Map = () => {
|
||||
setIsSearchModalOpen(false);
|
||||
};
|
||||
|
||||
// (선택) 다른 위치 클릭 시 오버레이 닫고 싶다면 Gis 쪽에서 지도 클릭 이벤트 받아 여기서 제거하는 훅을 연결하면 됨.
|
||||
const onInit = () => {
|
||||
|
||||
const map = gisMaps.current;
|
||||
if (!map) {
|
||||
console.warn("지도가 초기화되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (overlayRef.current) {
|
||||
map.removeOverlay?.(overlayRef.current);
|
||||
overlayRef.current = null;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-container">
|
||||
@@ -299,7 +311,7 @@ const Map = () => {
|
||||
onCheckedLayersChange={undefined}
|
||||
imgVisble={false}
|
||||
searchBar={
|
||||
<ProcSearchBar gisMaps={gisMaps} facilityTypes={facilityTypes} />
|
||||
<SearchBar gisMaps={gisMaps} facilityTypes={facilityTypes} onFeatureFocus={undefined} onInit={onInit} />
|
||||
}
|
||||
waterDepth={undefined}
|
||||
/>
|
||||
|
||||
@@ -6,17 +6,21 @@ import ListDiv from "@common/business_components/ui/list_div";
|
||||
import { Table, TableCell, TableHead, TableRow } from "@common/components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
|
||||
export default function SewageOccurModal(props: { fcltyName: string; facilityCd : string; searchYear : string}) {
|
||||
// 그리드 관련
|
||||
const {SewageOccurDetail, searchSewageOccurDetailList} = useFoStore((state) => state);
|
||||
|
||||
// searchYear 유효성 검사 및 기본값 설정
|
||||
const validSearchYear = props.searchYear && /^\d{4}$/.test(props.searchYear) ? props.searchYear : new Date().getFullYear().toString();
|
||||
|
||||
|
||||
const [startYearMonth, setStartYearMonth] = useState(validSearchYear+'01');
|
||||
const [endYearMonth, setEndYearMonth] = useState(validSearchYear+'12');
|
||||
const [detailList, setDetailList] = useState<modalTableType[]>([]);
|
||||
|
||||
// 가능한 시작년월 설정
|
||||
const [enableEndMonth, setEnableEndMonth] = useState<string[]>(['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']);
|
||||
|
||||
const {
|
||||
upHeadListSewageOccurDetail,
|
||||
gridListSewageOccurDetail
|
||||
@@ -33,7 +37,29 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
|
||||
|
||||
useEffect(() => {
|
||||
searchSewageOccurDetailList(props.facilityCd, validSearchYear, startYearMonth, endYearMonth);
|
||||
}, [startYearMonth, endYearMonth]);
|
||||
}, [startYearMonth, endYearMonth, searchSewageOccurDetailList, props.facilityCd, validSearchYear]);
|
||||
|
||||
useEffect(() => {
|
||||
const standdardMonthList = ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']
|
||||
setEnableEndMonth(standdardMonthList);
|
||||
// 시작년월이 바뀌면 선택가능한 년월 데이터가 변경돼야 한다.
|
||||
if(startYearMonth){
|
||||
const startMm = startYearMonth.substring(4, 6);
|
||||
|
||||
if(endYearMonth < startYearMonth) {
|
||||
setEndYearMonth(startYearMonth);
|
||||
}
|
||||
|
||||
standdardMonthList.forEach((month) => {
|
||||
setEnableEndMonth((prev) => {
|
||||
if (parseInt(month.replaceAll('월', '')) < parseInt(startMm)) {
|
||||
return prev.filter((m) => m !== month);
|
||||
}
|
||||
return prev;
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [endYearMonth, startYearMonth]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -63,6 +89,7 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
|
||||
selectClass="ml-5 w-[100px]"
|
||||
startYear={1900}
|
||||
yearReadOnly={true}
|
||||
enableMonth={['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']}
|
||||
/>~
|
||||
<DateMonthPicker
|
||||
field={{
|
||||
@@ -81,6 +108,7 @@ export default function SewageOccurModal(props: { fcltyName: string; facilityCd
|
||||
selectClass="ml-5 w-[100px]"
|
||||
startYear={1900}
|
||||
yearReadOnly={true}
|
||||
enableMonth={enableEndMonth}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
||||
@@ -222,6 +222,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
|
||||
},
|
||||
}));
|
||||
const res = await fetchSewageOccurList(pageNo, pageSize, searchYear, part, nameCd, fcltCpct, operationValue, fcltyNm);
|
||||
const excelDownList: ExcelType[] = [];
|
||||
const data = res.data;
|
||||
// Promise.all을 사용하여 모든 비동기 작업이 완료될 때까지 기다림
|
||||
const calData = await Promise.all(data.map(async (item: SewageOccurProps) => {
|
||||
@@ -301,6 +302,28 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
|
||||
item.estimationSewage = parseFloat((item.waterUsage * (item.swageChangePercent/100)).toFixed(2));
|
||||
return item;
|
||||
}));
|
||||
|
||||
if(pageSize>5000){
|
||||
calData.forEach((item: SewageOccurProps) => {
|
||||
excelDownList.push({
|
||||
시설코드: item.bscFctCd,
|
||||
권역: item.rvbsn,
|
||||
단위유역: item.lgbsn,
|
||||
중권역: item.mdmbsn,
|
||||
환경청: item.rgnNm,
|
||||
시설명: item.bscFctNm,
|
||||
시도: item.sido,
|
||||
시군구: item.sigungo,
|
||||
주소: item.daddr,
|
||||
시설용량: item.fctCpc,
|
||||
물사용량: item.waterUsage,
|
||||
오수전환율: item.swageChangePercent,
|
||||
오수발생량추정: item.estimationSewage,
|
||||
연간하수유입량 : item.sewageInputYear,
|
||||
청천시하수유입량 : item.sewageInputChungchun,
|
||||
});
|
||||
});
|
||||
}
|
||||
// 조회 데이터 설정
|
||||
set((state: any) => ({
|
||||
...state,
|
||||
@@ -311,7 +334,7 @@ export const sewageOccurReducer:(set:any)=>SewageOccurActions=(set: any) => {
|
||||
isLoading : false,
|
||||
}:{
|
||||
...state.SewageOccur,
|
||||
excelList: [],
|
||||
excelList: excelDownList,
|
||||
isLoading : false,
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -26,12 +26,14 @@ interface SearchBarProps {
|
||||
gisMaps: React.RefObject<any>;
|
||||
facilityTypes: { text: string; val: string }[];
|
||||
onFeatureFocus: any;
|
||||
onInit?: any;
|
||||
}
|
||||
|
||||
export const SearchBar = ({
|
||||
gisMaps,
|
||||
facilityTypes,
|
||||
onFeatureFocus,
|
||||
onInit = () => { },
|
||||
}: SearchBarProps) => {
|
||||
const [sidoValue, setSidoValue] = useState("0");
|
||||
const [sigunValue, setSigunValue] = useState("0");
|
||||
@@ -134,10 +136,8 @@ export const SearchBar = ({
|
||||
text: f.properties.swtrmt_fclt_nm ?? "(이름없음)",
|
||||
val: f.id,
|
||||
}));
|
||||
} else if (
|
||||
type === "tb_wr_bdst_ruse_fclt" // 재이용시설
|
||||
) {
|
||||
//재이용에서 참조하는 하수처리시설 목록
|
||||
} else if (type === "tb_wr_bdst_ruse_fclt") {
|
||||
// 재이용시설
|
||||
const procRes = await fetch("/reuse-service/reuseFc/pubFc");
|
||||
const procJson = await procRes.json();
|
||||
const procData = procJson.data;
|
||||
@@ -147,8 +147,8 @@ export const SearchBar = ({
|
||||
return code;
|
||||
});
|
||||
|
||||
//처리시설명으로 처리시설코드 조회
|
||||
let procUrl2 = "/operation-service/prcsFclt/ruseInfo/1/1000/A/{sggCd}/0/1/SW/{fcltyNm}";
|
||||
let procUrl2 =
|
||||
"/operation-service/prcsFclt/ruseInfo/1/1000/A/{sggCd}/0/1/SW/{fcltyNm}";
|
||||
procUrl2 = procUrl2
|
||||
.replace("{sggCd}", sigunValue)
|
||||
.replace("{fcltyNm}", encodeURIComponent(fcltyNm));
|
||||
@@ -161,9 +161,10 @@ export const SearchBar = ({
|
||||
body: JSON.stringify(procResult),
|
||||
});
|
||||
const procJson2 = await procRes2.json();
|
||||
const procResult2 = (procJson2.data || []).map((item: any) => item.bscFctCd);
|
||||
const procResult2 = (procJson2.data || []).map(
|
||||
(item: any) => item.bscFctCd
|
||||
);
|
||||
|
||||
//최종 처리시설코드로 재이용시설조회
|
||||
const res = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -177,20 +178,16 @@ export const SearchBar = ({
|
||||
text: item.ruseUtztnFcltNm ?? "(이름없음)",
|
||||
val: item.pbnstRuseFcltId,
|
||||
}));
|
||||
|
||||
} else if (
|
||||
type === "tb_wr_ruse_fclt_dmd_co" //수요처
|
||||
) {
|
||||
} else if (type === "tb_wr_ruse_fclt_dmd_co") {
|
||||
// 수요처
|
||||
const res = await fetch(url);
|
||||
const json = await res.json();
|
||||
list = (json.data || []).map((item: any) => ({
|
||||
text: item.dmdCoNm ?? "(이름없음)",
|
||||
val: item.dmdInfoId,
|
||||
}));
|
||||
} else if (
|
||||
type === "tb_wr_tmpr_dmd_co" //잠재수요처
|
||||
) {
|
||||
// GET 방식
|
||||
} else if (type === "tb_wr_tmpr_dmd_co") {
|
||||
// 잠재수요처 (GET)
|
||||
const res = await fetch(url);
|
||||
const json = await res.json();
|
||||
list = (json.data || []).map((item: any) => ({
|
||||
@@ -198,7 +195,7 @@ export const SearchBar = ({
|
||||
val: item.fctryMngSn,
|
||||
}));
|
||||
} else {
|
||||
// GET 방식
|
||||
// 기타 (GET)
|
||||
const res = await fetch(url);
|
||||
const json = await res.json();
|
||||
list = (json.data || []).map((item: any) => ({
|
||||
@@ -222,14 +219,12 @@ export const SearchBar = ({
|
||||
setSearchList(newList);
|
||||
};
|
||||
|
||||
//해당 시설물로 이동
|
||||
//해당 시설물로 이동
|
||||
const handleFeatureFocus = (data: any) => {
|
||||
|
||||
let featureId = data.fid;
|
||||
const layerNm = data.layerNm;
|
||||
|
||||
if (!isNaN(Number(featureId))) {
|
||||
// 숫자면 문자열로 변환
|
||||
featureId = String(featureId);
|
||||
}
|
||||
|
||||
@@ -246,12 +241,9 @@ export const SearchBar = ({
|
||||
console.warn("지도가 초기화되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
// 항상 같은 select 객체 사용
|
||||
const select = GisApp.Module.select as any;
|
||||
if (!select) return;
|
||||
// 1. 기존 선택 초기화
|
||||
//select.resetSelectedFeature();
|
||||
// 2. data가 OpenLayers Feature 인스턴스인지 확인
|
||||
|
||||
let foundFeature: any = null;
|
||||
|
||||
map
|
||||
@@ -264,7 +256,7 @@ export const SearchBar = ({
|
||||
if (feature) foundFeature = feature;
|
||||
}
|
||||
});
|
||||
// 3. 피처 선택
|
||||
|
||||
if (foundFeature) {
|
||||
const geometry = foundFeature.getGeometry();
|
||||
if (geometry) {
|
||||
@@ -284,7 +276,28 @@ export const SearchBar = ({
|
||||
console.warn("Feature를 찾을 수 없습니다:", data);
|
||||
}
|
||||
|
||||
onFeatureFocus(foundFeature);
|
||||
if (onFeatureFocus) {
|
||||
onFeatureFocus(foundFeature);
|
||||
}
|
||||
};
|
||||
|
||||
// 초기화(검색 조건 리셋)
|
||||
const handleInit = () => {
|
||||
// 시설 구분 기본값: 단일 항목이면 그 값, 아니면 "0"
|
||||
const defaultFacilityType =
|
||||
facilityTypes?.length === 1 && facilityTypes[0]
|
||||
? facilityTypes[0].val
|
||||
: "0";
|
||||
|
||||
// 시도/시군구/시설구분/시설명/검색목록 초기화
|
||||
setSidoValue("0");
|
||||
initializeSigunData("0"); // 시군구 목록도 "시군구/0"로 리셋되고, sigunValue도 "0"으로 맞춤
|
||||
setFacilityType(defaultFacilityType);
|
||||
setFcltyNm("");
|
||||
setSearchList([]);
|
||||
|
||||
// 필요 시 외부 초기화 콜백 실행
|
||||
onInit?.();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -314,7 +327,9 @@ export const SearchBar = ({
|
||||
selectClass="rounded-lg bg-white"
|
||||
label=""
|
||||
selectArray={sidoData}
|
||||
onSelectValue={(val: any) => onSelectValue(val.toString(), "ctpvCd")}
|
||||
onSelectValue={(val: any) =>
|
||||
onSelectValue(val.toString(), "ctpvCd")
|
||||
}
|
||||
value={sidoValue}
|
||||
/>
|
||||
<SelectBox
|
||||
@@ -323,7 +338,9 @@ export const SearchBar = ({
|
||||
selectClass="rounded-lg bg-white"
|
||||
label=""
|
||||
selectArray={filteredSigunData}
|
||||
onSelectValue={(val: any) => onSelectValue(val.toString(), "sggCd")}
|
||||
onSelectValue={(val: any) =>
|
||||
onSelectValue(val.toString(), "sggCd")
|
||||
}
|
||||
value={sigunValue}
|
||||
/>
|
||||
<SearchInputText
|
||||
@@ -332,7 +349,6 @@ export const SearchBar = ({
|
||||
setFcltyNm(val);
|
||||
}}
|
||||
setRtnData={(selected: { fnm: string; fid: string }) => {
|
||||
// 선택된 항목이 있을 경우 onFeatureSelect 실행
|
||||
const type = facilityType;
|
||||
handleFeatureFocus({
|
||||
layerNm: type,
|
||||
@@ -353,6 +369,16 @@ export const SearchBar = ({
|
||||
>
|
||||
조회
|
||||
</Button>
|
||||
{onInit && (
|
||||
<Button
|
||||
color="primary"
|
||||
className="mx-2 mt-1"
|
||||
size="sm"
|
||||
onClick={handleInit}
|
||||
>
|
||||
초기화
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user