diff --git a/apps/st/src/components/css/DataGrid.css b/apps/st/src/components/css/DataGrid.css index 68ab82f50..46a1c6304 100644 --- a/apps/st/src/components/css/DataGrid.css +++ b/apps/st/src/components/css/DataGrid.css @@ -27,7 +27,7 @@ } /* 셀 클래스가 있으면 위 기본색보다 우선 (같은 specificity + 나중 규칙) */ .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-readonly { - @apply !bg-[#f0f0f0] !text-[#666]; + @apply !bg-[#f9f8f8] !text-[#666]; } .rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-verify-error { @apply !bg-[#ffe6e6] !text-[#c00]; diff --git a/apps/st/src/components/module/CompactDataGrid.tsx b/apps/st/src/components/module/CompactDataGrid.tsx index b1f97eb14..048c21cec 100644 --- a/apps/st/src/components/module/CompactDataGrid.tsx +++ b/apps/st/src/components/module/CompactDataGrid.tsx @@ -72,6 +72,8 @@ const CompactDataGrid = ({ getGridDataRef, cellStyleCallback, onRowClick, + compactFullWidth = false, + compactGridHeightClass = "h-[65vh]", }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); @@ -313,7 +315,7 @@ const CompactDataGrid = ({ return () => { if (getGridDataRef) getGridDataRef.current = null; }; - }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox, getGridDataRef]); + }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox, getGridDataRef, compactFullWidth, compactGridHeightClass]); // 행 클릭 이벤트 useEffect(() => { @@ -336,8 +338,8 @@ const CompactDataGrid = ({ }, [onRowClick]); return ( -
-
+
+
void; closeDialog: () => void }) => void; + /** 상위 화면 검색 통계연도 — 시설 조회 다이얼로그에 전달 */ + statsYr?: string; +}; + +const GridTopActionButton = ({ text, onClick, statsYr }: GridTopActionButtonProps) => { + const [isOpen, setIsOpen] = useState(false); + const [title, setTitle] = useState(text); + + const openDialog = (nextTitle?: string) => { + setTitle(nextTitle ?? text); + setIsOpen(true); + }; + + const closeDialog = () => setIsOpen(false); + + const handleClick = () => { + if (onClick) { + onClick({ openDialog, closeDialog }); + return; + } + openDialog(text); + }; + + return ( + <> + + + + + {title} + + + + + + ); +}; + +export default GridTopActionButton; diff --git a/apps/st/src/components/module/SearchForm.tsx b/apps/st/src/components/module/SearchForm.tsx index af35891cf..44492a1dd 100644 --- a/apps/st/src/components/module/SearchForm.tsx +++ b/apps/st/src/components/module/SearchForm.tsx @@ -233,7 +233,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
}
- +
+
+ +
+ + {isLoading &&
+
+ +
+
} +
+
+

처리시설 정보

+ +
+
+
+

행정구역 정보

