하수도정비기본계획 진행중
This commit is contained in:
+3
-2
@@ -1,6 +1,7 @@
|
||||
NEXT_PUBLIC_SITE_ID = SN
|
||||
NEXT_PUBLIC_PORT = 3002
|
||||
NEXT_PUBLIC_PROXY_HOST = http://con.mind-one.co.kr:11302
|
||||
NEXT_PUBLIC_ADDR_URL = http://con.mind-one.co.kr:11082
|
||||
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 #TODO 운영에서 바꿔야 함
|
||||
@@ -11,5 +12,5 @@ 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 # 최용성 부장님 API
|
||||
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.66:8883/sewerage-service/api # 박이정 차장님 API
|
||||
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.128:8883/sewerage-service/api # 최용성 부장님 API
|
||||
#NEXT_PUBLIC_SEWERAGE_API_URL=http://192.168.1.222:8883/sewerage-service/api # 박이정 차장님 API
|
||||
|
||||
@@ -10,6 +10,8 @@ import { YearRangeSelectBox } from '@/components/ui/YearRangeSelectBox';
|
||||
import { SidoSigunguSelectBox } from '@/components/ui/SidoSigunguSelectBox';
|
||||
import { MsSwagePplCol2, SwtrmtFcltCol2, SwtrmtPrcsZoneCol2, MsSwageMhlCol2, SewagePump2, stofcbrCol2 } from './components/common/table';
|
||||
import LoadingOverlay from '@/components/ui/LoadingBar';
|
||||
import { GovSidoSigunguSearchForm } from '@/components/ui/govSidoSigunguSearchForm';
|
||||
import { useDcTree } from './components/searchModalReportApi';
|
||||
|
||||
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}`;
|
||||
|
||||
@@ -99,9 +101,9 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const [tableCount, setTableCount] = useState<number>(0);
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [basicType, setBasicType] = useState(BASIC_TYPES[0]?.val ?? "");
|
||||
const [시도, set시도] = useState(0);
|
||||
const [시군구, set시군구] = useState(0);
|
||||
const [처리구역, set처리구역] = useState("");
|
||||
const [ctpvCd, setCtpvCd] = useState(0);
|
||||
const [sigungu, setSigungu] = useState(0);
|
||||
const [swageProcessingZone, set처리구역] = useState("");
|
||||
// 날짜 상태 선언
|
||||
const [시작1, set시작1] = useState("");
|
||||
const [시작2, set시작2] = useState("");
|
||||
@@ -176,8 +178,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
set가동개시_종료_월("");
|
||||
set가동개시_시작_일("");
|
||||
set가동개시_종료_일("");
|
||||
set시도(0);
|
||||
set시군구(0);
|
||||
setCtpvCd(0);
|
||||
setSigungu(0);
|
||||
set처리구역("");
|
||||
setYearFilter({
|
||||
시작: "",
|
||||
@@ -226,14 +228,21 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
|
||||
if (cqlFilters.length > 0) queryParams.append('cqlFiter', cqlFilters.join(' and '));
|
||||
|
||||
console.log('API URL:', `${API_URL}/v1/fclts?${queryParams.toString()}`);
|
||||
const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`);
|
||||
console.log('필터링된 API 결과(개수):', res.data.count);
|
||||
console.log('필터링된 API 결과(데이터):', res.data.data);
|
||||
if (activeTab === 'report') {
|
||||
const data = flattenFolders(dcData);
|
||||
console.log('dcTree:', data);
|
||||
setTableData(data || []);
|
||||
setTableCount(data.length || []);
|
||||
} else {
|
||||
console.log('API URL:', `${API_URL}/v1/fclts?${queryParams.toString()}`);
|
||||
const res = await axios.get(`${API_URL}/v1/fclts?${queryParams.toString()}`);
|
||||
console.log('필터링된 API 결과(개수):', res.data.count);
|
||||
console.log('필터링된 API 결과(데이터):', res.data.data);
|
||||
setTableData(res.data.data || []);
|
||||
setTableCount(res.data.count || []);
|
||||
console.log('tableCount 상태 업데이트 후:', res.data.count); // tableCount 로그 추가
|
||||
}
|
||||
|
||||
setTableData(res.data.data || []);
|
||||
setTableCount(res.data.count || []);
|
||||
console.log('tableCount 상태 업데이트 후:', res.data.count); // tableCount 로그 추가
|
||||
setShowTable(true);
|
||||
} catch (err) {
|
||||
console.error('API ERROR:', err);
|
||||
@@ -309,8 +318,8 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
// 하수처리구역용 CQL 필터 생성
|
||||
const zoneCqlFilters = () => {
|
||||
const cqlFilters: string[] = [];
|
||||
if (시도) cqlFilters.push(`ctpv_cd='${시도}'`);
|
||||
if (시군구) cqlFilters.push(`sgg_cd='${시군구}'`);
|
||||
if (ctpvCd) cqlFilters.push(`ctpv_cd='${ctpvCd}'`);
|
||||
if (sigungu) cqlFilters.push(`sgg_cd='${sigungu}'`);
|
||||
if (변수1) cqlFilters.push(`swtrmt_zone_nm ILIKE '%${변수1}%'`);
|
||||
if (변수2) cqlFilters.push(`swtrmt_fclt_nm ILIKE '%${변수2}%'`);
|
||||
return cqlFilters;
|
||||
@@ -430,9 +439,9 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
const reportCqlFilters = () => {
|
||||
const cqlFilters: string[] = [];
|
||||
// 설치년도 범위
|
||||
if (시도) cqlFilters.push(`ctpv_cd='${시도}'`);
|
||||
if (시군구) cqlFilters.push(`sgg_cd='${시군구}'`);
|
||||
if (처리구역) cqlFilters.push(`처리구역='${처리구역}'`);
|
||||
if (ctpvCd) cqlFilters.push(`ctpv_cd='${ctpvCd}'`);
|
||||
if (sigungu) cqlFilters.push(`sgg_cd='${sigungu}'`);
|
||||
if (swageProcessingZone) cqlFilters.push(`swageProcessingZone='${swageProcessingZone}'`);
|
||||
if (변수1) cqlFilters.push(`처리구역코드='${변수1}'`);
|
||||
const startDate = getDateString(
|
||||
yearFilter.시작,
|
||||
@@ -677,13 +686,13 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
<div className="mb-3">
|
||||
<div className="mb-2 flex items-center">
|
||||
<SidoSigunguSelectBox
|
||||
sido={시도}
|
||||
sigungu={시군구}
|
||||
sido={ctpvCd}
|
||||
sigungu={sigungu}
|
||||
onSidoChange={(sidoId) => {
|
||||
set시도(sidoId);
|
||||
set시군구(0);
|
||||
setCtpvCd(sidoId);
|
||||
setSigungu(0);
|
||||
}}
|
||||
onSigunguChange={set시군구}
|
||||
onSigunguChange={setSigungu}
|
||||
/>
|
||||
<Label className="mr-2 w-auto text-xl text-gray-600">
|
||||
하수처리구역명
|
||||
@@ -991,13 +1000,13 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
{/* 시도, 시군구, 하수처리구역 한 줄 */}
|
||||
<div className="mb-6 flex items-center">
|
||||
<SidoSigunguSelectBox
|
||||
sido={시도}
|
||||
sigungu={시군구}
|
||||
sido={ctpvCd}
|
||||
sigungu={sigungu}
|
||||
onSidoChange={(sidoId) => {
|
||||
set시도(sidoId);
|
||||
set시군구(0);
|
||||
setCtpvCd(sidoId);
|
||||
setSigungu(0);
|
||||
}}
|
||||
onSigunguChange={set시군구}
|
||||
onSigunguChange={setSigungu}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
@@ -1008,7 +1017,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
label="하수처리구역"
|
||||
selectArray={처리구역List.map(opt => ({ val: opt.val, text: opt.text }))}
|
||||
onSelectValue={val => set처리구역(String(val))}
|
||||
value={처리구역}
|
||||
value={swageProcessingZone}
|
||||
/>
|
||||
<Input
|
||||
className='!text-xl w-[100px] placeholder:text-center mr-8'
|
||||
@@ -1028,6 +1037,7 @@ const SearchModal: React.FC<SearchModalProps> = ({
|
||||
endLabel=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 조회 버튼 중앙 정렬 */}
|
||||
<div className="absolute bottom-4 right-4 mr-2">
|
||||
<Button className="text-base py-2" onClick={handleSearch}>조회</Button>
|
||||
|
||||
@@ -65,12 +65,6 @@ export type TOilqData = {
|
||||
oilq: number; // 유량
|
||||
}
|
||||
|
||||
export const getDcTree = async () => {
|
||||
const queryString = '';
|
||||
const result = await getDcData(`/api/v1/dc/tree${queryString ? `?${queryString}` : ''}`);
|
||||
return result;
|
||||
};
|
||||
|
||||
const getOptionsAplcnYm = (yyyymms: string[]): { text: string; val: string, hidden?: boolean }[] => {
|
||||
const yyyymms1 = yyyymms.map(dateStr => {
|
||||
const year = dateStr.slice(0, 4);
|
||||
|
||||
@@ -20,7 +20,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
|
||||
const [popupPosition, setPopupPosition] = useState<{ top: number; left: number }>({ top: 0, left: 0 }); // 팝업 위치
|
||||
const [selectedAplcnYm, setSelectedAplcnYm] = useState("");
|
||||
const [inftwtAnlss, setInftwtAnlss] = useState<TInftwtAnls[]>([]);
|
||||
const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState<any[]>([{ val: 0, text: '선택', hidden: true }]); // 침입수분석정보 options
|
||||
const [inftwtAnlsInfos, setInftwtAnlsInfos] = useState<any[]>([{ val: 0, text: '선택' }]); // 침입수분석정보 options
|
||||
const [inftwtAnls, setInftwtAnls] = useState<TInftwtAnls | null>(null); // 침입수분석정보
|
||||
const [selectedInftwtAnls, setSelectedInftwtAnls] = useState<number>(0); // 침입수분석 정보 선택시 사용
|
||||
const [chartData, setChartData] = useState<{ chartData1: DataType[]; chartData2: DataType[] }>({
|
||||
@@ -52,7 +52,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
|
||||
setPopupOpen(true); // 모달이 닫힐 때 조회조건팝업은 열어두기
|
||||
setSelectedAplcnYm(""); // 상수사용월 초기화
|
||||
setInftwtAnlss([]); // 침입수분석 초기화
|
||||
setInftwtAnlsInfos([{ val: 0, text: '선택', hidden: true }]); // 침입수분석정보 초기화
|
||||
setInftwtAnlsInfos([{ val: 0, text: '선택'}]); // 침입수분석정보 초기화
|
||||
setInftwtAnls(null); // 침입수분석정보 초기화
|
||||
setSelectedInftwtAnls(0); // 침입수분석 일련번호 초기화
|
||||
setChartData({ chartData1: [], chartData2: [], }); // 차트 데이터 초기화
|
||||
@@ -72,7 +72,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
|
||||
|
||||
// 빈 값이면 초기화만 하고 종료
|
||||
if (!selectedValue || selectedValue === "0" || selectedValue === "") {
|
||||
setInftwtAnlsInfos([{ val: 0, text: '선택', hidden: true }]);
|
||||
setInftwtAnlsInfos([{ val: 0, text: '선택' }]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ const InfilChart = ({ pplMngNo }: ModalOpenProp) => {
|
||||
} catch (error) {
|
||||
console.error("selectInftwtAnls 에러:", error);
|
||||
setInftwtAnlss([]);
|
||||
setInftwtAnlsInfos([{ val: 0, text: '선택', hidden: true }]);
|
||||
setInftwtAnlsInfos([{ val: 0, text: '선택'}]);
|
||||
}
|
||||
setSelectedInftwtAnls(0);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
import {useState, useEffect} from 'react';
|
||||
import { getDcData } from '@/components/lib/api';
|
||||
import moment from "moment";
|
||||
|
||||
const ADDR_URL = process.env.NEXT_PUBLIC_ADDR_URL;
|
||||
export type SelectDataType = {
|
||||
val: string;
|
||||
text: string;
|
||||
sido?: string; // 시도 코드
|
||||
};
|
||||
|
||||
type Folder = {
|
||||
fldrSn: string;
|
||||
upFldrSn: string;
|
||||
fldrNm: string;
|
||||
sort_seq: number;
|
||||
children: Folder[];
|
||||
};
|
||||
|
||||
type FlattenedFolder = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
// 시군구 데이터
|
||||
const getSggCd = async (): Promise<SelectDataType[]> => {
|
||||
try {
|
||||
const response = await fetch(`${ADDR_URL}/api/v1/addr/sgg`, { method: "GET", headers: { accept: "application/json" } });
|
||||
if (!response.ok) throw new Error(`시군구 데이터 오류: ${response.status}`);
|
||||
const res = await response.json();
|
||||
const sgg = res.data;
|
||||
const sggCd = sgg.map((item: any) => ({
|
||||
val: item.adstDstrCd,
|
||||
sido: item.sido,
|
||||
text: item.gugun,
|
||||
}));
|
||||
sggCd.unshift({ val: '0', text: '전체' }); // "전체" 옵션 추가
|
||||
return sggCd;
|
||||
} catch (error) {
|
||||
console.error('시군구 데이터를 가져오는데 실패했습니다:', error);
|
||||
return [{ val: '0', text: '전체', sido: '0' }];
|
||||
}
|
||||
};
|
||||
|
||||
export const useSggCd = () => {
|
||||
const [data, setData] = useState<SelectDataType[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
const result = await getSggCd();
|
||||
if (result) {
|
||||
setData(result);
|
||||
}
|
||||
};
|
||||
fetch();
|
||||
}, []);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
const isYear = (value: string): boolean => {
|
||||
return /^[0-9]{4}년$/.test(value);
|
||||
};
|
||||
|
||||
function flattenFolders(data: Folder[]): FlattenedFolder[] {
|
||||
const result: FlattenedFolder[] = [];
|
||||
const sggCd = await getSggCd();
|
||||
function traverse(
|
||||
node: Folder,
|
||||
path: { [key: string]: string },
|
||||
level: number
|
||||
) {
|
||||
if (level === 2) {
|
||||
if (!sggCd.some(item => item.text === node.fldrNm)) {
|
||||
}
|
||||
if (isYear(node.fldrNm)) {
|
||||
level++;
|
||||
}
|
||||
}
|
||||
const newPath = {
|
||||
...path,
|
||||
//[`level${level}_fldrSn`]: node.fldrSn,
|
||||
[`level${level}`]: node.fldrNm,
|
||||
};
|
||||
|
||||
if (node.children.length === 0) {
|
||||
result.push(newPath);
|
||||
} else {
|
||||
node.children.forEach((child) => {
|
||||
traverse(child, newPath, level + 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
data.forEach((root) => traverse(root, {}, 0));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export const useDcTree = () => {
|
||||
const [data, setData] = useState<FlattenedFolder[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
const result = await getDcData(`/api/v1/dc/tree`);
|
||||
if (result) {
|
||||
const flattenedData = flattenFolders(result);
|
||||
setData(flattenedData);
|
||||
}
|
||||
};
|
||||
fetch();
|
||||
}, []);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const getDcTree = async () => {
|
||||
const queryString = '';
|
||||
const result = await getDcData(`/api/v1/dc/tree${queryString ? `?${queryString}` : ''}`);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user