+
+ +
+
+
+ ); +}; + +export default SidoSggFacilityNameSearchForm; diff --git a/apps/st/src/components/module/SplitDataGrid.tsx b/apps/st/src/components/module/SplitDataGrid.tsx index 47ca47012..f275b83a2 100644 --- a/apps/st/src/components/module/SplitDataGrid.tsx +++ b/apps/st/src/components/module/SplitDataGrid.tsx @@ -14,7 +14,7 @@ const SplitDataGrid = ({ enableSort = false, }: SplitDataGridProps) => { return ( -
+
{ +const TabDataGrid = ({ + columnInfo, + isExcelImport = true, + isExcelExport = true, + rows = [], + showHeaderCheckbox = false, + rowDataMap, + setRowDataMap, + activeTab: activeTabProp, + onActiveTabChange, + getGridDataRef, + enableSort = false, + facilitySearchStatsYr, +}: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const activeTabRef = useRef(""); @@ -738,6 +752,11 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r if (info.isSplitGrid && info.left && info.right) { const leftRowData = rowDataMap.get(info.left.tabKey || `${tabKey}_left`) || []; const rightRowData = rowDataMap.get(info.right.tabKey || `${tabKey}_right`) || []; + const splitTopButton = info.right.topButton; + const showSplitTopButton = + Boolean(splitTopButton?.text) && + (splitTopButton?.visible ?? true) && + isExcelImport; // ColumnInfoList를 ColumnInfo로 변환 const leftColumnInfo: ColumnInfo = { @@ -751,6 +770,15 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r return ( +
+ {showSplitTopButton && ( + + )} +
void +) => { + if (statusInfo?.laeSbmsnSttsCd) { + if (["2", "3"].includes(statusInfo.laeSbmsnSttsCd)) { + setIsEnterable(false); + } else { + setIsEnterable(periodEnterable); + } + } else { + setIsEnterable(periodEnterable); + } +}; + +function buildSewagePipeSearchParam( + values: SearchFormValues, + overrides?: { mode?: string }, +): SeweragePipeRequestParams { + return { + statsYr: values.year, + sewerBzmnCd: values.bsnmCd, + ctpvNm: values.sido, + sggNm: values.gugun === "ALL" ? "" : values.gugun, + ...(overrides?.mode ? { mode: overrides.mode } : {}), + }; +} // 하수도 통계 관리 > 02. 하수관로 const SewagePipeInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const { setMessage: alert } = useAlertStore((state) => state); - const [_isLoading, setIsLoading] = useState(false); const [activeTab, setActiveTab] = useState(SewagePipeInpColumnInfoList[0]?.tabKey ?? "ST00020001"); - const [isEnterable, _setIsEnterable] = useState(true); + const [isLoading, setIsLoading] = useState(false); + const [searchValues, setSearchValues] = useState(null); + const [isEnterable, setIsEnterable] = useState(true); + const [lastSearchedYear, setLastSearchedYear] = useState(null); + const [lastSearchedValues, setLastSearchedValues] = useState(null); + const [statusInfo, setStatusInfo] = useState(null); + // const [showDailog, setShowDailog] = useState(false); + // const [isExceptionSubmitFlow, setIsExceptionSubmitFlow] = useState(false); + const [_statsCd, setStatsCd] = useState(''); + /** API 연결 전에도 검색 후 툴바 등 UI를 쓸 수 있게 함 */ + const [hasSearched, setHasSearched] = useState(false); + // const { confirm } = useConfirm(); const { isAdminInfo } = useAdminStore(); + const getGridDataRef = useRef<(() => Record[]) | null>(null); + const searchParamRef = useRef(null); + /** 검색 시 checkInputPeriod 결과 — 탭 전환 지연 조회 시 편집 가능 여부와 동일하게 맞춤 */ + const periodEnterableRef = useRef(true); + /** 검색 완료 후(API 연결 전) 탭별 지연 로그용 — 첫 탭에 행이 없어도 동작하도록 보조 */ + const searchDoneRef = useRef(false); + const lazyTabLoggedRef = useRef>(new Set()); + + const firstTabKey = SewagePipeInpColumnInfoList[0]?.tabKey ?? "ST00020001"; + + const handleReset = () => { + setRowDataMap(new Map()); + setStatusInfo(null); + setLastSearchedYear(null); + setLastSearchedValues(null); + setHasSearched(false); + searchParamRef.current = null; + searchDoneRef.current = false; + lazyTabLoggedRef.current.clear(); + periodEnterableRef.current = true; + setActiveTab(firstTabKey); + }; + const columnInfo = useMemo(() => { const canEdit = isEnterable || isAdminInfo; return SewagePipeInpColumnInfoList.map((tab: ColumnInfoList) => { @@ -46,51 +128,313 @@ const SewagePipeInp = () => { }); }, [isEnterable, isAdminInfo]); - // const handleSearch = async (values: SearchFormValues) => { - // if (!values.sido || values.sido === 'ALL') { - // alert('시도를 선택해주세요.'); - // return; - // } + /** mergeIntoExistingMap: true면 지난연도(PRE) 등 — 현재 탭만 갱신, 나머지 탭 캐시 유지 */ + const loadSewagePipeActiveTabData = async ( + tabKey: string, + searchParam: SeweragePipeRequestParams, + values: SearchFormValues, + checkEnterable: boolean, + mergeIntoExistingMap: boolean, + updateLastSearchedValues: boolean, + ): Promise => { + const applyRowMap = (apply: (m: Map[]>) => void) => { + if (mergeIntoExistingMap) { + setRowDataMap((prev) => { + const next = new Map(prev); + apply(next); + return next; + }); + } else { + const next = new Map[]>(); + apply(next); + setRowDataMap(next); + } + }; - // setActiveTab('ST00020001'); + if (tabKey === 'ST00020001') { + const response = await statisticsInputSewPipeApiService.getRegionalFactStatus(searchParam); + if (response.status === 'success') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.regionalFactStatusList ?? []).map((d) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d, + })); + applyRowMap((m) => m.set('ST00020001', toGridRows(convertedData))); + setStatusInfo(response.data.statusInfo); + setStatsCd(commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable); + if (updateLastSearchedValues) setLastSearchedValues(values); + return true; + } + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + return false; + } + if (tabKey === 'ST00020002') { + const response = await statisticsInputSewPipeApiService.getFactInstallStatus(searchParam); + if (response.status === 'success') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.factInstallStatusList ?? []).map((d) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d, + })); + applyRowMap((m) => m.set('ST00020002', toGridRows(convertedData))); + setStatusInfo(response.data.statusInfo); + setStatsCd(commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable); + if (updateLastSearchedValues) setLastSearchedValues(values); + return true; + } + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + return false; + } + if (tabKey === 'ST00020003') { + const response = await statisticsInputSewPipeApiService.getPipeTypeStatus(searchParam); + if (response.status === 'success') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.pipeTypeStatusList ?? []).map((d) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d, + })); + applyRowMap((m) => m.set('ST00020003', toGridRows(convertedData))); + setStatusInfo(response.data.statusInfo); + setStatsCd(commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable); + if (updateLastSearchedValues) setLastSearchedValues(values); + return true; + } + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + return false; + } + if (tabKey === 'ST00020004') { + const response = await statisticsInputSewPipeApiService.getPipeDiameterStatus(searchParam); + if (response.status === 'success') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.pipeDiameterStatusList ?? []).map((d) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d, + })); + applyRowMap((m) => m.set('ST00020004', toGridRows(convertedData))); + setStatusInfo(response.data.statusInfo); + setStatsCd(commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable); + if (updateLastSearchedValues) setLastSearchedValues(values); + return true; + } + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + return false; + } + if (tabKey === 'ST00020005') { + const response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam); + if (response.status === 'success') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.manholeStatusList ?? []).map((d) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d, + })); + applyRowMap((m) => m.set('ST00020005', toGridRows(convertedData))); + setStatusInfo(response.data.statusInfo); + setStatsCd(commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable); + if (updateLastSearchedValues) setLastSearchedValues(values); + return true; + } + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + return false; + } + if (tabKey === 'ST00020006') { + const response = await statisticsInputSewPipeApiService.getConnectionStatus(searchParam); + if (response.status === 'success') { + const commonInfo = response.data.commonInfo; + const facilityConvertedData = (response.data.facilityConnectionList ?? []).map((d) => ({ + ...d, + })); + const adminConvertedData = (response.data.adminAreaConnectionList ?? []).map((d) => ({ + ...d, + ctpvNm: d.ctpvNm || commonInfo.ctpvNm, + })); + applyRowMap((m) => { + m.set('treatmentPlantConnectionInp', toGridRows(facilityConvertedData)); + m.set('adminAreaConnectionInp', toGridRows(adminConvertedData)); + }); + setStatusInfo(response.data.statusInfo); + setStatsCd(commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, checkEnterable, setIsEnterable); + if (updateLastSearchedValues) setLastSearchedValues(values); + return true; + } + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + return false; + } + if (!mergeIntoExistingMap) { + setRowDataMap(new Map()); + } + if (updateLastSearchedValues) setLastSearchedValues(values); + applyEnterableFromStatus(null, checkEnterable, setIsEnterable); + return true; + }; - // setRowDataMap(new Map()); + const handleSearch = async (values: SearchFormValues) => { + if (!values.sido || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } - // try { - // setIsLoading(true); + try { + const periodResponse = await statisticsInputSewSupplyRateApi.checkInputPeriod(values.year || ''); - // // const searchParam: SewagePipeReviewRequestParams = { - // // statsYr: values.year, - // // sewerBzmnCd: values.bsnmCd, - // // ctpvNm: values.sido, - // // sggNm: values.gugun === 'ALL' ? '' : values.gugun - // // }; + if (periodResponse.status !== 'success') { + alert(periodResponse.message); + return; + } - // // searchParamRef.current = searchParam; - // // const response = await statisticsManagementApi.getSewagePipeReviewRegionalList(searchParam); + const checkEnterable = periodResponse.data; + periodEnterableRef.current = checkEnterable; - // // if (response?.status === 'success' && response.data) { - // // const newRowDataMap = new Map[]>(); - // // newRowDataMap.set('ST00020001', toGridRows(response.data as object[])); - // // setRowDataMap(newRowDataMap); - // // } else { - // // alert(response?.message || "데이터가 없습니다."); - // // } - // } catch { - // alert('데이터 조회 중 오류가 발생했습니다.'); - // } finally { - // setIsLoading(false); - // } - // }; + setRowDataMap(new Map()); + lazyTabLoggedRef.current.clear(); + + setIsLoading(true); + + const searchParam = buildSewagePipeSearchParam(values); + searchParamRef.current = searchParam; + searchDoneRef.current = true; + setHasSearched(true); + setLastSearchedYear(values.year ?? null); + + await loadSewagePipeActiveTabData(activeTab, searchParam, values, checkEnterable, false, true); + } catch { + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + }; + + const handleActiveTabChange = async (tabKey: string) => { + setActiveTab(tabKey); + + const activeTabData = rowDataMap.get(tabKey); + const hasActiveTabData = Array.isArray(activeTabData) && activeTabData.length > 0; + + const canLazyLoad = + searchParamRef.current && + !hasActiveTabData && + !lazyTabLoggedRef.current.has(tabKey) && + searchDoneRef.current; + + if (!canLazyLoad) return; + + const searchParam = searchParamRef.current; + if (!searchParam) return; + + try { + setIsLoading(true); + + let response; + + if (tabKey === 'ST00020001') { + response = await statisticsInputSewPipeApiService.getRegionalFactStatus(searchParam); + } else if (tabKey === 'ST00020002') { + response = await statisticsInputSewPipeApiService.getFactInstallStatus(searchParam); + } else if (tabKey === 'ST00020003') { + response = await statisticsInputSewPipeApiService.getPipeTypeStatus(searchParam); + } else if (tabKey === 'ST00020004') { + response = await statisticsInputSewPipeApiService.getPipeDiameterStatus(searchParam); + } else if (tabKey === 'ST00020005') { + response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam); + } else if (tabKey === 'ST00020006') { + response = await statisticsInputSewPipeApiService.getConnectionStatus(searchParam); + } + lazyTabLoggedRef.current.add(tabKey); + + if (response?.status === 'success') { + setStatusInfo(response.data.statusInfo); + setStatsCd(response.data.commonInfo.statsCd); + applyEnterableFromStatus(response.data.statusInfo, periodEnterableRef.current, setIsEnterable); + setRowDataMap(prev => { + const next = new Map(prev); + if (tabKey === 'ST00020001') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.regionalFactStatusList ?? []).map((d: SeweragePipeInputRegionalFactStatusItem) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d + })); + next.set(tabKey, toGridRows(convertedData)); + } else if (tabKey === 'ST00020002') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.factInstallStatusList ?? []).map((d: SeweragePipeInputFactInstallStatusItem) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d + })); + next.set(tabKey, toGridRows(convertedData)); + } else if (tabKey === 'ST00020003') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.pipeTypeStatusList ?? []).map((d: SeweragePipeInputPipeTypeStatusItem) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d + })); + next.set(tabKey, toGridRows(convertedData)); + } else if (tabKey === 'ST00020004') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.pipeDiameterStatusList ?? []).map((d: SeweragePipeInputPipeDiameterStatusItem) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d + })); + next.set(tabKey, toGridRows(convertedData)); + } else if (tabKey === 'ST00020005') { + const commonInfo = response.data.commonInfo; + const convertedData = (response.data.manholeStatusList ?? []).map((d: SeweragePipeInputManholeStatusItem) => ({ + ctpvNm: commonInfo.ctpvNm, + ...d + })); + next.set(tabKey, toGridRows(convertedData)); + } else if (tabKey === 'ST00020006') { + const commonInfo = response.data.commonInfo; + const facilityConvertedData = (response.data.facilityConnectionList ?? []).map((d: SeweragePipeInputFacilityConnectionItem) => ({ + ...d + })); + const adminConvertedData = (response.data.adminAreaConnectionList ?? []).map((d: SeweragePipeInputAdminAreaConnectionItem) => ({ + ...d, + ctpvNm: d.ctpvNm || commonInfo.ctpvNm, + })); + next.set('treatmentPlantConnectionInp', toGridRows(facilityConvertedData)); + next.set('adminAreaConnectionInp', toGridRows(adminConvertedData)); + } + return next; + }); + } else { + alert(response?.message || '데이터 조회 중 오류가 발생했습니다.'); + } + } catch { + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + }; const SubmitExceptionFunc = () => { console.log('submit exception'); // 예외 제출 로직 }; - const getLastYearDataFunc = () => { - console.log('get last year data'); - // 지난연도 데이터 가져오기 로직 + const getLastYearDataFunc = async () => { + const values = lastSearchedValues ?? searchValues; + if (!values?.sido || values.sido === 'ALL') { + alert('시도를 선택해주세요.'); + return; + } + if (!lastSearchedYear) { + alert('먼저 데이터를 조회해주세요.'); + return; + } + try { + setIsLoading(true); + const param = buildSewagePipeSearchParam(values, { mode: 'PRE' }); + await loadSewagePipeActiveTabData(activeTab, param, values, periodEnterableRef.current, true, false); + } catch { + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } }; const submitFunc = () => { @@ -98,29 +442,146 @@ const SewagePipeInp = () => { // 제출 로직 }; - const saveFunc = () => { - console.log('save'); - // 저장 로직 + const saveFunc = async () => { + if (activeTab !== "ST00020001") { + return; + } + try { + const currentData = getGridDataRef.current?.(); + if (!currentData || currentData.length === 0) { + alert("저장할 데이터가 없습니다."); + return; + } + const values = lastSearchedValues ?? searchValues; + if (!values?.year) { + alert("검색 후 저장해 주세요."); + return; + } + + const columnFormatMap = new Map(); + RegionalFactStatusInpColumn.columns.forEach((col) => { + if (col.fieldName && col.dataFormat) { + columnFormatMap.set(col.fieldName, col.dataFormat); + } + }); + + const formatNumber = (value: string | number | null | undefined, fieldName: string): number => { + if (value === null || value === undefined || value === "") return 0; + const num = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value; + if (isNaN(num)) return 0; + const format = columnFormatMap.get(fieldName); + if (!format) return num; + const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0; + return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num); + }; + + const userInfo = await getUserInfo(); + + const saveList = currentData.map((d) => ({ + admdstCd: String(d.admdstCd ?? ""), + sggNm: String(d.sggNm ?? ""), + admdstNm: String(d.admdstNm ?? ""), + goalYr: String(d.goalYr ?? ""), + wholPplMtncPlanPrlg: formatNumber(d.wholPplMtncPlanPrlg, "wholPplMtncPlanPrlg"), + wholPlanPrlg: formatNumber(d.wholPlanPrlg, "wholPlanPrlg"), + wholFcltPrlg: formatNumber(d.wholFcltPrlg, "wholFcltPrlg"), + swagePplPsplyRt: formatNumber(d.swagePplPsplyRt, "swagePplPsplyRt"), + cbsysPplMtncPlanArea: formatNumber(d.cbsysPplMtncPlanArea, "cbsysPplMtncPlanArea"), + cbsysPplMtncPlanPrlg: formatNumber(d.cbsysPplMtncPlanPrlg, "cbsysPplMtncPlanPrlg"), + cbsysPlanPrlg: formatNumber(d.cbsysPlanPrlg, "cbsysPlanPrlg"), + cbsysFcltPrlg: formatNumber(d.cbsysFcltPrlg, "cbsysFcltPrlg"), + cbsysSqrePrlg: formatNumber(d.cbsysSqrePrlg, "cbsysSqrePrlg"), + cbsysCiclPrlg: formatNumber(d.cbsysCiclPrlg, "cbsysCiclPrlg"), + cbsysOpnPrlg: formatNumber(d.cbsysOpnPrlg, "cbsysOpnPrlg"), + cbsysGttrPrlg: formatNumber(d.cbsysGttrPrlg, "cbsysGttrPrlg"), + drtwPplMtncPlanArea: formatNumber(d.drtwPplMtncPlanArea, "drtwPplMtncPlanArea"), + drtwPplMtncPlanPrlg: formatNumber(d.drtwPplMtncPlanPrlg, "drtwPplMtncPlanPrlg"), + drtwPplPlanPrlg: formatNumber(d.drtwPplPlanPrlg, "drtwPplPlanPrlg"), + drtwPplFcltPrlg: formatNumber(d.drtwPplFcltPrlg, "drtwPplFcltPrlg"), + drtwPplSqrePrlg: formatNumber(d.drtwPplSqrePrlg, "drtwPplSqrePrlg"), + drtwPplCiclPrlg: formatNumber(d.drtwPplCiclPrlg, "drtwPplCiclPrlg"), + exlnPplMtncPlanArea: formatNumber(d.exlnPplMtncPlanArea, "exlnPplMtncPlanArea"), + exlnPplMtncPlanPrlg: formatNumber(d.exlnPplMtncPlanPrlg, "exlnPplMtncPlanPrlg"), + exlnPplPlanPrlg: formatNumber(d.exlnPplPlanPrlg, "exlnPplPlanPrlg"), + exlnPplFcltPrlg: formatNumber(d.exlnPplFcltPrlg, "exlnPplFcltPrlg"), + exlnPplSqrePrlg: formatNumber(d.exlnPplSqrePrlg, "exlnPplSqrePrlg"), + exlnPplCiclPrlg: formatNumber(d.exlnPplCiclPrlg, "exlnPplCiclPrlg"), + exlnPplOpnPrlg: formatNumber(d.exlnPplOpnPrlg, "exlnPplOpnPrlg"), + exlnPplGttrPrlg: formatNumber(d.exlnPplGttrPrlg, "exlnPplGttrPrlg"), + cbsysMnhlCnt: formatNumber(d.cbsysMnhlCnt, "cbsysMnhlCnt"), + sprsysDrtwMnhlCnt: formatNumber(d.sprsysDrtwMnhlCnt, "sprsysDrtwMnhlCnt"), + sprsysExlnMnhlCnt: formatNumber(d.sprsysExlnMnhlCnt, "sprsysExlnMnhlCnt"), + drtwRcvprpCnt: formatNumber(d.drtwRcvprpCnt, "drtwRcvprpCnt"), + exlnRcvprpCnt: formatNumber(d.exlnRcvprpCnt, "exlnRcvprpCnt"), + stofcbrCnt: formatNumber(d.stofcbrCnt, "stofcbrCnt"), + exlnOtflCnt: formatNumber(d.exlnOtflCnt, "exlnOtflCnt"), + sewerLdgrEdpPrlg: formatNumber(d.sewerLdgrEdpPrlg, "sewerLdgrEdpPrlg"), + sewerLdgrEdpRt: formatNumber(d.sewerLdgrEdpRt, "sewerLdgrEdpRt"), + rmrk: (d.rmrk as string | null) ?? null, + })); + + const param: SeweragePipeInputRegionalFactStatusSaveRequest = { + statsYr: values.year ?? "", + ctpvNm: values.sido ?? "", + sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""), + sewerBzmnCd: values.bsnmCd ?? "", + userId: userInfo.userUnqId, + superAdmin: isAdminInfo ? "superAdmin" : "", + saveList, + }; + + console.log(param); + } catch { + alert("저장 준비 중 오류가 발생했습니다."); + } }; + const gugunOkOrNotDoList = doList.includes(lastSearchedValues?.bsnmCd || '') + ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') + : true; + + const showSaveInToolbar = (isEnterable || isAdminInfo) && gugunOkOrNotDoList; + const showEnterableToolbarButtons = isEnterable && gugunOkOrNotDoList; + + /** TabDataGrid는 rowDataMap 사용 — 행이 하나라도 있을 때만 툴바 카드 의미 있음 */ + const hasRowData = Array.from(rowDataMap.values()).some((rows) => rows.length > 0); + + const showActionToolbarCard = + (hasRowData || hasSearched) && + (showSaveInToolbar || + (statusInfo?.laeSbmsnSttsCd === '2' && (isAdminInfo || (isEnterable && gugunOkOrNotDoList)))); return ( <> - -
-
- - - - + + {showActionToolbarCard && ( +
+
+ {showEnterableToolbarButtons && ( + <> + + void getLastYearDataFunc()} /> + + + )} + {showSaveInToolbar && } +
-
+ )} + {isLoading &&
+
+ +
+
} ); diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index e3253995e..e8fec3870 100644 --- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -30,7 +30,7 @@ import type { SewerageSupplyRateSaveRequest, SewerageSupplyRateStatusInfo, } from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface"; -import type { cancelSubmitRequest } from "@/entities/statistics/model/statistics-interface"; +import type { cancelSubmitRequest, SubmitExceptionRequest } from "@/entities/statistics/model/statistics-interface"; import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema"; import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn"; import { doList } from "@/components/util/column/input/DoList"; @@ -69,6 +69,8 @@ const SeweragePenetrationRateInp = () => { const [lastSearchedValues, setLastSearchedValues] = useState(null); const [statusInfo, setStatusInfo] = useState(null); const [showDailog, setShowDailog] = useState(false); + /** 예외제출 버튼으로 연 다이얼로그인지 (확인 시 executeSubmit 대신 SubmitExceptionFunc 경로) */ + const [isExceptionSubmitFlow, setIsExceptionSubmitFlow] = useState(false); const [statsCd, setStatsCd] = useState(''); const [footerFromApi, setFooterFromApi] = useState<{ sewerBzmnWholPpltnCnt?: number; sewerBzmnDomplWholPpltnCnt?: number; sewerBzmnFrgnrWholPpltnCnt?: number; sewerBzmnArea?: number } | null>(null); const { confirm } = useConfirm(); @@ -190,8 +192,39 @@ const SeweragePenetrationRateInp = () => { } }; - const SubmitExceptionFunc = () => { - + const SubmitExceptionFunc = async (submitInfo: StatisticsInputSubmitInfoFormData) => { + const userInfo = await getUserInfo(); + + const params: SubmitExceptionRequest = { + ...submitInfo, + sewerBzmnCd: searchValues?.bsnmCd ?? '', + ctpvNm: searchValues?.sido ?? '', + sggNm: searchValues?.gugun ?? '', + statsYr: searchValues?.year ?? '', + userId: userInfo.userUnqId, + statsCd: statsCd, + }; + + // if (isAdminInfo) { + // params.superAdmin = 'superAdmin'; + // } + + try { + setIsLoading(true); + + const response = await statisticsAPi.submitException(params); + + if (response.status === 'success') { + await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false); + alert('제출되었습니다.'); + } else { + alert(response.message || '데이터 제출 중 오류가 발생했습니다.'); + } + } catch { + alert('데이터 제출 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } }; const getLastYearDataFunc = async (values: SearchFormValues) => { @@ -209,21 +242,33 @@ const SeweragePenetrationRateInp = () => { await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }), true); }; - const submitFunc = async () => { - const isError = rowData.filter((d) => - hasVerificationErrors((d as GridRowWithVerification).verificationResult) - ); + const submitFunc = async (isException: boolean) => { + if (!isException) { + const isError = rowData.filter((d) => + hasVerificationErrors((d as GridRowWithVerification).verificationResult) + ); - if (isError.length > 0) { - alert(`데이터에 오류가 있습니다. - 수정 후 제출해주세요.`); - return; - } - if (await confirm('제출 하시겠습니까?')) { - setShowDailog(true); + if (isError.length > 0) { + alert(`데이터에 오류가 있습니다. + 수정 후 제출해주세요.`); + return; + } + if (await confirm('제출 하시겠습니까?')) { + setIsExceptionSubmitFlow(false); + setShowDailog(true); + } + } else { + if (await confirm('예외 제출 시 검증 결과에 오류가 있어도 제출 처리됩니다.')) { + setIsExceptionSubmitFlow(true); + setShowDailog(true); + } } }; + const executeExceptionSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => { + await SubmitExceptionFunc(submitInfo); + }; + const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => { try { setIsLoading(true); @@ -457,7 +502,7 @@ const SeweragePenetrationRateInp = () => { if (await confirm('제출된 내용을 취소하시겠습니까?')) { const userInfo = await getUserInfo(); - + const requestData: cancelSubmitRequest = { sewerBzmnCd: searchValues?.bsnmCd ?? '', ctpvNm: searchValues?.sido ?? '', @@ -503,11 +548,11 @@ const SeweragePenetrationRateInp = () => { {showEnterableToolbarButtons && ( <> {isAdminInfo && statusInfo && statusInfo.laeSbmsnSttsCd !== '0' && ( - + submitFunc(true)} /> )} getLastYearDataFunc(searchValues ?? {})} /> - - + submitFunc(false)} /> + )} {statusInfo?.laeSbmsnSttsCd === '2' && } @@ -557,7 +602,18 @@ const SeweragePenetrationRateInp = () => { />
- + { + setShowDailog(open); + if (!open) setIsExceptionSubmitFlow(false); + }} + statusInfo={statusInfo} + onConfirm={executeSubmit} + onExceptionConfirm={executeExceptionSubmit} + submitMode={isExceptionSubmitFlow ? 'exception' : 'normal'} + isLoading={isLoading} + /> ); }; diff --git a/apps/st/src/components/statistics/input/SubmitDailog.tsx b/apps/st/src/components/statistics/input/SubmitDailog.tsx index d2de6ab14..65f2f9306 100644 --- a/apps/st/src/components/statistics/input/SubmitDailog.tsx +++ b/apps/st/src/components/statistics/input/SubmitDailog.tsx @@ -47,7 +47,10 @@ interface SubmitDialogProps { statusInfo: SewerageSupplyRateStatusInfo | null; /** 다이얼로그에서 저장 클릭 시 호출. 제출 정보를 넘기면 부모에서 requestData에 포함해 제출 API 호출 */ onConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise; - onExceptionConfirm?: (data: any) => void | Promise; + /** 예외 제출로 다이얼로그를 연 경우: 일반 제출(onConfirm) 대신 호출 */ + onExceptionConfirm?: (data: StatisticsInputSubmitInfoFormData) => void | Promise; + /** 'normal': onConfirm / 'exception': onExceptionConfirm */ + submitMode?: "normal" | "exception"; isLoading?: boolean; } @@ -75,7 +78,15 @@ function statusInfoToFormData(info: SewerageSupplyRateStatusInfo): StatisticsInp }; }; -const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm, onExceptionConfirm, isLoading }: SubmitDialogProps) => { +const SubmitDailog = ({ + open, + onOpenChange, + statusInfo, + onConfirm, + onExceptionConfirm, + submitMode = "normal", + isLoading, +}: SubmitDialogProps) => { const { control, handleSubmit, reset, formState: { errors } } = useForm({ resolver: zodResolver(statisticsInputSubmitInfoSchema), defaultValues, @@ -88,7 +99,11 @@ const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm, onExceptionCo }, [open, statusInfo, reset]); async function onSubmit(data: StatisticsInputSubmitInfoFormData) { - await onConfirm?.(data); + if (submitMode === "exception") { + await onExceptionConfirm?.(data); + } else { + await onConfirm?.(data); + } onOpenChange(false); reset(defaultValues); } @@ -164,7 +179,7 @@ const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm, onExceptionCo 취소 diff --git a/apps/st/src/components/statistics/management/LogHistory.tsx b/apps/st/src/components/statistics/management/LogHistory.tsx index 2938343f8..225de9399 100644 --- a/apps/st/src/components/statistics/management/LogHistory.tsx +++ b/apps/st/src/components/statistics/management/LogHistory.tsx @@ -1,87 +1,78 @@ "use client"; -import { useState } from 'react'; -// import useSWR from 'swr'; +import { useCallback, useState } from 'react'; import { Button, - // Input, Label, - // Select, - // SelectTrigger, - // SelectContent, - // SelectItem, - // SelectValue + LoadingWithAnimation, } from "@common/components"; import DataGrid from '@/components/module/DataGrid'; -import { CodeSelect } from '@/entities/code'; +import { CodeSelectWithAll } from '@/entities/code'; + +import { statisticsAPi } from '@/entities/statistics/api/statistics-service'; +import type { StatisticsLogRequest } from '@/entities/statistics/model/statistics-interface'; +import { toGridRows } from '@/components/util/grid/gridFunction'; import { LogHistoryColumn } from '@/components/util/column/management/LogHistoryColumn'; -// import { LwpoCodeApi } from "@/entities/code"; +import { LogHistoryTablePagination } from '@/components/statistics/management/LogHistoryTablePagination'; -// const getStateCdListFetcher = async () => { -// return LwpoCodeApi.getLwpoCodeList({ -// sort: 'regDt,desc', -// upCd: 'STITEM', -// page: 0, -// size: 100, -// }); -// } +const PAGE_SIZE = 100; const LogHistory = () => { // const { setMessage: alert } = useAlertStore((state) => state); - const [statsCd, setStatsCd] = useState(''); + const [statsCd, setStatsCd] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [rowData, setRowData] = useState[]>([]); + const [pageIndex, setPageIndex] = useState(0); + const [totalPages, setTotalPages] = useState(0); - // const { data: lwpoCdList } = useSWR( - // "lwpo-code-list", - // getStateCdListFetcher, - // { - // revalidateOnFocus: false, - // revalidateOnReconnect: false, - // revalidateIfStale: false, - // dedupingInterval: 2000, - // shouldRetryOnError: false, - // onSuccess: (data) => { - // if (!data.content || data.content.length == 0) { - // alert(`시도 목록을 불러오는데 실패했습니다. - // 새로고침 후 다시 시도해주세요.`); - // } - // }, - // onError: () => { - // alert(`시도 목록을 불러오는데 실패했습니다. - // 새로고침 후 다시 시도해주세요.`); - // }, - // } - // ); + const loadLogs = useCallback(async (page1Based: number) => { + const param: StatisticsLogRequest = { + statsCd: (statsCd === '' || statsCd === 'ALL') ? '' : statsCd, + page: page1Based, + size: PAGE_SIZE, + }; + + try { + setIsLoading(true); + + const response = await statisticsAPi.getLogList(param); + + if (response.status === 'success') { + setRowData(toGridRows(response.data?.statsLogList ?? [])); + setTotalPages(response.data?.pageInfo?.totalPages ?? 0); + setPageIndex(Math.max(0, page1Based - 1)); + } else { + alert(response.message || '데이터 조회 중 오류가 발생했습니다.'); + } + } catch { + alert('데이터 조회 중 오류가 발생했습니다.'); + } finally { + setIsLoading(false); + } + }, [statsCd]); + + const handleSearch = async (e: React.FormEvent) => { + e.preventDefault(); + await loadLogs(1); + }; return (
-
+
- {/* */} -
@@ -96,14 +87,23 @@ const LogHistory = () => {
- +
+ +
+
} + {}} + rowData={rowData} + setRowData={() => { }} + /> + { + void loadLogs(idx + 1); + }} />
); diff --git a/apps/st/src/components/statistics/management/LogHistoryTablePagination.tsx b/apps/st/src/components/statistics/management/LogHistoryTablePagination.tsx new file mode 100644 index 000000000..88c589e01 --- /dev/null +++ b/apps/st/src/components/statistics/management/LogHistoryTablePagination.tsx @@ -0,0 +1,105 @@ +"use client"; + +/** + * @common/components DataTable 내부 Pagination과 동일 마크업/클래스 (복제). + * 공용 패키지 수정 없이 LogHistory 전용으로 둠. + */ +import { + ChevronLeftIcon, + ChevronRightIcon, + DoubleArrowLeftIcon, + DoubleArrowRightIcon, +} from "@radix-ui/react-icons"; + +import { Button, cn } from "@common/components"; + +export type LogHistoryTablePaginationProps = { + /** 총 페이지 수 (TanStack table.getPageCount()와 동일) */ + pageCount: number; + /** 0부터 시작하는 현재 페이지 인덱스 */ + pageIndex: number; + onPageIndexChange: (pageIndex: number) => void; +}; + +export function LogHistoryTablePagination({ + pageCount, + pageIndex: currentPage, + onPageIndexChange, +}: LogHistoryTablePaginationProps) { + const maxVisiblePages = 10; + + let startPage = Math.max(0, currentPage - maxVisiblePages / 2); + const endPage = Math.min(pageCount, startPage + maxVisiblePages); + + if (endPage - startPage < maxVisiblePages) { + startPage = Math.max(0, endPage - maxVisiblePages); + } + + const pageNumbers = Array(endPage - startPage) + .fill(0) + .map((_, i) => startPage + i); + + const canPrevious = currentPage > 0; + const canNext = pageCount > 0 && currentPage < pageCount - 1; + + return ( +
+ + +
+ {pageNumbers.map((pageNumber) => ( + + ))} +
+ + +
+ ); +} diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 77d3a5d88..37073b2db 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -54,11 +54,11 @@ const SewagePipeRvw = () => { try { setIsLoading(true); - const searchParam: SewagePipeReviewRequestParams = { - statsYr: values.year, - sewerBzmnCd: values.bsnmCd, - ctpvNm: values.sido, - sggNm: values.gugun === 'ALL' ? '' : values.gugun + const searchParam: SewagePipeReviewRequestParams = { + statsYr: values.year, + sewerBzmnCd: values.bsnmCd, + ctpvNm: values.sido, + sggNm: values.gugun === 'ALL' ? '' : values.gugun }; searchParamRef.current = searchParam; @@ -69,7 +69,7 @@ const SewagePipeRvw = () => { newRowDataMap.set('ST00020001', toGridRows(response.data as object[])); setRowDataMap(newRowDataMap); } else { - alert(response?.message || "데이터가 없습니다."); + alert(response?.message || '데이터 조회 중 오류가 발생했습니다.'); } } catch { alert('데이터 조회 중 오류가 발생했습니다.'); @@ -96,14 +96,14 @@ const SewagePipeRvw = () => { if (tabKey === 'ST00020002') { response = await statisticsManagementApi.getSewagePipeFacilityList(searchParamRef.current); - }else if(tabKey === 'ST00020003'){ - response = await statisticsManagementApi.getSewagePipeTypeList(searchParamRef.current); - }else if(tabKey === 'ST00020004'){ - response = await statisticsManagementApi.getSewagePipeDiamList(searchParamRef.current); + } else if (tabKey === 'ST00020003') { + response = await statisticsManagementApi.getSewagePipeTypeList(searchParamRef.current); + } else if (tabKey === 'ST00020004') { + response = await statisticsManagementApi.getSewagePipeDiamList(searchParamRef.current); } if (response?.status === 'success' && response.data) { - + setRowDataMap(prev => { const next = new Map(prev); next.set(tabKey, toGridRows(response.data as object[])); diff --git a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 8fdd74d4f..2b73f5160 100644 --- a/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -1,5 +1,5 @@ import { useState, useMemo } from "react"; -import { DataGrid } from "@rsone/components"; +import DataGrid from "@/components/module/DataGrid"; import SearchForm from "@/components/module/SearchForm"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; @@ -45,17 +45,17 @@ const StatsInputStatusRvw = () => { setIsLoading(true); const response = await statisticsManagementApi.getStatsInputStatusList({ - sido: values.sido, - gugun: values.gugun === 'ALL' ? '' : values.gugun, - yr: values.year, - bsnmCd: values.bsnmCd + ctpvNm: values.sido, + sggNm: values.gugun === 'ALL' ? '' : values.gugun, + statsYr: values.year, + sewerBzmnCd: values.bsnmCd }); if (response.status === 'success' && response.data) { const rawList = response.data.sewerageSupplyRateList ?? []; const convertedData: StatsInputStatusReviewItem[] = rawList.map((item: StatsInputStatusReviewItem) => ({ ...item, - status: item.status || '미확인', + // status: item.status || '미확인', })); setRowData(toGridRows(convertedData)); @@ -100,9 +100,10 @@ const StatsInputStatusRvw = () => { diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index 9d9a0e310..9c724b94e 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -197,6 +197,12 @@ export type ColumnInfo = { columnLayout: ColumnLayoutItem[]; }; +export type GridTopButtonConfig = { + visible?: boolean; + text: string; + onClick?: (helpers: { openDialog: (title?: string) => void; closeDialog: () => void }) => void; +}; + export type ColumnInfoList = { tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 columns?: ColumnConfig[]; // 일반 그리드용 (isSplitGrid가 false일 때) @@ -204,6 +210,7 @@ export type ColumnInfoList = { rowStartNum?: number; fixedColumns?: number; tabLabel?: string; // 탭에 표시될 레이블 + topButton?: GridTopButtonConfig; // 탭 상단 커스텀 버튼 isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 left?: ColumnInfoList; // SplitDataGrid용 왼쪽 그리드 정보 right?: ColumnInfoList; // SplitDataGrid용 오른쪽 그리드 정보 @@ -250,6 +257,10 @@ export type DataGridProps = { idFieldName?: string; /** 전체 정렬 기능 on/off (기본값: false) */ enableSort?: boolean; + /** CompactDataGrid 전용: true면 래퍼 너비 w-full (다이얼로그 등 분할 열 안에서 사용) */ + compactFullWidth?: boolean; + /** CompactDataGrid 전용: 그리드 영역 높이 Tailwind 클래스 */ + compactGridHeightClass?: string; }; export type TabDataGridProps = { @@ -274,6 +285,8 @@ export type TabDataGridProps = { }; /** 전체 정렬 기능 on/off (기본값: false) */ enableSort?: boolean; + /** 분할 탭 상단 시설 조회 다이얼로그용 — 상위 화면 검색의 통계연도(searchParam.statsYr) */ + facilitySearchStatsYr?: string | null; }; export type SplitDataGridProps = { diff --git a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts index 03a3157da..8d99e6c9e 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts @@ -1,52 +1,68 @@ import { ValueType } from "realgrid"; +import type { GridTopButtonConfig } from "@/components/type/DataGrid.type"; // 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리 // Tab 6-1: 행정구역별 연결 현황 (오른쪽 그리드) export const AdminAreaConnectionInpColumn = { columns: [ // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' } }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' } }, - { name: 'adstDong', fieldName: '행정구역명', header: { text: '행정구역명' } }, + { name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, editable: false }, + { name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false }, + { name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false }, // 연결여부 - { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + { name: 'isConnection', fieldName: 'isConnection', header: { text: '연결여부' }, editable: false }, // 연결하수처리장 - { name: 'bscFctNm', fieldName: '연결하수처리장', header: { text: '연결하수처리장' } }, + { name: 'connectionBscFctNmList', fieldName: 'connectionBscFctNmList', header: { text: '연결하수처리장' }, editable: false }, + { + name: 'admdstCd', + fieldName: 'admdstCd', + header: { text: '행정구역코드' }, + visible: false, + editable: false, + }, ], columnLayout: [ { name: 'adminArea', hideChildHeaders: false, header: { text: '행정구역' }, - items: ['sido', 'sgg', 'adstDong'], + items: ['ctpvNm', 'sggNm', 'admdstNm'], }, - 'iscan', - 'bscFctNm', + 'isConnection', + 'connectionBscFctNmList', + 'admdstCd' ], rowStartNum: 2, fixedColumns: 1, tabKey: 'adminAreaConnectionInp', - tabLabel: '행정구역별 연결 현황' + tabLabel: '행정구역별 연결 현황', + topButton: { + visible: true, + text: '시설별 설치 현황 관리', + onClick: ({ openDialog }: Parameters>[0]) => { + openDialog('시설별 설치 현황 관리'); + }, + }, }; // Tab 6-2: 하수처리장별 연결 현황 (왼쪽 그리드) export const TreatPlantConnectionInpColumn = { columns: [ // 하수처리장 정보 - { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, - { name: 'fctCpc', fieldName: '용량', header: { text: '용량' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'bscFctCd', fieldName: '하수처리장코드', header: { text: '하수처리장코드' } }, + { name: 'bscFctNm', fieldName: 'bscFctNm', header: { text: '하수처리장명' }, editable: false }, + { name: 'fctCpc', fieldName: 'fctCpc', header: { text: '용량' }, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false }, + { name: 'bscFctCd', fieldName: 'bscFctCd', header: { text: '하수처리장코드' }, editable: false }, // 연결여부 - { name: 'iscan', fieldName: '연결여부', header: { text: '연결여부' } }, + { name: 'isConnection', fieldName: 'isConnection', header: { text: '연결여부' }, editable: false }, // 연결지역 - { name: 'nmlist', fieldName: '연결지역', header: { text: '연결지역' } }, + { name: 'connectionAreaList', fieldName: 'connectionAreaList', header: { text: '연결지역' }, editable: false }, ], columnLayout: [ 'bscFctNm', 'fctCpc', 'bscFctCd', - 'iscan', - 'nmlist', + 'isConnection', + 'connectionAreaList', ], rowStartNum: 1, fixedColumns: 1, @@ -55,9 +71,9 @@ export const TreatPlantConnectionInpColumn = { }; export const ConnectionStatusInpColumn = { - tabKey: 'treatmentPlantConnectionInp', + tabKey: 'ST00020006', tabLabel: '시설별 현황 관리', isSplitGrid: true, - left: AdminAreaConnectionInpColumn, - right: TreatPlantConnectionInpColumn, + left: TreatPlantConnectionInpColumn, + right: AdminAreaConnectionInpColumn, }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts index 213ceb818..549baf09a 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/FactInstallStatusInpColumn.ts @@ -2,86 +2,97 @@ import { footerInt, footerDecimal2, footerDecimal3 } from "@/components/util/gri import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황 +// SeweragePipeInputFactInstallStatusItem + commonInfo.ctpvNm (그리드 행에 병합) export const FactInstallStatusInpColumn = { columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false }, + // 행정구역 (ctpvNm은 commonInfo에서 주입) + { name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' }, + { name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly' }, // 하수처리장 정보 - { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false }, - { name: 'fctCpc', fieldName: '하수처리시설용량(m³/일)', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false }, + { name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly' }, + { name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 처리구역면적(km²) - { name: 'procZoneSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'cmbnProcZoneAr', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, - { name: 'sprtProcZoneAr', fieldName: '분류식', header: { text: '분류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'prcsZoneArea', fieldName: 'prcsZoneArea', header: { text: '합계' }, footer: footerDecimal3, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'cbsysPrcsZoneArea', fieldName: 'cbsysPrcsZoneArea', header: { text: '합류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, + { name: 'sprsysPrcsZoneArea', fieldName: 'sprsysPrcsZoneArea', header: { text: '분류식' }, footer: footerDecimal3, valueType: ValueType.NUMBER, dataFormat: '#,##0.000' }, // 분류식화율 - { name: 'sprtRt', fieldName: '분류식화율', header: { text: '분류식화율' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, + { name: 'sprsysVartnRt', fieldName: 'sprsysVartnRt', header: { text: '분류식화율' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' }, // 배수설비(개소) - { name: 'drngEqpSm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'cmbnDrngEqp', fieldName: '합류식', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'sprtDrngEqpSm', fieldName: '소계', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'sprtDrngEqpCnnc', fieldName: '연결', header: { text: '연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'sprtDrngEqpDcnnc', fieldName: '미연결', header: { text: '미연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'mltvEqpmCnt', fieldName: 'mltvEqpmCnt', header: { text: '합계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'cbsysMltvEqpmCnt', fieldName: 'cbsysMltvEqpmCnt', header: { text: '합류식' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprsysMltvEqpmCnt', fieldName: 'sprsysMltvEqpmCnt', header: { text: '소계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprsysMltvLnkgCnt', fieldName: 'sprsysMltvLnkgCnt', header: { text: '연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprsysMltvYetLnkgCnt', fieldName: 'sprsysMltvYetLnkgCnt', header: { text: '미연결' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수관로 > 총시설연장 - { name: 'piplFcltyExtn', fieldName: '총시설연장(m)', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'wholFcltPrlg', fieldName: 'wholFcltPrlg', header: { text: '총시설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 하수관로 > 차집/오수간선(m) - { name: 'icgMnnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'icgExtn', fieldName: '차집', header: { text: '차집' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'mnnExtn', fieldName: '오수 간선', header: { text: '오수 간선' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'wholIcptgAtlfcsPrlg', fieldName: 'wholIcptgAtlfcsPrlg', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'icptgPrlg', fieldName: 'icptgPrlg', header: { text: '차집' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'atlfcsPrlg', fieldName: 'atlfcsPrlg', header: { text: '오수 간선' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 하수관로 > 토실/토구(개소) > 합류식 - { name: 'cmbnSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'cbsysStofcbrCnt', fieldName: 'cbsysStofcbrCnt', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수관로 > 토실/토구(개소) > 분류식 - { name: 'sprtSoilholeSite', fieldName: '우수토실', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'sprtSoilspllSite', fieldName: '우수토구', header: { text: '우수토구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprsysStofcbrCnt', fieldName: 'sprsysStofcbrCnt', header: { text: '우수토실' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'sprsysExlnOtflCnt', fieldName: 'sprsysExlnOtflCnt', header: { text: '우수토구' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 하수관로 > 지선(m) - { name: 'brnchlnSm', fieldName: '합계', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'cmbnBrnchlnExtn', fieldName: '합류식', header: { text: '합류식' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'wholBrchlnPrlg', fieldName: 'wholBrchlnPrlg', header: { text: '합계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'cbsysBrchlnPrlg', fieldName: 'cbsysBrchlnPrlg', header: { text: '합류식' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - // 하수관로 > 지선(m) > 분류식 - { name: 'rainwtrBrnchlnExtn', fieldName: '우수', header: { text: '우수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'pltwtrBrnchlnExtn', fieldName: '오수', header: { text: '오수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + // 하수관로 > 지선(m) > 분류식 + { name: 'exlnBrchlnPrlg', fieldName: 'exlnBrchlnPrlg', header: { text: '우수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, + { name: 'drtwBrchlnPrlg', fieldName: 'drtwBrchlnPrlg', header: { text: '오수' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + { name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } }, + + // 식별·키 필드 (API SeweragePipeInputFactInstallStatusItem, 그리드 비표시 — fixedColumns와 겹치지 않도록 맨 뒤) + { name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' }, + { name: 'prcsFcltSn', fieldName: 'prcsFcltSn', header: { text: '처리시설일련번호' }, visible: false, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'swtrmtFcltCd', fieldName: 'swtrmtFcltCd', header: { text: '하수처리시설코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' }, ], columnLayout: [ { name: 'adminArea', hideChildHeaders: false, header: { text: '행정구역' }, - items: ['sido', 'sgg'], + items: [ + { column: 'ctpvNm', footerUserSpans: [{ colspan: 2 }] }, + 'sggNm', + ], }, - 'bscFctNm', - 'fctCpc', + 'swtrmtFcltNm', + 'admdstNm', + 'prcsFcltCpct', { name: 'procZone', hideChildHeaders: false, header: { text: '처리구역면적(km²)' }, - items: ['procZoneSm', 'cmbnProcZoneAr', 'sprtProcZoneAr'], + items: ['prcsZoneArea', 'cbsysPrcsZoneArea', 'sprsysPrcsZoneArea'], }, - 'sprtRt', + 'sprsysVartnRt', { name: 'drainEquip', hideChildHeaders: false, header: { text: '배수설비(개소)' }, items: [ - 'drngEqpSm', - 'cmbnDrngEqp', + 'mltvEqpmCnt', + 'cbsysMltvEqpmCnt', { name: 'sprtDrainEquip', hideChildHeaders: false, header: { text: '분류식' }, - items: ['sprtDrngEqpSm', 'sprtDrngEqpCnnc', 'sprtDrngEqpDcnnc'], + items: ['sprsysMltvEqpmCnt', 'sprsysMltvLnkgCnt', 'sprsysMltvYetLnkgCnt'], }, ], }, @@ -90,12 +101,12 @@ export const FactInstallStatusInpColumn = { hideChildHeaders: false, header: { text: '하수관로' }, items: [ - 'piplFcltyExtn', + 'wholFcltPrlg', { name: 'interceptor', hideChildHeaders: false, header: { text: '차집/오수간선(m)' }, - items: ['icgMnnSm', 'icgExtn', 'mnnExtn'], + items: ['wholIcptgAtlfcsPrlg', 'icptgPrlg', 'atlfcsPrlg'], }, { name: 'soilHole', @@ -106,13 +117,13 @@ export const FactInstallStatusInpColumn = { name: 'cmbnSoilHole', hideChildHeaders: false, header: { text: '합류식' }, - items: ['cmbnSoilholeSite'], + items: ['cbsysStofcbrCnt'], }, { name: 'sprtSoilHole', hideChildHeaders: false, header: { text: '분류식' }, - items: ['sprtSoilholeSite', 'sprtSoilspllSite'], + items: ['sprsysStofcbrCnt', 'sprsysExlnOtflCnt'], }, ], }, @@ -121,22 +132,25 @@ export const FactInstallStatusInpColumn = { hideChildHeaders: false, header: { text: '지선(m)' }, items: [ - 'brnchlnSm', - 'cmbnBrnchlnExtn', + 'wholBrchlnPrlg', + 'cbsysBrchlnPrlg', { name: 'sprtBranchLine', hideChildHeaders: false, header: { text: '분류식' }, - items: ['rainwtrBrnchlnExtn', 'pltwtrBrnchlnExtn'], + items: ['exlnBrchlnPrlg', 'drtwBrchlnPrlg'], }, ], }, ], }, - 'rmk', + 'rmrk', + 'admdstCd', + 'prcsFcltSn', + 'swtrmtFcltCd', ], rowStartNum: 4, fixedColumns: 3, - tabKey: 'factInstallStatusInp', + tabKey: 'ST00020002', tabLabel: '시설별 설치현황' -}; \ No newline at end of file +}; diff --git a/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts index 5732a82df..8fa0b8bbb 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusInpColumn.ts @@ -1,331 +1,158 @@ +import type { ColumnConfig, ColumnLayoutItem } from "@/components/type/DataGrid.type"; import { footerInt } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황 +// SeweragePipeInputManholeStatusItem + commonInfo.ctpvNm (그리드 행에 병합) +// API: yy14=2014년 … yy25=2025년 (필드 접두 yy + 연도 끝자리) + +const MANHOLE_YY_MIN = 14; +const MANHOLE_YY_MAX = 25; +const calendarYearFromYy = (yy: number) => 2000 + yy; + +const intCol = (name: string, headerText: string): ColumnConfig => ({ + name, + fieldName: name, + header: { text: headerText }, + footer: footerInt, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0", +}); + +function totalBlockColumns(): ColumnConfig[] { + return [ + intCol("totalWholMnhlCnt", "계"), + intCol("totalStep1MnhlCnt", "주철"), + intCol("totalStep2MnhlCnt", "주철(조화)"), + intCol("totalStep3MnhlCnt", "콘크리트"), + intCol("totalStep4MnhlCnt", "기타"), + intCol("totalStep5MnhlCnt", "추락방지시설설치맨홀(개)"), + ]; +} + +function yyBlockColumns(yy: number): ColumnConfig[] { + const p = `yy${yy}`; + return [ + intCol(`${p}WholMnhlCnt`, "계"), + intCol(`${p}Step1MnhlCnt`, "주철"), + intCol(`${p}Step2MnhlCnt`, "주철(조화)"), + intCol(`${p}Step3MnhlCnt`, "콘크리트"), + intCol(`${p}Step4MnhlCnt`, "기타"), + intCol(`${p}Step5MnhlCnt`, "추락방지시설설치맨홀(개)"), + ]; +} + +function yyYearLayout(yy: number): ColumnLayoutItem { + const y = calendarYearFromYy(yy); + const p = `yy${yy}`; + return { + name: `year${y}`, + hideChildHeaders: false, + header: { text: `${y}년` }, + items: [ + { + name: `year${y}Material`, + hideChildHeaders: false, + header: { text: "맨홀뚜껑 재질(개)" }, + items: [ + `${p}WholMnhlCnt`, + `${p}Step1MnhlCnt`, + `${p}Step2MnhlCnt`, + `${p}Step3MnhlCnt`, + `${p}Step4MnhlCnt`, + ], + }, + `${p}Step5MnhlCnt`, + ], + }; +} + +const yearLayoutItems: ColumnLayoutItem[] = []; +for (let yy = MANHOLE_YY_MIN; yy <= MANHOLE_YY_MAX; yy++) { + yearLayoutItems.push(yyYearLayout(yy)); +} export const ManholeStatusInpColumn = { columns: [ - // 행정구역 - { name: 'a1', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'a2', fieldName: '시군구', header: { text: '시군구' }, editable: false }, - - // 집중강우중점관리구역구분 - { name: 'a3', fieldName: '집중강우중점관리구역구분', header: { text: '집중강우중점관리구역구분' }, editable: false, footer: { text: '합계' } }, - - // 연도별총계 > 맨홀뚜껑 재질(개) - { name: 'b1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'b2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'b3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'b4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'b5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 연도별총계 > 추락방지시설설치맨홀(개) - { name: 'b6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2015년 이전 > 맨홀뚜껑 재질(개) - { name: 'c1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'c2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'c3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'c4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'c5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2015년 이전 > 추락방지시설설치맨홀(개) - { name: 'c6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2015년 > 맨홀뚜껑 재질(개) - { name: 'd1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'd2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'd3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'd4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'd5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2015년 > 추락방지시설설치맨홀(개) - { name: 'd6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2016년 > 맨홀뚜껑 재질(개) - { name: 'e1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'e2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'e3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'e4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'e5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2016년 > 추락방지시설설치맨홀(개) - { name: 'e6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2017년 > 맨홀뚜껑 재질(개) - { name: 'f1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'f2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'f3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'f4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'f5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2017년 > 추락방지시설설치맨홀(개) - { name: 'f6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2018년 > 맨홀뚜껑 재질(개) - { name: 'g1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'g2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'g3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'g4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'g5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2018년 > 추락방지시설설치맨홀(개) - { name: 'g6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2019년 > 맨홀뚜껑 재질(개) - { name: 'h1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'h2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'h3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'h4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'h5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2019년 > 추락방지시설설치맨홀(개) - { name: 'h6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2020년 > 맨홀뚜껑 재질(개) - { name: 'i1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'i2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'i3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'i4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'i5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2020년 > 추락방지시설설치맨홀(개) - { name: 'i6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2021년 > 맨홀뚜껑 재질(개) - { name: 'j1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'j2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'j3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'j4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'j5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2021년 > 추락방지시설설치맨홀(개) - { name: 'j6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2022년 > 맨홀뚜껑 재질(개) - { name: 'k1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'k2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'k3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'k4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'k5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2022년 > 추락방지시설설치맨홀(개) - { name: 'k6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2023년 > 맨홀뚜껑 재질(개) - { name: 'l1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'l2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'l3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'l4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'l5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2023년 > 추락방지시설설치맨홀(개) - { name: 'l6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2024년 > 맨홀뚜껑 재질(개) - { name: 'm1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'm2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'm3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'm4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'm5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2024년 > 추락방지시설설치맨홀(개) - { name: 'm6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 2025년 > 맨홀뚜껑 재질(개) - { name: 'n1', fieldName: '계', header: { text: '계' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'n2', fieldName: '주철', header: { text: '주철' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'n3', fieldName: '주철(조화)', header: { text: '주철(조화)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'n4', fieldName: '콘크리트', header: { text: '콘크리트' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'n5', fieldName: '기타', header: { text: '기타' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - // 2025년 > 추락방지시설설치맨홀(개) - { name: 'n6', fieldName: '추락방지시설설치맨홀(개)', header: { text: '추락방지시설설치맨홀(개)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - - // 비고 - { name: 'z1', fieldName: '비고', header: { text: '비고' } }, - ], + { + name: "ctpvNm", + fieldName: "ctpvNm", + header: { text: "시도" }, + footer: { text: "합계" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "sggNm", + fieldName: "sggNm", + header: { text: "시군구" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "admdstNm", + fieldName: "admdstNm", + header: { text: "행정구역명" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "emphsMngSeNm", + fieldName: "emphsMngSeNm", + header: { text: "집중강우중점관리구역구분" }, + footer: { text: "합계" }, + editable: false, + }, + ...totalBlockColumns(), + ...Array.from({ length: MANHOLE_YY_MAX - MANHOLE_YY_MIN + 1 }, (_, i) => + yyBlockColumns(MANHOLE_YY_MIN + i) + ).flat(), + { name: "rmrk", fieldName: "rmrk", header: { text: "비고" } }, + { + name: "admdstCd", + fieldName: "admdstCd", + header: { text: "행정구역코드" }, + visible: false, + editable: false, + styleName: "rg-cell-readonly", + }, + ] as ColumnConfig[], columnLayout: [ { - name: 'adminArea', + name: "adminArea", hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['a1', 'a2'], + header: { text: "행정구역" }, + items: [{ column: "ctpvNm", footerUserSpans: [{ colspan: 2 }] }, "sggNm"], }, - 'a3', + "admdstNm", + "emphsMngSeNm", { - name: 'yearlyTotal', + name: "yearlyTotal", hideChildHeaders: false, - header: { text: '연도별총계' }, + header: { text: "연도별총계" }, items: [ { - name: 'yearlyTotalMaterial', + name: "yearlyTotalMaterial", hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['b1', 'b2', 'b3', 'b4', 'b5'], + header: { text: "맨홀뚜껑 재질(개)" }, + items: [ + "totalWholMnhlCnt", + "totalStep1MnhlCnt", + "totalStep2MnhlCnt", + "totalStep3MnhlCnt", + "totalStep4MnhlCnt", + ], }, - 'b6', + "totalStep5MnhlCnt", ], }, - { - name: 'before2015', - hideChildHeaders: false, - header: { text: '2015년 이전' }, - items: [ - { - name: 'before2015Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['c1', 'c2', 'c3', 'c4', 'c5'], - }, - 'c6', - ], - }, - { - name: 'year2015', - hideChildHeaders: false, - header: { text: '2015년' }, - items: [ - { - name: 'year2015Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['d1', 'd2', 'd3', 'd4', 'd5'], - }, - 'd6', - ], - }, - { - name: 'year2016', - hideChildHeaders: false, - header: { text: '2016년' }, - items: [ - { - name: 'year2016Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['e1', 'e2', 'e3', 'e4', 'e5'], - }, - 'e6', - ], - }, - { - name: 'year2017', - hideChildHeaders: false, - header: { text: '2017년' }, - items: [ - { - name: 'year2017Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['f1', 'f2', 'f3', 'f4', 'f5'], - }, - 'f6', - ], - }, - { - name: 'year2018', - hideChildHeaders: false, - header: { text: '2018년' }, - items: [ - { - name: 'year2018Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['g1', 'g2', 'g3', 'g4', 'g5'], - }, - 'g6', - ], - }, - { - name: 'year2019', - hideChildHeaders: false, - header: { text: '2019년' }, - items: [ - { - name: 'year2019Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['h1', 'h2', 'h3', 'h4', 'h5'], - }, - 'h6', - ], - }, - { - name: 'year2020', - hideChildHeaders: false, - header: { text: '2020년' }, - items: [ - { - name: 'year2020Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['i1', 'i2', 'i3', 'i4', 'i5'], - }, - 'i6', - ], - }, - { - name: 'year2021', - hideChildHeaders: false, - header: { text: '2021년' }, - items: [ - { - name: 'year2021Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['j1', 'j2', 'j3', 'j4', 'j5'], - }, - 'j6', - ], - }, - { - name: 'year2022', - hideChildHeaders: false, - header: { text: '2022년' }, - items: [ - { - name: 'year2022Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['k1', 'k2', 'k3', 'k4', 'k5'], - }, - 'k6', - ], - }, - { - name: 'year2023', - hideChildHeaders: false, - header: { text: '2023년' }, - items: [ - { - name: 'year2023Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['l1', 'l2', 'l3', 'l4', 'l5'], - }, - 'l6', - ], - }, - { - name: 'year2024', - hideChildHeaders: false, - header: { text: '2024년' }, - items: [ - { - name: 'year2024Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['m1', 'm2', 'm3', 'm4', 'm5'], - }, - 'm6', - ], - }, - { - name: 'year2025', - hideChildHeaders: false, - header: { text: '2025년' }, - items: [ - { - name: 'year2025Material', - hideChildHeaders: false, - header: { text: '맨홀뚜껑 재질(개)' }, - items: ['n1', 'n2', 'n3', 'n4', 'n5'], - }, - 'n6', - ], - }, - 'z1', - ], + ...yearLayoutItems, + "rmrk", + "admdstCd" + ] as ColumnLayoutItem[], rowStartNum: 3, fixedColumns: 2, - tabKey: 'manholeStatusInp', - tabLabel: '맨홀 현황' -}; \ No newline at end of file + tabKey: "ST00020005", + tabLabel: "맨홀 현황", +}; diff --git a/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts index af009e292..a852f45f2 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn.ts @@ -2,62 +2,151 @@ import { footerDecimal2 } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 4. 관경별 현황 +// SeweragePipeInputPipeDiameterStatusItem + commonInfo.ctpvNm (그리드 행에 병합) export const PipeDiameterStatusInpColumn = { columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false, footer: { text: '합계' } }, - - // 관종 - { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, editable: false }, - - // 총계(m) - 계산 - { name: 'totalDiameter', fieldName: '총계(m)', header: { text: '총계(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 원형(m) - { name: 'under200', fieldName: '200mm 미만', header: { text: '200mm 미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'over200Undev300', fieldName: '200mm이상~300mm미만', header: { text: '200mm이상~300mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'over300Undev500', fieldName: '300mm이상~500mm미만', header: { text: '300mm이상~500mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'over500Undev500', fieldName: '500mm이상~800mm미만', header: { text: '500mm이상~800mm미만' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'over800', fieldName: '800이상mm', header: { text: '800이상mm' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 사각형(m) - { name: 'box', fieldName: '사각형(m)', header: { text: '사각형(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 기타(측구 개거 등) - { name: 'etc', fieldName: '기타(측구 개거 등)', header: { text: '기타(측구 개거 등)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + { + name: "ctpvNm", + fieldName: "ctpvNm", + header: { text: "시도" }, + footer: { text: "합계" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "sggNm", + fieldName: "sggNm", + header: { text: "시군구" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "pipeSeNm", + fieldName: "pipeSeNm", + header: { text: "관종" }, + editable: false, + }, + { + name: "admdstNm", + fieldName: "admdstNm", + header: { text: "행정구역명" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "pdmtByTsmWhol", + fieldName: "pdmtByTsmWhol", + header: { text: "총계(m)" }, + footer: footerDecimal2, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "step1PdmtPrlg", + fieldName: "step1PdmtPrlg", + header: { text: "200mm 미만" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "step2PdmtPrlg", + fieldName: "step2PdmtPrlg", + header: { text: "200mm이상~300mm미만" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "step3PdmtPrlg", + fieldName: "step3PdmtPrlg", + header: { text: "300mm이상~500mm미만" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "step4PdmtPrlg", + fieldName: "step4PdmtPrlg", + header: { text: "500mm이상~800mm미만" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "step5PdmtPrlg", + fieldName: "step5PdmtPrlg", + header: { text: "800mm 이상" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "sqrePdmtPrlg", + fieldName: "sqrePdmtPrlg", + header: { text: "사각형(m)" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "etcPdmtPrlg", + fieldName: "etcPdmtPrlg", + header: { text: "기타(측구 개거 등)" }, + footer: footerDecimal2, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { name: "rmrk", fieldName: "rmrk", header: { text: "비고" } }, + { + name: "admdstCd", + fieldName: "admdstCd", + header: { text: "행정구역코드" }, + visible: false, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "pipeSeCd", + fieldName: "pipeSeCd", + header: { text: "관종코드" }, + visible: false, + editable: false, + styleName: "rg-cell-readonly", + }, ], columnLayout: [ { - name: 'adminArea', + name: "adminArea", hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], + header: { text: "행정구역" }, + items: [{ column: "ctpvNm", footerUserSpans: [{ colspan: 2 }] }, "sggNm"], }, - 'swrgPipeCd', - 'totalDiameter', + "pipeSeNm", + "admdstNm", + "pdmtByTsmWhol", { - name: 'circular', + name: "circular", hideChildHeaders: false, - header: { text: '원형(m)' }, + header: { text: "원형(m)" }, items: [ - 'under200', - 'over200Undev300', - 'over300Undev500', - 'over500Undev500', - 'over800', + "step1PdmtPrlg", + "step2PdmtPrlg", + "step3PdmtPrlg", + "step4PdmtPrlg", + "step5PdmtPrlg", ], }, - 'box', - 'etc', - 'rmk', + "sqrePdmtPrlg", + "etcPdmtPrlg", + "rmrk", + "admdstCd", + "pipeSeCd", ], rowStartNum: 2, - fixedColumns: 1, - tabKey: 'pipeDiameterStatusInp', - tabLabel: '관경별 현황' -}; \ No newline at end of file + fixedColumns: 2, + tabKey: "ST00020004", + tabLabel: "관경별 현황", +}; diff --git a/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts index e1e33a3c8..9b61abe2a 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn.ts @@ -1,377 +1,186 @@ +import type { ColumnConfig, ColumnLayoutItem } from "@/components/type/DataGrid.type"; import { footerDecimal2 } from "@/components/util/grid/footerSummary"; import { ValueType } from "realgrid"; // 하수도 통계 관리 > 02.하수관로 > tab 3. 관종별 현황 +// SeweragePipeInputPipeTypeStatusItem + commonInfo.ctpvNm (그리드 행에 병합) +// +// 연도 그룹: yy1 = 1996년 이전, yy2 = 1996년 … API 상한 yy30(2024년)까지. +// 표시 구간: 1996년 ~ (현재 연도 − 1) 까지. API 밖 연도는 yy 인덱스 상한으로 캡. + +const YY_API_MAX = 30; +/** yy 인덱스 → 달력 연도 (yy2 → 1996) */ +const calendarYearForYyIndex = (yyIndex: number) => 1994 + yyIndex; + +/** 이 모듈이 로드될 때의 “데이터 기준 마지막 연도” (현재 연도 − 1) */ +const lastDataYear = new Date().getFullYear() - 1; + +const yyYearCols = ( + n: number, + opts: { footer?: typeof footerDecimal2; visible?: boolean } = {} +): ColumnConfig[] => { + const whol = `yy${n}PrlgWhol`; + const lyng = `yy${n}LyngPrlg`; + const dmltn = `yy${n}DmltnPrlg`; + const vis = opts.visible === false ? ({ visible: false } as const) : {}; + return [ + { + name: whol, + fieldName: whol, + header: { text: "계" }, + ...(opts.footer !== undefined ? { footer: opts.footer } : {}), + editable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + ...vis, + }, + { + name: lyng, + fieldName: lyng, + header: { text: "매설연장(m)" }, + ...(opts.footer !== undefined ? { footer: opts.footer } : {}), + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + ...vis, + }, + { + name: dmltn, + fieldName: dmltn, + header: { text: "철거연장(m)" }, + ...(opts.footer !== undefined ? { footer: opts.footer } : {}), + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + ...vis, + }, + ]; +}; + +/** yy2(1996) ~ yyK 까지 표시. K는 API 상한 YY_API_MAX */ +const maxYyIndex = + lastDataYear < 1996 ? 1 : Math.min(YY_API_MAX, lastDataYear - 1994); + +const yearLayoutItems: ColumnLayoutItem[] = []; +for (let yy = 2; yy <= maxYyIndex; yy++) { + const y = calendarYearForYyIndex(yy); + yearLayoutItems.push({ + name: `year${y}`, + hideChildHeaders: false, + header: { text: `${y}년` }, + items: [`yy${yy}PrlgWhol`, `yy${yy}LyngPrlg`, `yy${yy}DmltnPrlg`], + }); +} export const PipeTypeStatusInpColumn = { columns: [ - // 행정구역 - { name: 'sido', fieldName: '시도', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, editable: false }, - - // 관종 - { name: 'swrgPipeCd', fieldName: '관종', header: { text: '관종' }, footer: { text: '합계' }, editable: false }, - - // 총계 - { name: 'totalSum', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'totalLayingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'totalRemvlExtn', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 1996년 이전 (footer 없음) - { name: 'totalExtn22y', fieldName: '계', header: { text: '계' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn22y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn22y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 1996년 - { name: 'totalExtn01y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn01y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn01y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 1997년 - { name: 'totalExtn02y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn02y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn02y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 1998년 - { name: 'totalExtn03y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn03y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn03y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 1999년 - { name: 'totalExtn04y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn04y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn04y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2000년 - { name: 'totalExtn05y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn05y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn05y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2001년 - { name: 'totalExtn06y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn06y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn06y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2002년 - { name: 'totalExtn07y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn07y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn07y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2003년 - { name: 'totalExtn08y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn08y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn08y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2004년 - { name: 'totalExtn09y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn09y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn09y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2005년 - { name: 'totalExtn10y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn10y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn10y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2006년 - { name: 'totalExtn11y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn11y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn11y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2007년 - { name: 'totalExtn12y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn12y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn12y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2008년 - { name: 'totalExtn13y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn13y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn13y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2009년 - { name: 'totalExtn14y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn14y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn14y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2010년 - { name: 'totalExtn15y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn15y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn15y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2011년 - { name: 'totalExtn16y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn16y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn16y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2012년 - { name: 'totalExtn17y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn17y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn17y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2013년 - { name: 'totalExtn18y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn18y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn18y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2014년 - { name: 'totalExtn19y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn19y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn19y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2015년 - { name: 'totalExtn20y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn20y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn20y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2016년 - { name: 'totalExtn21y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn21y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn21y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2017년 - { name: 'totalExtn23y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn23y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn23y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2018년 - { name: 'totalExtn24y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn24y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn24y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2019년 - { name: 'totalExtn25y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn25y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn25y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2020년 - { name: 'totalExtn26y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn26y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn26y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2021년 - { name: 'totalExtn27y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn27y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn27y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2022년 - { name: 'totalExtn28y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn28y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn28y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2023년 - { name: 'totalExtn29y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn29y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn29y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2024년 - { name: 'totalExtn30y', fieldName: '계', header: { text: '계' }, footer: footerDecimal2, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'layingExtn30y', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - { name: 'remvlExtn30y', fieldName: '철거연장(m)', header: { text: '철거연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 2025년 - { name: 'layingExtn', fieldName: '매설연장(m)', header: { text: '매설연장(m)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' }, - - // 비고 - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ], - columnLayout: [ - { - name: 'adminArea', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - 'swrgPipeCd', - { - name: 'totalGroup', - hideChildHeaders: false, - header: { text: '총계' }, - items: ['totalSum', 'totalLayingExtn', 'totalRemvlExtn'], - }, - { - name: 'year1996Before', - hideChildHeaders: false, - header: { text: '1996년 이전' }, - items: ['totalExtn22y', 'layingExtn22y', 'remvlExtn22y'], - }, - { - name: 'year1996', - hideChildHeaders: false, - header: { text: '1996년' }, - items: ['totalExtn01y', 'layingExtn01y', 'remvlExtn01y'], - }, - { - name: 'year1997', - hideChildHeaders: false, - header: { text: '1997년' }, - items: ['totalExtn02y', 'layingExtn02y', 'remvlExtn02y'], - }, - { - name: 'year1998', - hideChildHeaders: false, - header: { text: '1998년' }, - items: ['totalExtn03y', 'layingExtn03y', 'remvlExtn03y'], - }, - { - name: 'year1999', - hideChildHeaders: false, - header: { text: '1999년' }, - items: ['totalExtn04y', 'layingExtn04y', 'remvlExtn04y'], - }, - { - name: 'year2000', - hideChildHeaders: false, - header: { text: '2000년' }, - items: ['totalExtn05y', 'layingExtn05y', 'remvlExtn05y'], - }, - { - name: 'year2001', - hideChildHeaders: false, - header: { text: '2001년' }, - items: ['totalExtn06y', 'layingExtn06y', 'remvlExtn06y'], - }, - { - name: 'year2002', - hideChildHeaders: false, - header: { text: '2002년' }, - items: ['totalExtn07y', 'layingExtn07y', 'remvlExtn07y'], - }, - { - name: 'year2003', - hideChildHeaders: false, - header: { text: '2003년' }, - items: ['totalExtn08y', 'layingExtn08y', 'remvlExtn08y'], - }, - { - name: 'year2004', - hideChildHeaders: false, - header: { text: '2004년' }, - items: ['totalExtn09y', 'layingExtn09y', 'remvlExtn09y'], - }, - { - name: 'year2005', - hideChildHeaders: false, - header: { text: '2005년' }, - items: ['totalExtn10y', 'layingExtn10y', 'remvlExtn10y'], - }, - { - name: 'year2006', - hideChildHeaders: false, - header: { text: '2006년' }, - items: ['totalExtn11y', 'layingExtn11y', 'remvlExtn11y'], - }, - { - name: 'year2007', - hideChildHeaders: false, - header: { text: '2007년' }, - items: ['totalExtn12y', 'layingExtn12y', 'remvlExtn12y'], - }, - { - name: 'year2008', - hideChildHeaders: false, - header: { text: '2008년' }, - items: ['totalExtn13y', 'layingExtn13y', 'remvlExtn13y'], - }, - { - name: 'year2009', - hideChildHeaders: false, - header: { text: '2009년' }, - items: ['totalExtn14y', 'layingExtn14y', 'remvlExtn14y'], - }, - { - name: 'year2010', - hideChildHeaders: false, - header: { text: '2010년' }, - items: ['totalExtn15y', 'layingExtn15y', 'remvlExtn15y'], - }, - { - name: 'year2011', - hideChildHeaders: false, - header: { text: '2011년' }, - items: ['totalExtn16y', 'layingExtn16y', 'remvlExtn16y'], - }, - { - name: 'year2012', - hideChildHeaders: false, - header: { text: '2012년' }, - items: ['totalExtn17y', 'layingExtn17y', 'remvlExtn17y'], - }, - { - name: 'year2013', - hideChildHeaders: false, - header: { text: '2013년' }, - items: ['totalExtn18y', 'layingExtn18y', 'remvlExtn18y'], - }, - { - name: 'year2014', - hideChildHeaders: false, - header: { text: '2014년' }, - items: ['totalExtn19y', 'layingExtn19y', 'remvlExtn19y'], - }, - { - name: 'year2015', - hideChildHeaders: false, - header: { text: '2015년' }, - items: ['totalExtn20y', 'layingExtn20y', 'remvlExtn20y'], - }, - { - name: 'year2016', - hideChildHeaders: false, - header: { text: '2016년' }, - items: ['totalExtn21y', 'layingExtn21y', 'remvlExtn21y'], - }, - { - name: 'year2017', - hideChildHeaders: false, - header: { text: '2017년' }, - items: ['totalExtn23y', 'layingExtn23y', 'remvlExtn23y'], - }, - { - name: 'year2018', - hideChildHeaders: false, - header: { text: '2018년' }, - items: ['totalExtn24y', 'layingExtn24y', 'remvlExtn24y'], - }, - { - name: 'year2019', - hideChildHeaders: false, - header: { text: '2019년' }, - items: ['totalExtn25y', 'layingExtn25y', 'remvlExtn25y'], - }, - { - name: 'year2020', - hideChildHeaders: false, - header: { text: '2020년' }, - items: ['totalExtn26y', 'layingExtn26y', 'remvlExtn26y'], - }, - { - name: 'year2021', - hideChildHeaders: false, - header: { text: '2021년' }, - items: ['totalExtn27y', 'layingExtn27y', 'remvlExtn27y'], - }, - { - name: 'year2022', - hideChildHeaders: false, - header: { text: '2022년' }, - items: ['totalExtn28y', 'layingExtn28y', 'remvlExtn28y'], - }, - { - name: 'year2023', - hideChildHeaders: false, - header: { text: '2023년' }, - items: ['totalExtn29y', 'layingExtn29y', 'remvlExtn29y'], - }, - { - name: 'year2024', - hideChildHeaders: false, - header: { text: '2024년' }, - items: ['totalExtn30y', 'layingExtn30y', 'remvlExtn30y'], - }, - 'layingExtn', - 'rmk', - ], - rowStartNum: 2, - fixedColumns: 2, - tabKey: 'pipeTypeStatusInp', - tabLabel: '관종별 현황' - }; \ No newline at end of file + { + name: "ctpvNm", + fieldName: "ctpvNm", + header: { text: "시도" }, + footer: { text: "합계" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "sggNm", + fieldName: "sggNm", + header: { text: "시군구" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "pipeSeNm", + fieldName: "pipeSeNm", + header: { text: "관종" }, + footer: { text: "합계" }, + editable: false, + }, + { + name: "admdstNm", + fieldName: "admdstNm", + header: { text: "행정구역명" }, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "pipeByPrstWhol", + fieldName: "pipeByPrstWhol", + header: { text: "계" }, + footer: footerDecimal2, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "lyngPrlg", + fieldName: "lyngPrlg", + header: { text: "매설연장(m)" }, + footer: footerDecimal2, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + { + name: "dmltnPrlg", + fieldName: "dmltnPrlg", + header: { text: "철거연장(m)" }, + footer: footerDecimal2, + editable: false, + valueType: ValueType.NUMBER, + dataFormat: "#,##0.00", + }, + ...yyYearCols(1, {}), + ...Array.from({ length: YY_API_MAX - 1 }, (_, i) => { + const yy = i + 2; + return yyYearCols(yy, { + footer: footerDecimal2, + visible: yy <= maxYyIndex, + }); + }).flat(), + { name: "rmrk", fieldName: "rmrk", header: { text: "비고" } }, + { + name: "admdstCd", + fieldName: "admdstCd", + header: { text: "행정구역코드" }, + visible: false, + editable: false, + styleName: "rg-cell-readonly", + }, + { + name: "pipeSeCd", + fieldName: "pipeSeCd", + header: { text: "관종코드" }, + visible: false, + editable: false, + styleName: "rg-cell-readonly", + }, + ] as ColumnConfig[], + columnLayout: [ + { + name: "adminArea", + hideChildHeaders: false, + header: { text: "행정구역" }, + items: [{ column: "ctpvNm", footerUserSpans: [{ colspan: 2 }] }, "sggNm"], + }, + "pipeSeNm", + "admdstNm", + { + name: "totalGroup", + hideChildHeaders: false, + header: { text: "총계" }, + items: ["pipeByPrstWhol", "lyngPrlg", "dmltnPrlg"], + }, + { + name: "year1996Before", + hideChildHeaders: false, + header: { text: "1996년 이전" }, + items: ["yy1PrlgWhol", "yy1LyngPrlg", "yy1DmltnPrlg"], + }, + ...yearLayoutItems, + "rmrk", + 'admdstCd', + ] as ColumnLayoutItem[], + rowStartNum: 2, + fixedColumns: 2, + tabKey: "ST00020003", + tabLabel: "관종별 현황", +}; diff --git a/apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts index 50c16fe40..4ef03f741 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/RegionalFactStatusInpColumn.ts @@ -63,6 +63,7 @@ export const RegionalFactStatusInpColumn = { // 비고 { name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } }, + { name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정코드' }, visible: false }, ], columnLayout: [ { @@ -156,6 +157,7 @@ export const RegionalFactStatusInpColumn = { 'sewerLdgrEdpPrlg', 'sewerLdgrEdpRt', 'rmrk', + 'admdstCd', ], rowStartNum: 4, fixedColumns: 1, diff --git a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts index 9f280338c..cb06da831 100644 --- a/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts +++ b/apps/st/src/components/util/column/review/StatsInputStatusRvwColumn.ts @@ -1,113 +1,33 @@ -import { ValueType } from "realgrid"; - /** * 하수도 통계 검토 00. 통계 입력 현황 */ const StatsInputStatusInfoColumnRaw = { columns: [ // 기본 정보 - { name: 'chk', fieldName: 'chk', header: { text: '체크' }, width: 40 }, - { name: 'sido', fieldName: 'sido', header: { text: '시도' }, width: 80,mergeCells: true}, - { name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, width: 100 }, - { name: 'status', fieldName: 'status', header: { text: '진행상태' }, width: 120 }, + { name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, }, + { name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, }, + { name: 'sewerBzmnCd', fieldName: 'sewerBzmnCd', header: { text: '사업자코드' }, visible: false }, + { name: 'statsCd', fieldName: 'statsCd', header: { text: '메뉴코드' }, visible: false }, + { name: 'status', fieldName: 'status', header: { text: '진행상태' }, mergeCells: true }, + { name: 'statsNm', fieldName: 'statsNm', header: { text: '구분' }, width: 220 }, - // 01. 하수도보급율 (supply) - { name: 'supplyCharger', fieldName: 'supplyCharger', header: { text: '제출자' } }, - { name: 'supplyCttpc', fieldName: 'supplyCttpc', header: { text: '연락처' } }, - { name: 'supplyStatusNm', fieldName: 'supplyStatusNm', header: { text: '지자체진행상태' } }, - { name: 'supplyStatus', fieldName: 'supplyStatus', header: { text: '진행상태' } }, - { name: 'supplyCnt', fieldName: 'supplyCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 02. 하수관로 (facility) - 기존 3번 - { name: 'facilityCharger', fieldName: 'facilityCharger', header: { text: '제출자' } }, - { name: 'facilityCttpc', fieldName: 'facilityCttpc', header: { text: '연락처' } }, - { name: 'facilityStatusNm', fieldName: 'facilityStatusNm', header: { text: '지자체진행상태' } }, - { name: 'facilityStatus', fieldName: 'facilityStatus', header: { text: '진행상태' } }, - { name: 'facilityCnt', fieldName: 'facilityCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 03. 하수관로유지관리 (pipe) - 기존 4번 - { name: 'pipeCharger', fieldName: 'pipeCharger', header: { text: '제출자' } }, - { name: 'pipeCttpc', fieldName: 'pipeCttpc', header: { text: '연락처' } }, - { name: 'pipeStatusNm', fieldName: 'pipeStatusNm', header: { text: '지자체진행상태' } }, - { name: 'pipeCnt', fieldName: 'pipeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 04. 하수저류시설 (storage) - 기존 5번 - { name: 'storageCharger', fieldName: 'storageCharger', header: { text: '제출자' } }, - { name: 'storageCttpc', fieldName: 'storageCttpc', header: { text: '연락처' } }, - { name: 'storageStatusNm', fieldName: 'storageStatusNm', header: { text: '지자체진행상태' } }, - { name: 'storageCnt', fieldName: 'storageCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 05. 펌프장 (pump) - 기존 6번 - { name: 'pumpCharger', fieldName: 'pumpCharger', header: { text: '제출자' } }, - { name: 'pumpCttpc', fieldName: 'pumpCttpc', header: { text: '연락처' } }, - { name: 'pumpStatusNm', fieldName: 'pumpStatusNm', header: { text: '지자체진행상태' } }, - { name: 'pumpCnt', fieldName: 'pumpCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 06. 공공하수처리시설 (treat) - 기존 7번 - { name: 'treatCharger', fieldName: 'treatCharger', header: { text: '제출자' } }, - { name: 'treatCttpc', fieldName: 'treatCttpc', header: { text: '연락처' } }, - { name: 'treatStatusNm', fieldName: 'treatStatusNm', header: { text: '지자체진행상태' } }, - { name: 'treatCnt', fieldName: 'treatCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 07. 분뇨처리시설 (small) - 기존 8번 - { name: 'smallCharger', fieldName: 'smallCharger', header: { text: '제출자' } }, - { name: 'smallCttpc', fieldName: 'smallCttpc', header: { text: '연락처' } }, - { name: 'smallStatusNm', fieldName: 'smallStatusNm', header: { text: '지자체진행상태' } }, - { name: 'smallCnt', fieldName: 'smallCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 08. 개인하수처리시설 (private) - 기존 9번 - { name: 'privateCharger', fieldName: 'privateCharger', header: { text: '제출자' } }, - { name: 'privateCttpc', fieldName: 'privateCttpc', header: { text: '연락처' } }, - { name: 'privateStatusNm', fieldName: 'privateStatusNm', header: { text: '지자체진행상태' } }, - { name: 'privateCnt', fieldName: 'privateCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 09. 하수도재정 (finance) - 기존 10번 - { name: 'financeCharger', fieldName: 'financeCharger', header: { text: '제출자' } }, - { name: 'financeCttpc', fieldName: 'financeCttpc', header: { text: '연락처' } }, - { name: 'financeStatusNm', fieldName: 'financeStatusNm', header: { text: '지자체진행상태' } }, - { name: 'financeCnt', fieldName: 'financeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 10. 물재이용 (reuse) - 기존 11번 - { name: 'reuseCharger', fieldName: 'reuseCharger', header: { text: '제출자' } }, - { name: 'reuseCttpc', fieldName: 'reuseCttpc', header: { text: '연락처' } }, - { name: 'reuseStatusNm', fieldName: 'reuseStatusNm', header: { text: '지자체진행상태' } }, - { name: 'reuseCnt', fieldName: 'reuseCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 11. 하수및분뇨찌꺼기 (sludge) - 기존 12번 - { name: 'sludgeCharger', fieldName: 'sludgeCharger', header: { text: '제출자' } }, - { name: 'sludgeCttpc', fieldName: 'sludgeCttpc', header: { text: '연락처' } }, - { name: 'sludgeStatusNm', fieldName: 'sludgeStatusNm', header: { text: '지자체진행상태' } }, - { name: 'sludgeCnt', fieldName: 'sludgeCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 12. 하수및분뇨관련산업 (excreta) - 기존 13번 - { name: 'excretaCharger', fieldName: 'excretaCharger', header: { text: '제출자' } }, - { name: 'excretaCttpc', fieldName: 'excretaCttpc', header: { text: '연락처' } }, - { name: 'excretaStatusNm', fieldName: 'excretaStatusNm', header: { text: '지자체진행상태' } }, - { name: 'excretaCnt', fieldName: 'excretaCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, - - // 13. 하수도서비스수준 (complaint) - 기존 15번 - { name: 'complaintCharger', fieldName: 'complaintCharger', header: { text: '제출자' } }, - { name: 'complaintCttpc', fieldName: 'complaintCttpc', header: { text: '연락처' } }, - { name: 'complaintStatusNm', fieldName: 'complaintStatusNm', header: { text: '지자체진행상태' } }, - { name: 'complaintCnt', fieldName: 'complaintCnt', header: { text: '건수' }, valueType: ValueType.NUMBER }, + { name: 'chargerNm', fieldName: 'chargerNm', header: { text: '제출자' } }, + { name: 'chargerCttpc', fieldName: 'chargerCttpc', header: { text: '연락처' } }, + { name: 'statusNm', fieldName: 'statusNm', header: { text: '지자체진행상태' } }, + { name: 'statusNm2', fieldName: 'statusNm2', header: { text: '진행상태' } }, ], columnLayout: [ - { name: 'addrGroup', header: { text: '구분' }, items: ['sido', 'gugun'] }, + 'ctpvNm', + 'sggNm', + 'statsNm', 'status', - { name: 'group01', header: { text: '01. 하수도보급율' }, items: ['supplyCharger', 'supplyCttpc', 'supplyStatusNm', 'supplyStatus', 'supplyCnt'] }, - { name: 'group02', header: { text: '02. 하수관로' }, items: ['facilityCharger', 'facilityCttpc', 'facilityStatusNm', 'facilityStatus', 'facilityCnt'] }, - { name: 'group03', header: { text: '03. 하수관로유지관리' }, items: ['pipeCharger', 'pipeCttpc', 'pipeStatusNm', 'pipeCnt'] }, - { name: 'group04', header: { text: '04. 하수저류시설' }, items: ['storageCharger', 'storageCttpc', 'storageStatusNm', 'storageCnt'] }, - { name: 'group05', header: { text: '05. 펌프장' }, items: ['pumpCharger', 'pumpCttpc', 'pumpStatusNm', 'pumpCnt'] }, - { name: 'group06', header: { text: '06. 공공하수처리시설' }, items: ['treatCharger', 'treatCttpc', 'treatStatusNm', 'treatCnt'] }, - { name: 'group07', header: { text: '07. 분뇨처리시설' }, items: ['smallCharger', 'smallCttpc', 'smallStatusNm', 'smallCnt'] }, - { name: 'group08', header: { text: '08. 개인하수처리시설' }, items: ['privateCharger', 'privateCttpc', 'privateStatusNm', 'privateCnt'] }, - { name: 'group09', header: { text: '09. 하수도재정' }, items: ['financeCharger', 'financeCttpc', 'financeStatusNm', 'financeCnt'] }, - { name: 'group10', header: { text: '10. 물재이용' }, items: ['reuseCharger', 'reuseCttpc', 'reuseStatusNm', 'reuseCnt'] }, - { name: 'group11', header: { text: '11. 하수및분뇨찌꺼기' }, items: ['sludgeCharger', 'sludgeCttpc', 'sludgeStatusNm', 'sludgeCnt'] }, - { name: 'group12', header: { text: '12. 하수및분뇨관련산업' }, items: ['excretaCharger', 'excretaCttpc', 'excretaStatusNm', 'excretaCnt'] }, - { name: 'group13', header: { text: '13. 하수도서비스수준' }, items: ['complaintCharger', 'complaintCttpc', 'complaintStatusNm', 'complaintCnt'] } + 'chargerNm', + 'chargerCttpc', + 'statusNm', + 'statusNm2', + 'statsCd', + 'sewerBzmnCd', ] }; diff --git a/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts b/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts new file mode 100644 index 000000000..af6aad7fb --- /dev/null +++ b/apps/st/src/entities/statistics/api/input/statistics-sewage-pipe-input-service.ts @@ -0,0 +1,94 @@ +import { ENDPOINT } from "@/shared/config"; +import { stClient } from "@/shared/api/client"; +import type { + SeweragePipeFacilityAdminAreaListRequest, + SeweragePipeFacilityAdminAreaListResponse, + SeweragePipeFacilitiesListRequest, + SeweragePipeFacilitiesListResponse, + SeweragePipeInputConnectionStatusResponse, + SeweragePipeInputFactInstallResponse, + SeweragePipeInputManholeResponse, + SeweragePipeInputPipeDiameterResponse, + SeweragePipeInputPipeTypeResponse, + SeweragePipeInputRegionalFactStatusSaveRequest, + SeweragePipeInputRegionalFactStatusSaveApiResponse, + SeweragePipeInputRegionalResponse, + SeweragePipeRequestParams, + StatisticsInputSewPipeService, +} from "../../model/input/statistics-sewage-pipe-input-interface"; + +export class StatisticsInputSewPipeApiService implements StatisticsInputSewPipeService { + public async getRegionalFactStatus(param: SeweragePipeRequestParams): Promise { + const response = await stClient.get ( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/regional-facility-status`, + { params: param }, + ); + return response.data; + } + + public async getFactInstallStatus(param: SeweragePipeRequestParams): Promise { + const response = await stClient.get ( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-install-status`, + { params: param }, + ); + return response.data; + } + + public async getPipeTypeStatus(param: SeweragePipeRequestParams): Promise { + const response = await stClient.get ( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-type-status`, + { params: param }, + ); + return response.data; + } + + public async getPipeDiameterStatus(param: SeweragePipeRequestParams): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/pipe-diameter-status`, + { params: param }, + ); + return response.data; + } + + public async getManholeStatus(param: SeweragePipeRequestParams): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/manhole-status`, + { params: param }, + ); + return response.data; + } + + public async getConnectionStatus(param: SeweragePipeRequestParams): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status`, + { params: param }, + ); + return response.data; + } + + public async getFacilitiesList(param: SeweragePipeFacilitiesListRequest): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status/popup/facilities`, + { params: param }, + ); + return response.data; + } + + public async getFacilityAdminAreaList(param: SeweragePipeFacilityAdminAreaListRequest): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/facility-connection-status/popup/areas`, + { params: param }, + ); + return response.data; + } + + public async saveRegionalFactStatus(param: SeweragePipeInputRegionalFactStatusSaveRequest): Promise { + const response = await stClient.post( + `${ENDPOINT.ST_SERVICE.INPUT}/sewage-pipe/regional-facility-status/save`, + param, + ); + return response.data; + } +}; + +export const statisticsInputSewPipeApiService = new StatisticsInputSewPipeApiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/api/statistics-management-service.ts b/apps/st/src/entities/statistics/api/statistics-management-service.ts index 99f7ea552..8c688a2f0 100644 --- a/apps/st/src/entities/statistics/api/statistics-management-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-management-service.ts @@ -36,7 +36,7 @@ export class StatisticsManagementApiService { * @param params (yr, bsnmCd, sido, gugun) */ public async getStatsInputStatusList( - params: { yr?: string; bsnmCd?: string; sido?: string; gugun?: string } + params: { statsYr?: string; sewerBzmnCd?: string; ctpvNm?: string; sggNm?: string } ): Promise { const response = await stClient.get( `${ENDPOINT.ST_SERVICE.REVIEW}/input-status`, diff --git a/apps/st/src/entities/statistics/api/statistics-service.ts b/apps/st/src/entities/statistics/api/statistics-service.ts index 1f2b66bd8..42b5544e6 100644 --- a/apps/st/src/entities/statistics/api/statistics-service.ts +++ b/apps/st/src/entities/statistics/api/statistics-service.ts @@ -9,6 +9,10 @@ import { type cancelSubmitRequest, type cancelSubmitResponse, type ImrRequest, + type SubmitExceptionRequest, + type SubmitExceptionResponse, + type StatisticsLogRequest, + type StatisticsLogResponse, } from "../model/statistics-interface"; export class StatisticsAPiService implements StatisticsService { @@ -27,6 +31,14 @@ export class StatisticsAPiService implements StatisticsService { return response.data; } + public async getSggAllList(sidoName: string): Promise> { + const response = await stClient.get>( + `${ENDPOINT.ST_SERVICE.COMMON}/sgg-all`, + { params: { sidoName } }, + ); + return response.data; + } + // 입력 - 제출 취소 public async cancelSubmit(param: cancelSubmitRequest): Promise { const response = await stClient.put( @@ -43,6 +55,23 @@ export class StatisticsAPiService implements StatisticsService { ); return response.data; } + + // 예외 제출 + public async submitException(param: SubmitExceptionRequest): Promise { + const response = await stClient.post( + `${ENDPOINT.ST_SERVICE.INPUTCOMMON}/submit-exception`, + param + ); + return response.data; + } + + public async getLogList(param: StatisticsLogRequest): Promise { + const response = await stClient.get( + `${ENDPOINT.ST_SERVICE.INPUTCOMMON}/logs`, + { params: param }, + ); + return response.data; + } } export const statisticsAPi = new StatisticsAPiService(); \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts b/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts new file mode 100644 index 000000000..79f9fd1db --- /dev/null +++ b/apps/st/src/entities/statistics/model/input/statistics-sewage-pipe-input-interface.ts @@ -0,0 +1,523 @@ +import type { SewerageSupplyRateSaveApiResponse } from "./statistics-sewage-supply-rate-input-interface"; + +export interface SeweragePipeRequestParams { + ctpvNm?: string; + sggNm?: string; + sewerBzmnCd?: string; + statsYr?: string; + mode?: string; +} + +export interface SeweragePipeInputStatusInfo { + laePicNm: string | null; + laePicTelNo: string | null; + laeKbrdrDeptNm: string | null; + laeKbrdrJbgdNm: string | null; + laeIdfrNm: string | null; + laeIdfrTelNo: string | null; + laeIdfrDeptNm: string | null; + laeIdfrJbgdNm: string | null; + laeSbmsnSttsCd: string | null; + laeSbmsnYmd: string | null; +} + +export interface VerifyResultItem { + vrfcCd: string; + rsnExpln: string; +} + +/** 필드명 -> 검증 결과 배열 */ +export type SeweragePipeInputVerificationResult = Record; + +export interface SeweragePipeInputCommonInfo { + statsYr: string; + ctpvNm: string; + sewerBzmnCd: string; + statsCd: string; + verificationResult?: SeweragePipeInputVerificationResult; +} + +export interface SeweragePipeInputRegionalFactStatusItem { + admdstCd: string; + sggNm: string; + admdstNm: string; + goalYr: string; + + wholPplMtncPlanPrlg: number; + wholPlanPrlg: number; + wholFcltPrlg: number; + swagePplPsplyRt: number; + + cbsysPplMtncPlanArea: number; + cbsysPplMtncPlanPrlg: number; + cbsysPlanPrlg: number; + cbsysFcltPrlg: number; + cbsysSqrePrlg: number; + cbsysCiclPrlg: number; + cbsysOpnPrlg: number; + cbsysGttrPrlg: number; + + drtwPplMtncPlanArea: number; + drtwPplMtncPlanPrlg: number; + drtwPplPlanPrlg: number; + drtwPplFcltPrlg: number; + drtwPplSqrePrlg: number; + drtwPplCiclPrlg: number; + + exlnPplMtncPlanArea: number; + exlnPplMtncPlanPrlg: number; + exlnPplPlanPrlg: number; + exlnPplFcltPrlg: number; + exlnPplSqrePrlg: number; + exlnPplCiclPrlg: number; + exlnPplOpnPrlg: number; + exlnPplGttrPrlg: number; + + cbsysMnhlCnt: number; + sprsysDrtwMnhlCnt: number; + sprsysExlnMnhlCnt: number; + + drtwRcvprpCnt: number; + exlnRcvprpCnt: number; + + stofcbrCnt: number; + exlnOtflCnt: number; + + sewerLdgrEdpPrlg: number; + sewerLdgrEdpRt: number; + + rmrk: string | null; + verificationResult?: SeweragePipeInputVerificationResult; +} + +export interface SeweragePipeInputRegionalResponseData { + statusInfo: SeweragePipeInputStatusInfo; + commonInfo: SeweragePipeInputCommonInfo; + regionalFactStatusList: SeweragePipeInputRegionalFactStatusItem[]; +} + +export interface SeweragePipeInputRegionalResponse { + status: string; + data: SeweragePipeInputRegionalResponseData; + message?: string; +} + +/** 지역별 시설현황(Tab1) 저장 — saveList 행 (검증 결과 제외) */ +export type SeweragePipeInputRegionalFactStatusSaveItem = Omit< + SeweragePipeInputRegionalFactStatusItem, + "verificationResult" +>; + +/** 지역별 시설현황 저장 API 요청 */ +export interface SeweragePipeInputRegionalFactStatusSaveRequest { + statsYr: string; + ctpvNm: string; + sggNm: string; + sewerBzmnCd: string; + userId: string; + superAdmin: string; + saveList: SeweragePipeInputRegionalFactStatusSaveItem[]; +} + +/** 지역별 시설현황 저장 API 응답 — 보급률 저장과 동일 래핑 */ +export type SeweragePipeInputRegionalFactStatusSaveApiResponse = SewerageSupplyRateSaveApiResponse; + +/** 시설별 설치 현황 — 목록 항목 */ +export interface SeweragePipeInputFactInstallStatusItem { + admdstCd: string; + sggNm: string; + admdstNm: string; + prcsFcltSn: number; + swtrmtFcltCd: string; + swtrmtFcltNm: string; + prcsFcltCpct: number; + prcsZoneArea: number; + cbsysPrcsZoneArea: number; + sprsysPrcsZoneArea: number; + sprsysVartnRt: number; + mltvEqpmCnt: number; + cbsysMltvEqpmCnt: number; + sprsysMltvEqpmCnt: number; + sprsysMltvLnkgCnt: number; + sprsysMltvYetLnkgCnt: number; + wholFcltPrlg: number; + wholIcptgAtlfcsPrlg: number; + icptgPrlg: number; + atlfcsPrlg: number; + cbsysStofcbrCnt: number; + sprsysStofcbrCnt: number; + sprsysExlnOtflCnt: number; + wholBrchlnPrlg: number; + cbsysBrchlnPrlg: number; + exlnBrchlnPrlg: number; + drtwBrchlnPrlg: number; + rmrk: string; + verificationResult?: SeweragePipeInputVerificationResult; +} + +/** 시설별 설치 현황 — data 본문 */ +export interface SeweragePipeInputFactInstallResponseData { + statusInfo: SeweragePipeInputStatusInfo; + commonInfo: SeweragePipeInputCommonInfo; + factInstallStatusList: SeweragePipeInputFactInstallStatusItem[]; +} + +/** 시설별 설치 현황 — API 응답 */ +export interface SeweragePipeInputFactInstallResponse { + status: string; + data: SeweragePipeInputFactInstallResponseData; + message?: string; +} + +/** 관종별 현황 — 목록 항목 */ +export interface SeweragePipeInputPipeTypeStatusItem { + admdstCd: string; + sggNm: string; + admdstNm: string; + pipeSeCd: string; + pipeSeNm: string; + pipeByPrstWhol: number; + lyngPrlg: number; + dmltnPrlg: number; + yy1PrlgWhol: number; + yy1LyngPrlg: number; + yy1DmltnPrlg: number; + yy2PrlgWhol: number; + yy2LyngPrlg: number; + yy2DmltnPrlg: number; + yy3PrlgWhol: number; + yy3LyngPrlg: number; + yy3DmltnPrlg: number; + yy4PrlgWhol: number; + yy4LyngPrlg: number; + yy4DmltnPrlg: number; + yy5PrlgWhol: number; + yy5LyngPrlg: number; + yy5DmltnPrlg: number; + yy6PrlgWhol: number; + yy6LyngPrlg: number; + yy6DmltnPrlg: number; + yy7PrlgWhol: number; + yy7LyngPrlg: number; + yy7DmltnPrlg: number; + yy8PrlgWhol: number; + yy8LyngPrlg: number; + yy8DmltnPrlg: number; + yy9PrlgWhol: number; + yy9LyngPrlg: number; + yy9DmltnPrlg: number; + yy10PrlgWhol: number; + yy10LyngPrlg: number; + yy10DmltnPrlg: number; + yy11PrlgWhol: number; + yy11LyngPrlg: number; + yy11DmltnPrlg: number; + yy12PrlgWhol: number; + yy12LyngPrlg: number; + yy12DmltnPrlg: number; + yy13PrlgWhol: number; + yy13LyngPrlg: number; + yy13DmltnPrlg: number; + yy14PrlgWhol: number; + yy14LyngPrlg: number; + yy14DmltnPrlg: number; + yy15PrlgWhol: number; + yy15LyngPrlg: number; + yy15DmltnPrlg: number; + yy16PrlgWhol: number; + yy16LyngPrlg: number; + yy16DmltnPrlg: number; + yy17PrlgWhol: number; + yy17LyngPrlg: number; + yy17DmltnPrlg: number; + yy18PrlgWhol: number; + yy18LyngPrlg: number; + yy18DmltnPrlg: number; + yy19PrlgWhol: number; + yy19LyngPrlg: number; + yy19DmltnPrlg: number; + yy20PrlgWhol: number; + yy20LyngPrlg: number; + yy20DmltnPrlg: number; + yy21PrlgWhol: number; + yy21LyngPrlg: number; + yy21DmltnPrlg: number; + yy22PrlgWhol: number; + yy22LyngPrlg: number; + yy22DmltnPrlg: number; + yy23PrlgWhol: number; + yy23LyngPrlg: number; + yy23DmltnPrlg: number; + yy24PrlgWhol: number; + yy24LyngPrlg: number; + yy24DmltnPrlg: number; + yy25PrlgWhol: number; + yy25LyngPrlg: number; + yy25DmltnPrlg: number; + yy26PrlgWhol: number; + yy26LyngPrlg: number; + yy26DmltnPrlg: number; + yy27PrlgWhol: number; + yy27LyngPrlg: number; + yy27DmltnPrlg: number; + yy28PrlgWhol: number; + yy28LyngPrlg: number; + yy28DmltnPrlg: number; + yy29PrlgWhol: number; + yy29LyngPrlg: number; + yy29DmltnPrlg: number; + yy30PrlgWhol: number; + yy30LyngPrlg: number; + yy30DmltnPrlg: number; + rmrk: string; + verificationResult?: SeweragePipeInputVerificationResult; +} + +/** 관종별 현황 — data 본문 */ +export interface SeweragePipeInputPipeTypeResponseData { + statusInfo: SeweragePipeInputStatusInfo; + commonInfo: SeweragePipeInputCommonInfo; + pipeTypeStatusList: SeweragePipeInputPipeTypeStatusItem[]; +} + +/** 관종별 현황 — API 응답 */ +export interface SeweragePipeInputPipeTypeResponse { + status: string; + data: SeweragePipeInputPipeTypeResponseData; + message?: string; +} + +/** 관경별 현황 — 목록 항목 */ +export interface SeweragePipeInputPipeDiameterStatusItem { + admdstCd: string; + sggNm: string; + admdstNm: string; + pipeSeCd: string; + pipeSeNm: string; + pdmtByTsmWhol: number; + step1PdmtPrlg: number; + step2PdmtPrlg: number; + step3PdmtPrlg: number; + step4PdmtPrlg: number; + step5PdmtPrlg: number; + sqrePdmtPrlg: number; + etcPdmtPrlg: number; + rmrk: string; + verificationResult?: SeweragePipeInputVerificationResult; +} + +/** 관경별 현황 — data 본문 */ +export interface SeweragePipeInputPipeDiameterResponseData { + statusInfo: SeweragePipeInputStatusInfo; + commonInfo: SeweragePipeInputCommonInfo; + pipeDiameterStatusList: SeweragePipeInputPipeDiameterStatusItem[]; +} + +/** 관경별 현황 — API 응답 */ +export interface SeweragePipeInputPipeDiameterResponse { + status: string; + data: SeweragePipeInputPipeDiameterResponseData; + message?: string; +} + +/** 맨홀 현황 — 목록 항목 (yy14=2014년 … yy25=2025년) */ +export interface SeweragePipeInputManholeStatusItem { + sggNm: string; + admdstCd: string; + admdstNm: string; + emphsMngSeNm: string; + totalWholMnhlCnt: number; + totalStep1MnhlCnt: number; + totalStep2MnhlCnt: number; + totalStep3MnhlCnt: number; + totalStep4MnhlCnt: number; + totalStep5MnhlCnt: number; + yy14WholMnhlCnt: number; + yy14Step1MnhlCnt: number; + yy14Step2MnhlCnt: number; + yy14Step3MnhlCnt: number; + yy14Step4MnhlCnt: number; + yy14Step5MnhlCnt: number; + yy15WholMnhlCnt: number; + yy15Step1MnhlCnt: number; + yy15Step2MnhlCnt: number; + yy15Step3MnhlCnt: number; + yy15Step4MnhlCnt: number; + yy15Step5MnhlCnt: number; + yy16WholMnhlCnt: number; + yy16Step1MnhlCnt: number; + yy16Step2MnhlCnt: number; + yy16Step3MnhlCnt: number; + yy16Step4MnhlCnt: number; + yy16Step5MnhlCnt: number; + yy17WholMnhlCnt: number; + yy17Step1MnhlCnt: number; + yy17Step2MnhlCnt: number; + yy17Step3MnhlCnt: number; + yy17Step4MnhlCnt: number; + yy17Step5MnhlCnt: number; + yy18WholMnhlCnt: number; + yy18Step1MnhlCnt: number; + yy18Step2MnhlCnt: number; + yy18Step3MnhlCnt: number; + yy18Step4MnhlCnt: number; + yy18Step5MnhlCnt: number; + yy19WholMnhlCnt: number; + yy19Step1MnhlCnt: number; + yy19Step2MnhlCnt: number; + yy19Step3MnhlCnt: number; + yy19Step4MnhlCnt: number; + yy19Step5MnhlCnt: number; + yy20WholMnhlCnt: number; + yy20Step1MnhlCnt: number; + yy20Step2MnhlCnt: number; + yy20Step3MnhlCnt: number; + yy20Step4MnhlCnt: number; + yy20Step5MnhlCnt: number; + yy21WholMnhlCnt: number; + yy21Step1MnhlCnt: number; + yy21Step2MnhlCnt: number; + yy21Step3MnhlCnt: number; + yy21Step4MnhlCnt: number; + yy21Step5MnhlCnt: number; + yy22WholMnhlCnt: number; + yy22Step1MnhlCnt: number; + yy22Step2MnhlCnt: number; + yy22Step3MnhlCnt: number; + yy22Step4MnhlCnt: number; + yy22Step5MnhlCnt: number; + yy23WholMnhlCnt: number; + yy23Step1MnhlCnt: number; + yy23Step2MnhlCnt: number; + yy23Step3MnhlCnt: number; + yy23Step4MnhlCnt: number; + yy23Step5MnhlCnt: number; + yy24WholMnhlCnt: number; + yy24Step1MnhlCnt: number; + yy24Step2MnhlCnt: number; + yy24Step3MnhlCnt: number; + yy24Step4MnhlCnt: number; + yy24Step5MnhlCnt: number; + yy25WholMnhlCnt: number; + yy25Step1MnhlCnt: number; + yy25Step2MnhlCnt: number; + yy25Step3MnhlCnt: number; + yy25Step4MnhlCnt: number; + yy25Step5MnhlCnt: number; + rmrk: string; + verificationResult?: SeweragePipeInputVerificationResult; +} + +/** 맨홀 현황 — data 본문 */ +export interface SeweragePipeInputManholeResponseData { + statusInfo: SeweragePipeInputStatusInfo; + commonInfo: SeweragePipeInputCommonInfo; + manholeStatusList: SeweragePipeInputManholeStatusItem[]; +} + +/** 맨홀 현황 — API 응답 */ +export interface SeweragePipeInputManholeResponse { + status: string; + data: SeweragePipeInputManholeResponseData; + message?: string; +} + +/** 시설별 현황 관리 - 하수처리장별 연결 현황 목록 항목 */ +export interface SeweragePipeInputFacilityConnectionItem { + bscFctNm: string; + fctCpc: number; + bscFctCd: string; + isConnection: string; + connectionAreaList: string; +} + +/** 시설별 현황 관리 - 행정구역별 연결 현황 목록 항목 */ +export interface SeweragePipeInputAdminAreaConnectionItem { + ctpvNm: string; + sggNm: string; + admdstNm: string; + admdstCd: string; + isConnection: string; + connectionBscFctNmList: string; +} + +/** 시설별 현황 관리 — data 본문 */ +export interface SeweragePipeInputConnectionStatusResponseData { + statusInfo: SeweragePipeInputStatusInfo; + commonInfo: SeweragePipeInputCommonInfo; + facilityConnectionList: SeweragePipeInputFacilityConnectionItem[]; + adminAreaConnectionList: SeweragePipeInputAdminAreaConnectionItem[]; +} + +/** 시설별 현황 관리 — API 응답 */ +export interface SeweragePipeInputConnectionStatusResponse { + status: string; + data: SeweragePipeInputConnectionStatusResponseData; + message?: string; +} + +/** facilitiesList 요청 — statsYr 필수, 나머지 선택 */ +export interface SeweragePipeFacilitiesListRequest { + statsYr: string; + sewerBzmnCd?: string; + ctpvNm?: string; + sggNm?: string; + fcltyNm?: string; +} + +/** facilitiesList 응답 — 목록 항목 */ +export interface SeweragePipeFacilitiesListItem { + statsYr: string; + ctpvNm: string; + sggNm: string; + admdstCd: string; + bscFctNm: string; + fctCpc: number; + bscFctCd: string; +} + +/** facilitiesList API 응답 */ +export interface SeweragePipeFacilitiesListResponse { + status: string; + data: SeweragePipeFacilitiesListItem[]; + message?: string; +} + +/** 처리시설 선택 후 행정구역(연결) 목록 조회 요청 */ +export interface SeweragePipeFacilityAdminAreaListRequest { + statsYr: string; + swtrmtFcltCd: string; + sewerBzmnCd: string; + ctpvNm: string; + sggNm: string; +} + +/** 처리시설별 행정구역 목록 항목 */ +export interface SeweragePipeFacilityAdminAreaItem { + ctpvNm: string; + sggNm: string; + admdstNm: string; + admdstCd: string; + isConnection: string; +} + +/** 처리시설별 행정구역 목록 API 응답 */ +export interface SeweragePipeFacilityAdminAreaListResponse { + status: string; + data: SeweragePipeFacilityAdminAreaItem[]; + message?: string; +} + +export interface StatisticsInputSewPipeService { + getRegionalFactStatus(param: SeweragePipeRequestParams): Promise; + getFactInstallStatus(param: SeweragePipeRequestParams): Promise; + getPipeTypeStatus(param: SeweragePipeRequestParams): Promise; + getPipeDiameterStatus(param: SeweragePipeRequestParams): Promise; + getManholeStatus(param: SeweragePipeRequestParams): Promise; + getConnectionStatus(param: SeweragePipeRequestParams): Promise; + getFacilitiesList(param: SeweragePipeFacilitiesListRequest): Promise; + getFacilityAdminAreaList(param: SeweragePipeFacilityAdminAreaListRequest): Promise; + saveRegionalFactStatus( + param: SeweragePipeInputRegionalFactStatusSaveRequest, + ): Promise; +} \ No newline at end of file diff --git a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts index ff86a8799..e2515fccb 100644 --- a/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-input-review-interface.ts @@ -4,92 +4,16 @@ import type { ApiResponse } from "./statistics-interface"; * 검토-00.통계 입력현황 아이템 인터페이스 */ export interface StatsInputStatusReviewItem { - chk: string; - sido: string; - gugun: string; - yr: string; - bsnmCd: string; - status: string; - - // 01. 하수도보급율 (supply) - supplyCharger: string; - supplyCttpc: string; - supplyStatusNm: string; - supplyStatus: string; - supplyCnt: number; - - // 02. 하수관로 (facility - 기존 3번) - facilityCharger: string; - facilityCttpc: string; - facilityStatusNm: string; - facilityStatus: string; - facilityCnt: number; - - // 03. 하수관로유지관리 (pipe - 기존 4번) - pipeCharger: string; - pipeCttpc: string; - pipeStatusNm: string; - pipeCnt: number; - - // 04. 하수저류시설 (storage - 기존 5번) - storageCharger: string; - storageCttpc: string; - storageStatusNm: string; - storageCnt: number; - - // 05. 펌프장 (pump - 기존 6번) - pumpCharger: string; - pumpCttpc: string; - pumpStatusNm: string; - pumpCnt: number; - - // 06. 공공하수처리시설 (treat - 기존 7번) - treatCharger: string; - treatCttpc: string; - treatStatusNm: string; - treatCnt: number; - - // 07. 분뇨처리시설 (small - 기존 8번) - smallCharger: string; - smallCttpc: string; - smallStatusNm: string; - smallCnt: number; - - // 08. 개인하수처리시설 (private - 기존 9번) - privateCharger: string; - privateCttpc: string; - privateStatusNm: string; - privateCnt: number; - - // 09. 하수도재정 (finance - 기존 10번) - financeCharger: string; - financeCttpc: string; - financeStatusNm: string; - financeCnt: number; - - // 10. 물재이용 (reuse - 기존 11번) - reuseCharger: string; - reuseCttpc: string; - reuseStatusNm: string; - reuseCnt: number; - - // 11. 하수및분뇨찌꺼기 (sludge - 기존 12번) - sludgeCharger: string; - sludgeCttpc: string; - sludgeStatusNm: string; - sludgeCnt: number; - - // 12. 하수및분뇨관련산업 (excreta - 기존 13번) - excretaCharger: string; - excretaCttpc: string; - excretaStatusNm: string; - excretaCnt: number; - - // 13. 하수도서비스수준 (complaint - 기존 15번) - complaintCharger: string; - complaintCttpc: string; - complaintStatusNm: string; - complaintCnt: number; + ctpvNm?: string; + sggNm?: string; + sewerBzmnCd?: string; + status?: string; + statsNm?: string; + statsCd?: string; + statusNm?: string; + statusCd?: string; + chargerNm?: string; + chargerCttpc?: string; } export interface StatsInputStatusReviewResponseData { diff --git a/apps/st/src/entities/statistics/model/statistics-interface.ts b/apps/st/src/entities/statistics/model/statistics-interface.ts index 5a2b9eab5..f32f7ef4f 100644 --- a/apps/st/src/entities/statistics/model/statistics-interface.ts +++ b/apps/st/src/entities/statistics/model/statistics-interface.ts @@ -43,9 +43,65 @@ export interface ImrRequest { lae_sbmsn_stts_cd: string; } +export interface SubmitExceptionRequest { + statsYr: string; + statsCd: string; + ctpvNm: string; + sggNm: string; + sewerBzmnCd: string; + userId: string; + superAdmin?: string; + laePicNm: string; + laePicTelNo: string; + laeKbrdrDeptNm: string; + laeKbrdrJbgdNm: string; + laeIdfrNm: string; + laeIdfrTelNo: string; + laeIdfrDeptNm: string; + laeIdfrJbgdNm: string +} + +export interface SubmitExceptionResponse { + status: string; + message?: string; +} + +export interface StatisticsLog { + statsLogSn?: number; + menuNm?: string; + tabNm?: string; + tblNm?: string; + dmndFwkNm?: string; + rgtrId?: string; + regDt?: string; +} + +export interface StatisticsLogRequest { + page: number; + size: number; + statsCd?: string; +} + +export interface StatisticsLogResponse { + status: string; + message?: string; + data?: { + statsLogList: StatisticsLog[]; + pageInfo: { + totalElements: number; + totalPages: number; + currentPage: number; + size: number; + }; + }; +} + export interface StatisticsService { getSidoList(): Promise>; getSggList(sidoName: string): Promise>; + getSggAllList(sidoName: string): Promise>; cancelSubmit(param: cancelSubmitRequest): Promise; callImrService(param: ImrRequest): Promise; + submitException(param: SubmitExceptionRequest): Promise; + getLogList(param: StatisticsLogRequest): Promise; } \ No newline at end of file