Merge remote-tracking branch 'origin/iipbs/st/dev'
This commit is contained in:
@@ -955,7 +955,7 @@ const DataGrid = ({
|
||||
try {
|
||||
gv.commit?.();
|
||||
} catch {
|
||||
/* ignore */
|
||||
console.error('commit error');
|
||||
}
|
||||
const ds = gv.getDataSource();
|
||||
if (!ds) return rowDataRef.current.map((r) => ({ ...r }));
|
||||
@@ -1954,7 +1954,7 @@ useEffect(() => {
|
||||
}
|
||||
| undefined;
|
||||
if (!gv?.getDataSource) return [];
|
||||
try { gv.commit?.(); } catch { /* ignore */ }
|
||||
try { gv.commit?.(); } catch { console.error('commit error'); }
|
||||
const ds = gv.getDataSource();
|
||||
if (!ds) return [];
|
||||
const cnt = ds.getRowCount();
|
||||
@@ -2022,7 +2022,7 @@ useEffect(() => {
|
||||
column.footer.styleName = styleName;
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
console.error('총계 스타일 재적용/초기화 error');
|
||||
}
|
||||
});
|
||||
gridView.refresh?.();
|
||||
|
||||
@@ -236,12 +236,13 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
const sggOptions = sggList?.data ?? [];
|
||||
const isDoSelected = isDoSido(selectedSido);
|
||||
const firstConcreteSggOption = firstConcreteSgg(sggOptions);
|
||||
// 도: 빈 값일 때만 첫 시군구로 보이게. ALL은 사용자가 고른 전체 유지
|
||||
const gugunSelectValue =
|
||||
isDoSelected && isAllGugunValue(values.gugun)
|
||||
isDoSelected && !values.gugun
|
||||
? (firstConcreteSggOption?.gugun ?? undefined)
|
||||
: values.gugun || undefined;
|
||||
|
||||
// 도: 전체(ALL/"")가 아니라 그 다음 시군구. 그 외: 전체
|
||||
// 도: 초기/시도 변경(빈 값)만 첫 시군구. 전체(ALL)는 유지. 그 외: 전체
|
||||
useEffect(() => {
|
||||
if (!mergedProps.gugun) return;
|
||||
if (props.defaultRegionAll) return;
|
||||
@@ -263,7 +264,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
if (!firstConcreteSggOption) return;
|
||||
|
||||
setValues((prev) => {
|
||||
if (!isAllGugunValue(prev.gugun)) return prev;
|
||||
if (prev.gugun) return prev;
|
||||
return {
|
||||
...prev,
|
||||
gugun: firstConcreteSggOption.gugun,
|
||||
|
||||
@@ -104,7 +104,7 @@ function safeGridViewRefresh(gv: { refresh?: () => void } | null | undefined) {
|
||||
try {
|
||||
gv.refresh();
|
||||
} catch {
|
||||
/* noop */
|
||||
console.error('refresh error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ function setRowCheckByItemIndex(
|
||||
try {
|
||||
gv?.checkItem?.(itemIndex, checked, false);
|
||||
} catch {
|
||||
/* RealGrid 체크 API 미지원 등 */
|
||||
console.error('RealGrid 체크 API error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ function uncheckGridRow(gridRef: MutableRefObject<RealGridReact | null>, itemInd
|
||||
try {
|
||||
(gridRef.current?.gridView as GridViewWithCheckApi | undefined)?.checkItem?.(itemIndex, false, false);
|
||||
} catch {
|
||||
/* ignore */
|
||||
console.error('RealGrid 체크 API error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,7 @@ import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import type {
|
||||
SeweragePipeInputFactInstallStatusSaveRequest,
|
||||
SeweragePipeInputFactInstallStatusSubmitRequest,
|
||||
SeweragePipeInputManholeStatusItem,
|
||||
SeweragePipeInputManholeStatusSaveRequest,
|
||||
SeweragePipeInputManholeStatusSaveYearlyStatItem,
|
||||
SeweragePipeInputManholeStatusSubmitRequest,
|
||||
SeweragePipeInputPipeDiameterStatusSaveRequest,
|
||||
SeweragePipeInputPipeDiameterStatusSubmitRequest,
|
||||
@@ -221,11 +219,6 @@ const applyPipeTypeStatusEditableColumns = (
|
||||
});
|
||||
};
|
||||
|
||||
const getManholeLastDataYear = () => {
|
||||
const lastDataYear = new Date().getFullYear() - 1;
|
||||
return Math.max(2014, lastDataYear);
|
||||
};
|
||||
|
||||
/** 2-3 관종별: verificationResult.prlgWhol → 총계 계(pipeByPrstWhol) */
|
||||
function remapPipeTypePrlgWholVerification(
|
||||
result?: SeweragePipeInputVerificationResult | null,
|
||||
@@ -280,43 +273,6 @@ function normalizePipeTypeStatusRow(
|
||||
};
|
||||
}
|
||||
|
||||
/** 맨홀 신 응답(yearlyStats) -> 그리드 yy{14..25}* 필드로 정규화 */
|
||||
function normalizeManholeStatusRow(
|
||||
row: SeweragePipeInputManholeStatusItem,
|
||||
ctpvNm: string,
|
||||
): Record<string, string | number | SeweragePipeInputVerificationResult | undefined> {
|
||||
const maxYy = getManholeLastDataYear() % 100;
|
||||
const { yearlyStats, ...rest } = row;
|
||||
const yearFields: Record<string, number> = {};
|
||||
for (let yy = 14; yy <= maxYy; yy++) {
|
||||
yearFields[`yy${yy}WholMnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step1MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step2MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step3MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step4MnhlCnt`] = 0;
|
||||
yearFields[`yy${yy}Step5MnhlCnt`] = 0;
|
||||
}
|
||||
|
||||
for (const y of yearlyStats ?? []) {
|
||||
const year = Number(y.manhYr);
|
||||
if (!Number.isFinite(year)) continue;
|
||||
const yy = year % 100;
|
||||
if (yy < 14 || yy > maxYy) continue;
|
||||
yearFields[`yy${yy}WholMnhlCnt`] = Number(y.wholMnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step1MnhlCnt`] = Number(y.step1MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step2MnhlCnt`] = Number(y.step2MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step3MnhlCnt`] = Number(y.step3MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step4MnhlCnt`] = Number(y.step4MnhlCnt ?? 0);
|
||||
yearFields[`yy${yy}Step5MnhlCnt`] = Number(y.step5MnhlCnt ?? 0);
|
||||
}
|
||||
|
||||
return {
|
||||
ctpvNm,
|
||||
...rest,
|
||||
...yearFields,
|
||||
};
|
||||
}
|
||||
|
||||
/** ST00020006(연결)은 행이 좌·우 그리드 키에만 있음 */
|
||||
type GridRowWithVerification = Record<string, string | number> & {
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
@@ -884,9 +840,10 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = filterFetched(response.data.manholeStatusList).map((d) =>
|
||||
normalizeManholeStatusRow(d, commonInfo.ctpvNm),
|
||||
);
|
||||
const convertedData = filterFetched(response.data.manholeStatusList).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
applyRowMap((m) => m.set('ST00020005', toGridRows(convertedData)));
|
||||
setTabStatusInfoMap((prev) => new Map(prev).set(tabKey, response.data.statusInfo));
|
||||
setTabStatsCdMap((prev) => new Map(prev).set(tabKey, commonInfo.statsCd));
|
||||
@@ -1434,36 +1391,17 @@ const SewagePipeInp = () => {
|
||||
const decimalPlaces = format.match(/\.(\d+)/)?.[1]?.length ?? 0;
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
const minYy = 14;
|
||||
const maxYy = getManholeLastDataYear() % 100;
|
||||
const submitList = currentData.map((d) => {
|
||||
const yearlyStats: SeweragePipeInputManholeStatusSaveYearlyStatItem[] = [];
|
||||
for (let yy = minYy; yy <= maxYy; yy++) {
|
||||
const year = 2000 + yy;
|
||||
const wholKey = `yy${yy}WholMnhlCnt`;
|
||||
const step1Key = `yy${yy}Step1MnhlCnt`;
|
||||
const step2Key = `yy${yy}Step2MnhlCnt`;
|
||||
const step3Key = `yy${yy}Step3MnhlCnt`;
|
||||
const step4Key = `yy${yy}Step4MnhlCnt`;
|
||||
const step5Key = `yy${yy}Step5MnhlCnt`;
|
||||
yearlyStats.push({
|
||||
manhYr: String(year),
|
||||
wholMnhlCnt: formatNumber(d[wholKey] as string | number | undefined, wholKey),
|
||||
step1MnhlCnt: formatNumber(d[step1Key] as string | number | undefined, step1Key),
|
||||
step2MnhlCnt: formatNumber(d[step2Key] as string | number | undefined, step2Key),
|
||||
step3MnhlCnt: formatNumber(d[step3Key] as string | number | undefined, step3Key),
|
||||
step4MnhlCnt: formatNumber(d[step4Key] as string | number | undefined, step4Key),
|
||||
step5MnhlCnt: formatNumber(d[step5Key] as string | number | undefined, step5Key),
|
||||
});
|
||||
}
|
||||
return {
|
||||
emphsMngSeCd: nullableTrimmedString(d.emphsMngSeCd),
|
||||
admdstCd: nullableTrimmedString(d.admdstCd),
|
||||
admdstNm: nullableTrimmedString(d.admdstNm),
|
||||
yearlyStats,
|
||||
rmrk: nullableTrimmedString(d.rmrk),
|
||||
};
|
||||
});
|
||||
const submitList = currentData.map((d) => ({
|
||||
admdstCd: nullableTrimmedString(d.admdstCd),
|
||||
admdstNm: nullableTrimmedString(d.admdstNm),
|
||||
emphsMngSeCd: nullableTrimmedString(d.emphsMngSeCd),
|
||||
frlvlMnhlCnt: formatNumber(d.frlvlMnhlCnt, "frlvlMnhlCnt"),
|
||||
sclvlMnhlCnt: formatNumber(d.sclvlMnhlCnt, "sclvlMnhlCnt"),
|
||||
thlvlMnhlCnt: formatNumber(d.thlvlMnhlCnt, "thlvlMnhlCnt"),
|
||||
folvlMnhlCnt: formatNumber(d.folvlMnhlCnt, "folvlMnhlCnt"),
|
||||
filvlMnhlCnt: formatNumber(d.filvlMnhlCnt, "filvlMnhlCnt"),
|
||||
rmrk: nullableTrimmedString(d.rmrk),
|
||||
}));
|
||||
const requestData: SeweragePipeInputManholeStatusSubmitRequest = {
|
||||
...submitBase,
|
||||
submitList,
|
||||
@@ -1989,37 +1927,17 @@ const SewagePipeInp = () => {
|
||||
return decimalPlaces > 0 ? parseFloat(num.toFixed(decimalPlaces)) : Math.round(num);
|
||||
};
|
||||
|
||||
const minYy = 14;
|
||||
const maxYy = getManholeLastDataYear() % 100;
|
||||
|
||||
const saveList = currentData.map((d) => {
|
||||
const yearlyStats: SeweragePipeInputManholeStatusSaveYearlyStatItem[] = [];
|
||||
for (let yy = minYy; yy <= maxYy; yy++) {
|
||||
const year = 2000 + yy;
|
||||
const wholKey = `yy${yy}WholMnhlCnt`;
|
||||
const step1Key = `yy${yy}Step1MnhlCnt`;
|
||||
const step2Key = `yy${yy}Step2MnhlCnt`;
|
||||
const step3Key = `yy${yy}Step3MnhlCnt`;
|
||||
const step4Key = `yy${yy}Step4MnhlCnt`;
|
||||
const step5Key = `yy${yy}Step5MnhlCnt`;
|
||||
yearlyStats.push({
|
||||
manhYr: String(year),
|
||||
wholMnhlCnt: formatNumber(d[wholKey] as string | number | undefined, wholKey),
|
||||
step1MnhlCnt: formatNumber(d[step1Key] as string | number | undefined, step1Key),
|
||||
step2MnhlCnt: formatNumber(d[step2Key] as string | number | undefined, step2Key),
|
||||
step3MnhlCnt: formatNumber(d[step3Key] as string | number | undefined, step3Key),
|
||||
step4MnhlCnt: formatNumber(d[step4Key] as string | number | undefined, step4Key),
|
||||
step5MnhlCnt: formatNumber(d[step5Key] as string | number | undefined, step5Key),
|
||||
});
|
||||
}
|
||||
return {
|
||||
emphsMngSeCd: nullableTrimmedString(d.emphsMngSeCd),
|
||||
admdstCd: nullableTrimmedString(d.admdstCd),
|
||||
admdstNm: nullableTrimmedString(d.admdstNm),
|
||||
yearlyStats,
|
||||
rmrk: nullableTrimmedString(d.rmrk),
|
||||
};
|
||||
});
|
||||
const saveList = currentData.map((d) => ({
|
||||
admdstCd: nullableTrimmedString(d.admdstCd),
|
||||
admdstNm: nullableTrimmedString(d.admdstNm),
|
||||
emphsMngSeCd: nullableTrimmedString(d.emphsMngSeCd),
|
||||
frlvlMnhlCnt: formatNumber(d.frlvlMnhlCnt, "frlvlMnhlCnt"),
|
||||
sclvlMnhlCnt: formatNumber(d.sclvlMnhlCnt, "sclvlMnhlCnt"),
|
||||
thlvlMnhlCnt: formatNumber(d.thlvlMnhlCnt, "thlvlMnhlCnt"),
|
||||
folvlMnhlCnt: formatNumber(d.folvlMnhlCnt, "folvlMnhlCnt"),
|
||||
filvlMnhlCnt: formatNumber(d.filvlMnhlCnt, "filvlMnhlCnt"),
|
||||
rmrk: nullableTrimmedString(d.rmrk),
|
||||
}));
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const param: SeweragePipeInputManholeStatusSaveRequest = {
|
||||
|
||||
@@ -103,7 +103,7 @@ export function ReviewOpinionDialog({
|
||||
resetForm();
|
||||
onOpenChange(false);
|
||||
} catch {
|
||||
/* 저장 실패 시 부모에서 alert 후 throw — 다이얼로그는 유지 */
|
||||
console.error('검토 의견 저장 error');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import type {
|
||||
ColumnLayoutItem,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { getST00020003RvwConfig, getST00020005RvwConfig,SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeRvwColumn";
|
||||
import { getST00020003RvwConfig,SewagePipeColumnInfoListRvw } from "@/components/util/column/review/SewagePipeRvwColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { buildReviewCellStyleCallbackByTab } from "@/components/util/grid/reviewEmptyCurrCellStyle";
|
||||
|
||||
@@ -151,11 +151,9 @@ const SewagePipeRvw = () => {
|
||||
() => {
|
||||
const statsYr = lastSearchValues?.year ?? new Date().getFullYear();
|
||||
const st00020003Config = getST00020003RvwConfig(statsYr);
|
||||
const st00020005Config = getST00020005RvwConfig(statsYr);
|
||||
return SewagePipeColumnInfoListRvw.map((tab) => {
|
||||
const source =
|
||||
tab.tabKey === "ST00020003" ? st00020003Config
|
||||
: tab.tabKey === "ST00020005" ? st00020005Config
|
||||
: tab;
|
||||
return {
|
||||
...source,
|
||||
|
||||
@@ -11,7 +11,7 @@ import DataGrid from "@/components/module/DataGrid";
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import type { ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { getST00020003Config, getST00020005Config,SewagePipeColumnInfoListTot } from "@/components/util/column/total/SewagePipeTotColumn";
|
||||
import { getST00020003Config, SewagePipeColumnInfoListTot } from "@/components/util/column/total/SewagePipeTotColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
|
||||
const firstTabKey = SewagePipeColumnInfoListTot[0]?.tabKey ?? "ST00020001";
|
||||
@@ -205,12 +205,10 @@ const SewagePipeTot = () => {
|
||||
{columnInfo.map((info) => {
|
||||
const tabKey = info.tabKey;
|
||||
|
||||
// ★ [동적 처리] ST00020003·ST00020005는 함수를 통해 컬럼 정보를 실시간으로 생성
|
||||
// ★ [동적 처리] ST00020003은 함수를 통해 컬럼 정보를 실시간으로 생성
|
||||
const currentYear = lastSearchedValuesRef.current?.year || new Date().getFullYear();
|
||||
const finalTabConfig =
|
||||
tabKey === "ST00020003" ? getST00020003Config(currentYear) :
|
||||
tabKey === "ST00020005" ? getST00020005Config(currentYear) :
|
||||
info;
|
||||
tabKey === "ST00020003" ? getST00020003Config(currentYear) : info;
|
||||
|
||||
if (!finalTabConfig.columns || !finalTabConfig.columnLayout) {
|
||||
return null;
|
||||
|
||||
@@ -9,7 +9,12 @@ import { useAlertStore } from "@/shared/lib";
|
||||
import { NoData } from "@/shared/ui/no-data";
|
||||
import { CodeSelectWithAll } from "@/entities/code";
|
||||
import { generalverificationApiService } from "@/entities/statistics/api/general-verification-service";
|
||||
import { statisticsInputSewSupplyRateApi } from "@/entities/statistics/api/input/statistics-input-sew-supply-rate-service";
|
||||
import type { GeneralverificationList } from "@/entities/statistics/model/general-verification-interface";
|
||||
import {
|
||||
getInputPeriodVerificationManageBlockedMessage,
|
||||
isInputPeriodCurrent,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import {
|
||||
Button,
|
||||
DataTable,
|
||||
@@ -47,6 +52,10 @@ const GeneralVerificationManagement = () => {
|
||||
const [isExporting, setIsExporting] = useState<boolean>(false);
|
||||
const [selectedVrfcRow, setSelectedVrfcRow] = useState<number | null>(null);
|
||||
const [showRegistForm, setShowRegistForm] = useState<boolean>(false);
|
||||
const [inputPeriodBlocked, setInputPeriodBlocked] = useState(false);
|
||||
const [inputPeriodBlockedMessage, setInputPeriodBlockedMessage] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
|
||||
@@ -91,8 +100,18 @@ const GeneralVerificationManagement = () => {
|
||||
};
|
||||
|
||||
const columns = useMemo(
|
||||
() => getGeneralVerificationColumns(() => handleSearch()),
|
||||
[searchValues.statsCd, searchValues.vrfcClsfCd, searchValues.useYn],
|
||||
() =>
|
||||
getGeneralVerificationColumns(() => handleSearch(), {
|
||||
mutationBlocked: inputPeriodBlocked,
|
||||
blockedMessage: inputPeriodBlockedMessage,
|
||||
}),
|
||||
[
|
||||
searchValues.statsCd,
|
||||
searchValues.vrfcClsfCd,
|
||||
searchValues.useYn,
|
||||
inputPeriodBlocked,
|
||||
inputPeriodBlockedMessage,
|
||||
],
|
||||
);
|
||||
|
||||
const table = useReactTable({
|
||||
@@ -162,6 +181,24 @@ const GeneralVerificationManagement = () => {
|
||||
|
||||
useEffect(() => {
|
||||
void handleSearch();
|
||||
void (async () => {
|
||||
try {
|
||||
const statsYr = String(new Date().getFullYear() - 1);
|
||||
const response =
|
||||
await statisticsInputSewSupplyRateApi.checkInputPeriod(statsYr);
|
||||
if (response.status !== "success") return;
|
||||
const blocked = isInputPeriodCurrent(response.data);
|
||||
setInputPeriodBlocked(blocked);
|
||||
setInputPeriodBlockedMessage(
|
||||
blocked
|
||||
? getInputPeriodVerificationManageBlockedMessage(response.data)
|
||||
: null,
|
||||
);
|
||||
} catch {
|
||||
setInputPeriodBlocked(false);
|
||||
setInputPeriodBlockedMessage(null);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@@ -263,13 +300,25 @@ const GeneralVerificationManagement = () => {
|
||||
<i className="diveicon di-file-excel" />
|
||||
<span>내보내기</span>
|
||||
</Button>
|
||||
<RegistDialog
|
||||
open={showRegistForm}
|
||||
onOpenChange={setShowRegistForm}
|
||||
onSuccess={() => void handleSearch()}
|
||||
>
|
||||
<Button>등록</Button>
|
||||
</RegistDialog>
|
||||
{inputPeriodBlocked ? (
|
||||
<span
|
||||
title={
|
||||
inputPeriodBlockedMessage ?? undefined
|
||||
}
|
||||
>
|
||||
<Button disabled type="button">
|
||||
등록
|
||||
</Button>
|
||||
</span>
|
||||
) : (
|
||||
<RegistDialog
|
||||
open={showRegistForm}
|
||||
onOpenChange={setShowRegistForm}
|
||||
onSuccess={() => void handleSearch()}
|
||||
>
|
||||
<Button>등록</Button>
|
||||
</RegistDialog>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="card !mx-2 !my-4 h-full overflow-auto !p-0">
|
||||
@@ -294,7 +343,11 @@ const GeneralVerificationManagement = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<DetailComponent selectedVrfcRow={selectedVrfcRow} />
|
||||
<DetailComponent
|
||||
selectedVrfcRow={selectedVrfcRow}
|
||||
mutationBlocked={inputPeriodBlocked}
|
||||
blockedMessage={inputPeriodBlockedMessage}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
+76
-2
@@ -391,9 +391,15 @@ const buildRuleBlocksFromFormulas = (
|
||||
|
||||
interface DetailComponentProps {
|
||||
selectedVrfcRow: number | null;
|
||||
mutationBlocked?: boolean;
|
||||
blockedMessage?: string | null;
|
||||
}
|
||||
|
||||
const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
const DetailComponent = ({
|
||||
selectedVrfcRow,
|
||||
mutationBlocked = false,
|
||||
blockedMessage = null,
|
||||
}: DetailComponentProps) => {
|
||||
const [detailInfo, setDetailInfo] = useState<VerifyDetailData | null>(null);
|
||||
/** 수식 / 조건·논리 연산자를 순서대로 담는 UI 블록 (서로 강제 교차하지 않음) */
|
||||
const [ruleBlocks, setRuleBlocks] = useState<RuleBlock[]>([
|
||||
@@ -487,6 +493,13 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
};
|
||||
|
||||
const handleSaveClick = async () => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
const trgtStatsCd = detailInfo?.commonInfo.trgtStatsCd;
|
||||
if (!trgtStatsCd) {
|
||||
alert("대상 통계항목(trgtStatsCd) 정보가 없습니다.");
|
||||
@@ -623,6 +636,13 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
formula?: VerifyDetailResponseDto | null,
|
||||
blockId?: string,
|
||||
) => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
setSelectedFormula(formula ?? null);
|
||||
setSelectedFormulaBlockId(blockId ?? null);
|
||||
setShowFomulaDialog(true);
|
||||
@@ -671,6 +691,13 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
};
|
||||
|
||||
const handleResetClick = async () => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
const currentSignature = JSON.stringify(
|
||||
normalizeFormulaListForCompare(formulaList, groupByFlags),
|
||||
);
|
||||
@@ -689,6 +716,13 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
};
|
||||
|
||||
const handleAddClause = () => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
setRuleBlocks((prev) => [
|
||||
...prev,
|
||||
{
|
||||
@@ -702,6 +736,13 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
|
||||
/** 항상 목록 맨 뒤(마지막 수식 뒤 포함)에 조건·논리 연산자 Select 추가 */
|
||||
const handleAddConnector = () => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (connectorOperators.length === 0) {
|
||||
alert("조건·논리 연산자 목록을 불러오지 못했습니다.");
|
||||
return;
|
||||
@@ -720,6 +761,13 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
};
|
||||
|
||||
const handleRemoveBlock = (blockId: string) => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
setRuleBlocks((prev) => {
|
||||
const next = prev.filter((b) => b.id !== blockId);
|
||||
if (next.some((b) => b.kind === "formula")) return next;
|
||||
@@ -831,6 +879,7 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
<div className="h-px flex-1 bg-[#e2e5ea]" />
|
||||
<Select
|
||||
value={block.value}
|
||||
disabled={mutationBlocked}
|
||||
onValueChange={(v) => {
|
||||
setRuleBlocks(
|
||||
(prev) => {
|
||||
@@ -907,6 +956,7 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
size="icon"
|
||||
color="red"
|
||||
className="size-[3.2rem] shrink-0 rounded-full"
|
||||
disabled={mutationBlocked}
|
||||
onClick={() =>
|
||||
handleRemoveBlock(
|
||||
block.id,
|
||||
@@ -933,6 +983,7 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
blockIndex,
|
||||
)}
|
||||
groupBy={block.groupBy}
|
||||
disabled={mutationBlocked}
|
||||
onGroupByChange={(
|
||||
checked,
|
||||
) => {
|
||||
@@ -1045,6 +1096,12 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
<Button
|
||||
type="button"
|
||||
className="h-[3.6rem] gap-1.5 px-4"
|
||||
disabled={mutationBlocked}
|
||||
title={
|
||||
mutationBlocked
|
||||
? (blockedMessage ?? undefined)
|
||||
: undefined
|
||||
}
|
||||
onClick={handleAddClause}
|
||||
>
|
||||
<i className="ri-play-list-add-fill text-[16px]" />
|
||||
@@ -1054,6 +1111,12 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
type="button"
|
||||
color="gray"
|
||||
className="h-[3.6rem] gap-1.5 px-4"
|
||||
disabled={mutationBlocked}
|
||||
title={
|
||||
mutationBlocked
|
||||
? (blockedMessage ?? undefined)
|
||||
: undefined
|
||||
}
|
||||
onClick={handleAddConnector}
|
||||
>
|
||||
<i className="ri-git-commit-line text-[16px]" />
|
||||
@@ -1083,13 +1146,24 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
<Button
|
||||
type="button"
|
||||
color="red"
|
||||
title="리셋"
|
||||
title={
|
||||
mutationBlocked
|
||||
? (blockedMessage ?? "리셋")
|
||||
: "리셋"
|
||||
}
|
||||
disabled={mutationBlocked}
|
||||
onClick={handleResetClick}
|
||||
>
|
||||
<i className="diveicon di-arrow-reset" />
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={mutationBlocked}
|
||||
title={
|
||||
mutationBlocked
|
||||
? (blockedMessage ?? undefined)
|
||||
: undefined
|
||||
}
|
||||
onClick={handleSaveClick}
|
||||
>
|
||||
등록
|
||||
|
||||
+11
-2
@@ -19,6 +19,7 @@ interface FormulaComponentsProps {
|
||||
index?: number,
|
||||
) => void;
|
||||
vrfcClsfCd?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const zoneClassName: Record<ClauseZone, string> = {
|
||||
@@ -45,6 +46,7 @@ const FormulaComponents = ({
|
||||
onOperatorChange,
|
||||
handleFomulaDialog,
|
||||
vrfcClsfCd,
|
||||
disabled = false,
|
||||
}: FormulaComponentsProps) => {
|
||||
const cmprOpert = data?.cmprOpert;
|
||||
const displayFormula = data
|
||||
@@ -60,6 +62,7 @@ const FormulaComponents = ({
|
||||
size="icon"
|
||||
className="formulaDeleteBtn size-[2.6rem] shrink-0 rounded-full !bg-[#f24e5b] hover:!bg-[#d63c48]"
|
||||
color="red"
|
||||
disabled={disabled}
|
||||
onClick={onDelete}
|
||||
>
|
||||
<i className="ri-subtract-fill text-[16px]" />
|
||||
@@ -70,21 +73,27 @@ const FormulaComponents = ({
|
||||
id={`formulaInput-${index ?? 0}`}
|
||||
value={displayFormula}
|
||||
title={displayFormula}
|
||||
onClick={() => handleFomulaDialog?.(true, data, index)}
|
||||
onClick={() => {
|
||||
if (disabled) return;
|
||||
handleFomulaDialog?.(true, data, index);
|
||||
}}
|
||||
readOnly
|
||||
disabled={disabled}
|
||||
/>
|
||||
<div className="w-[200px] shrink-0 [&_button]:!h-[3.6rem] [&_button]:!w-[200px] [&_button]:min-w-[200px] [&_button]:max-w-[200px]">
|
||||
<OperatorsComponents
|
||||
cmprOpert={cmprOpert}
|
||||
onValueChange={onOperatorChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
{vrfcClsfCd !== "TOTAL" &&
|
||||
<label className="flex w-[96px] shrink-0 items-center justify-end gap-1.5 text-[#4b5563] cursor-pointer">
|
||||
<label className={`flex w-[96px] shrink-0 items-center justify-end gap-1.5 text-[#4b5563] ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"}`}>
|
||||
<input
|
||||
type="checkbox"
|
||||
className="cursor-pointer accent-[#3a6df0]"
|
||||
checked={groupBy}
|
||||
disabled={disabled}
|
||||
onChange={(e) => onGroupByChange?.(e.target.checked)}
|
||||
/>
|
||||
group by
|
||||
|
||||
+4
-1
@@ -26,13 +26,15 @@ interface OperatorsComponentsProps {
|
||||
onValueChange?: (value: string) => void;
|
||||
placeholder?: string;
|
||||
opertSeCd?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const OperatorsComponents = ({
|
||||
cmprOpert,
|
||||
onValueChange,
|
||||
placeholder = "연산자 없음",
|
||||
opertSeCd = "opertSeCd=CMPR"
|
||||
opertSeCd = "opertSeCd=CMPR",
|
||||
disabled = false,
|
||||
}: OperatorsComponentsProps) => {
|
||||
const [operators, setOperators] = useState<OperatorItem[]>([]);
|
||||
const [localValue, setLocalValue] = useState<string>(cmprOpert ?? "");
|
||||
@@ -75,6 +77,7 @@ const OperatorsComponents = ({
|
||||
return (
|
||||
<Select
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onValueChange={(v) => {
|
||||
setLocalValue(v);
|
||||
onValueChange?.(v);
|
||||
|
||||
+32
-8
@@ -50,6 +50,9 @@ interface RegistDialogProps {
|
||||
vrfcSn?: number;
|
||||
/** 수정/등록 성공 시 부모에서 목록 재조회 등 실행 */
|
||||
onSuccess?: () => void;
|
||||
/** 입력기간이면 수정 불가(삭제는 가능) */
|
||||
mutationBlocked?: boolean;
|
||||
blockedMessage?: string | null;
|
||||
}
|
||||
|
||||
const RegistDialog = memo(
|
||||
@@ -59,10 +62,13 @@ const RegistDialog = memo(
|
||||
onOpenChange,
|
||||
vrfcSn,
|
||||
onSuccess,
|
||||
mutationBlocked = false,
|
||||
blockedMessage = null,
|
||||
...props
|
||||
}: RegistDialogProps) => {
|
||||
|
||||
const isVrfcSn = vrfcSn != null;
|
||||
const editBlocked = mutationBlocked && isVrfcSn;
|
||||
const [checkVrfcNm, setCheckVrfcNm] = useState<boolean>(false);
|
||||
const { confirm } = useConfirm();
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
@@ -219,6 +225,13 @@ const RegistDialog = memo(
|
||||
}, [vrfcNm, open, isVrfcSn]);
|
||||
|
||||
const onSubmit = async (data: GeneralVerificationMasterSubmitFormData) => {
|
||||
if (mutationBlocked) {
|
||||
alert(
|
||||
blockedMessage ??
|
||||
"입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
const currentVrfcNm = (data.vrfcNm ?? '').trim();
|
||||
const originalVrfcNm = originalVrfcNmRef.current;
|
||||
|
||||
@@ -321,7 +334,7 @@ const RegistDialog = memo(
|
||||
onValueChange={field.onChange}
|
||||
placeholder="전체"
|
||||
className="w-[16rem]"
|
||||
disabled={isVrfcSn}
|
||||
disabled={isVrfcSn || editBlocked}
|
||||
/>
|
||||
</FormControl>
|
||||
{form.formState.errors.trgtStatsCd && (
|
||||
@@ -348,7 +361,7 @@ const RegistDialog = memo(
|
||||
value={field.value ?? ""}
|
||||
className="!text-[1.3rem]"
|
||||
placeholder="검증명을 입력해주세요"
|
||||
disabled={(trgtStatsCd ?? '') === ''}
|
||||
disabled={editBlocked || (trgtStatsCd ?? '') === ''}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</FormControl>
|
||||
@@ -380,6 +393,7 @@ const RegistDialog = memo(
|
||||
<Select
|
||||
value={field.value ?? ""}
|
||||
onValueChange={field.onChange}
|
||||
disabled={editBlocked}
|
||||
>
|
||||
<SelectTrigger className="w-[10rem]">
|
||||
<SelectValue placeholder="선택" />
|
||||
@@ -416,6 +430,7 @@ const RegistDialog = memo(
|
||||
placeholder="소수점자리수를 입력해주세요"
|
||||
type="number"
|
||||
min={0}
|
||||
disabled={editBlocked}
|
||||
/>
|
||||
</FormControl>
|
||||
<p className="text-gray-500 text-base !mt-0">
|
||||
@@ -443,7 +458,7 @@ const RegistDialog = memo(
|
||||
<Select
|
||||
value={field.value ?? ""}
|
||||
onValueChange={field.onChange}
|
||||
disabled={Number(dcptDigtCnt ?? 0) === 0}
|
||||
disabled={editBlocked || Number(dcptDigtCnt ?? 0) === 0}
|
||||
>
|
||||
<SelectTrigger className="w-[10rem]">
|
||||
<SelectValue placeholder="선택" />
|
||||
@@ -484,13 +499,14 @@ const RegistDialog = memo(
|
||||
{...field}
|
||||
name="useYn"
|
||||
onValueChange={field.onChange}
|
||||
disabled={editBlocked}
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="Y" id="useY" />
|
||||
<RadioGroupItem value="Y" id="useY" disabled={editBlocked} />
|
||||
<Label htmlFor="useY">사용</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="N" id="useN" />
|
||||
<RadioGroupItem value="N" id="useN" disabled={editBlocked} />
|
||||
<Label htmlFor="useN">사용안함</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
@@ -599,9 +615,17 @@ const RegistDialog = memo(
|
||||
삭제
|
||||
</Button>
|
||||
}
|
||||
<Button size="lg" type="submit">
|
||||
{vrfcSn != null ? '수정' : '등록'}
|
||||
</Button>
|
||||
{editBlocked ? (
|
||||
<span title={blockedMessage ?? undefined}>
|
||||
<Button size="lg" type="submit" disabled>
|
||||
수정
|
||||
</Button>
|
||||
</span>
|
||||
) : (
|
||||
<Button size="lg" type="submit">
|
||||
{vrfcSn != null ? '수정' : '등록'}
|
||||
</Button>
|
||||
)}
|
||||
<DialogClose asChild>
|
||||
<Button size="lg" color="white">
|
||||
취소
|
||||
|
||||
@@ -5,130 +5,18 @@ import { footerInt } from "@/components/util/grid/footerSummary";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 5. 맨홀 현황
|
||||
// SeweragePipeInputManholeStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
// API: yy14=2015년 이전(2014년 데이터) … yy{(현재연도-1)%100} (필드 접두 yy + 연도 끝자리)
|
||||
|
||||
const MANHOLE_START_YEAR = 2014;
|
||||
const MANHOLE_LAST_DATA_YEAR = Math.max(MANHOLE_START_YEAR, new Date().getFullYear() - 1);
|
||||
const MANHOLE_YY_MIN = MANHOLE_START_YEAR % 100;
|
||||
const MANHOLE_YY_MAX = MANHOLE_LAST_DATA_YEAR % 100;
|
||||
const calendarYearFromYy = (yy: number) => 2000 + yy;
|
||||
|
||||
/** yy14(2014) 구간은 헤더에 「2015년 이전」 표기 (합계·검토 컬럼과 동일) */
|
||||
const manholeYearHeaderText = (yy: number): string => {
|
||||
const y = calendarYearFromYy(yy);
|
||||
return y === MANHOLE_START_YEAR ? "2015년 이전" : `${y}년`;
|
||||
};
|
||||
|
||||
const intCol = (name: string, headerText: string): ColumnConfig => ({
|
||||
const intCol = (name: string, headerText: string, editable = true): ColumnConfig => ({
|
||||
name,
|
||||
fieldName: name,
|
||||
header: { text: headerText },
|
||||
footer: footerInt,
|
||||
// editable: false,
|
||||
editable,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: "#,##0",
|
||||
...(editable ? {} : { styleName: "rg-cell-total" }),
|
||||
});
|
||||
|
||||
const yearlySumFields = (suffix: "WholMnhlCnt" | "Step1MnhlCnt" | "Step2MnhlCnt" | "Step3MnhlCnt" | "Step4MnhlCnt" | "Step5MnhlCnt") =>
|
||||
Array.from({ length: MANHOLE_YY_MAX - MANHOLE_YY_MIN + 1 }, (_, i) => `yy${MANHOLE_YY_MIN + i}${suffix}`);
|
||||
|
||||
function totalBlockColumns(): ColumnConfig[] {
|
||||
return [
|
||||
{
|
||||
...intCol("totalWholMnhlCnt", "계"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("WholMnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep1MnhlCnt", "주철"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step1MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep2MnhlCnt", "주철(조화)"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step2MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep3MnhlCnt", "콘크리트"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step3MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep4MnhlCnt", "기타"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step4MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
{
|
||||
...intCol("totalStep5MnhlCnt", "추락방지시설설치맨홀(개)"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: { fields: yearlySumFields("Step5MnhlCnt"), type: "sum" as const },
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function yyBlockColumns(yy: number): ColumnConfig[] {
|
||||
const p = `yy${yy}`;
|
||||
return [
|
||||
{
|
||||
...intCol(`${p}WholMnhlCnt`, "계"),
|
||||
styleName: "rg-cell-total",
|
||||
editable: false,
|
||||
computed: {
|
||||
fields: [
|
||||
`${p}Step1MnhlCnt`,
|
||||
`${p}Step2MnhlCnt`,
|
||||
`${p}Step3MnhlCnt`,
|
||||
`${p}Step4MnhlCnt`,
|
||||
`${p}Step5MnhlCnt`,
|
||||
],
|
||||
type: "sum" as const,
|
||||
},
|
||||
},
|
||||
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: manholeYearHeaderText(yy) },
|
||||
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: [
|
||||
{
|
||||
@@ -160,12 +48,19 @@ export const ManholeStatusInpColumn = {
|
||||
editable: false,
|
||||
styleName: "rg-cell-readonly",
|
||||
footer: { text: "합계" },
|
||||
// editable: false,
|
||||
},
|
||||
...totalBlockColumns(),
|
||||
...Array.from({ length: MANHOLE_YY_MAX - MANHOLE_YY_MIN + 1 }, (_, i) =>
|
||||
yyBlockColumns(MANHOLE_YY_MIN + i)
|
||||
).flat(),
|
||||
{
|
||||
...intCol("wholMnhlCnt", "계", false),
|
||||
computed: {
|
||||
fields: ["frlvlMnhlCnt", "sclvlMnhlCnt", "thlvlMnhlCnt", "folvlMnhlCnt"],
|
||||
type: "sum" as const,
|
||||
},
|
||||
},
|
||||
intCol("frlvlMnhlCnt", "주철"),
|
||||
intCol("sclvlMnhlCnt", "주철(조화)"),
|
||||
intCol("thlvlMnhlCnt", "콘크리트"),
|
||||
intCol("folvlMnhlCnt", "기타"),
|
||||
intCol("filvlMnhlCnt", "추락방지시설설치맨홀(개)"),
|
||||
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" } },
|
||||
{
|
||||
name: "admdstCd",
|
||||
@@ -194,31 +89,17 @@ export const ManholeStatusInpColumn = {
|
||||
"admdstNm",
|
||||
"emphsMngSeNm",
|
||||
{
|
||||
name: "yearlyTotal",
|
||||
name: "mtrlGroup",
|
||||
hideChildHeaders: false,
|
||||
header: { text: "연도별총계" },
|
||||
items: [
|
||||
{
|
||||
name: "yearlyTotalMaterial",
|
||||
hideChildHeaders: false,
|
||||
header: { text: "맨홀뚜껑 재질(개)" },
|
||||
items: [
|
||||
"totalWholMnhlCnt",
|
||||
"totalStep1MnhlCnt",
|
||||
"totalStep2MnhlCnt",
|
||||
"totalStep3MnhlCnt",
|
||||
"totalStep4MnhlCnt",
|
||||
],
|
||||
},
|
||||
"totalStep5MnhlCnt",
|
||||
],
|
||||
header: { text: "맨홀뚜껑 재질(개)" },
|
||||
items: ["wholMnhlCnt", "frlvlMnhlCnt", "sclvlMnhlCnt", "thlvlMnhlCnt", "folvlMnhlCnt"],
|
||||
},
|
||||
...yearLayoutItems,
|
||||
"filvlMnhlCnt",
|
||||
"rmrk",
|
||||
"admdstCd",
|
||||
"emphsMngSeCd",
|
||||
] as ColumnLayoutItem[],
|
||||
rowStartNum: 3,
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
tabKey: "ST00020005",
|
||||
tabLabel: "맨홀 현황",
|
||||
|
||||
@@ -11,6 +11,7 @@ import RegistDialog from "@/components/statistics/verification/generalVerificati
|
||||
|
||||
export const getGeneralVerificationColumns = (
|
||||
onUpdateSuccess?: () => void,
|
||||
options?: { mutationBlocked?: boolean; blockedMessage?: string | null },
|
||||
): ColumnDef<GeneralverificationList>[] => [
|
||||
{
|
||||
id: "no",
|
||||
@@ -53,6 +54,8 @@ export const getGeneralVerificationColumns = (
|
||||
<GeneralVerificationCopyButton
|
||||
row={row.original}
|
||||
onSuccess={onUpdateSuccess}
|
||||
mutationBlocked={options?.mutationBlocked}
|
||||
blockedMessage={options?.blockedMessage}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
@@ -65,6 +68,8 @@ export const getGeneralVerificationColumns = (
|
||||
<GeneralVerificationManageButton
|
||||
vrfcSn={row.original.vrfcSn}
|
||||
onSuccess={onUpdateSuccess}
|
||||
mutationBlocked={options?.mutationBlocked}
|
||||
blockedMessage={options?.blockedMessage}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
@@ -74,9 +79,13 @@ export const getGeneralVerificationColumns = (
|
||||
const GeneralVerificationManageButton = ({
|
||||
vrfcSn,
|
||||
onSuccess,
|
||||
mutationBlocked,
|
||||
blockedMessage,
|
||||
}: {
|
||||
vrfcSn: number;
|
||||
onSuccess?: () => void;
|
||||
mutationBlocked?: boolean;
|
||||
blockedMessage?: string | null;
|
||||
}) => {
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
return (
|
||||
@@ -85,6 +94,8 @@ const GeneralVerificationManageButton = ({
|
||||
onOpenChange={setDialogOpen}
|
||||
vrfcSn={vrfcSn}
|
||||
onSuccess={onSuccess}
|
||||
mutationBlocked={mutationBlocked}
|
||||
blockedMessage={blockedMessage}
|
||||
>
|
||||
<Button size="sm">관리</Button>
|
||||
</RegistDialog>
|
||||
@@ -94,11 +105,24 @@ const GeneralVerificationManageButton = ({
|
||||
const GeneralVerificationCopyButton = ({
|
||||
row,
|
||||
onSuccess,
|
||||
mutationBlocked,
|
||||
blockedMessage,
|
||||
}: {
|
||||
row: GeneralverificationList;
|
||||
onSuccess?: () => void;
|
||||
mutationBlocked?: boolean;
|
||||
blockedMessage?: string | null;
|
||||
}) => {
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
if (mutationBlocked) {
|
||||
return (
|
||||
<span title={blockedMessage ?? undefined}>
|
||||
<Button size="sm" color="white" disabled type="button">
|
||||
복사
|
||||
</Button>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<CopyDialog
|
||||
open={dialogOpen}
|
||||
|
||||
@@ -434,18 +434,16 @@ const rawList = [
|
||||
]
|
||||
},
|
||||
|
||||
// ST00020005 맨홀 현황은 연도 범위가 동적이므로 rawList에 포함하지 않고
|
||||
// getST00020005RvwConfig() 로 런타임에 생성합니다.
|
||||
{
|
||||
tabKey: "ST00020005_PLACEHOLDER",
|
||||
tabLabel: "맨홀 현황",
|
||||
rowStartNum: 3,
|
||||
tabKey: 'ST00020005',
|
||||
tabLabel: '맨홀 현황',
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 3,
|
||||
columns: [
|
||||
{
|
||||
name: "ctpvNm",
|
||||
fieldName: "ctpvNm",
|
||||
header: { text: "시도" },
|
||||
name: 'ctpvNm',
|
||||
fieldName: 'ctpvNm',
|
||||
header: { text: '시도' },
|
||||
mergeCells: true,
|
||||
sortdisable: true,
|
||||
footer: [
|
||||
@@ -455,11 +453,11 @@ const rawList = [
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, "displayYear");
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + "합계" : "합계";
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -468,18 +466,18 @@ const rawList = [
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, "displayYear");
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + "합계" : "합계";
|
||||
return divisionValues.length > divisionIndex ? divisionValues[divisionIndex] + '합계' : '합계';
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, mergeCells: true, sortdisable: true },
|
||||
{ name: "admdstNm", fieldName: "admdstNm", header: { text: "행정구역명" }, mergeCells: true, sortdisable: true },
|
||||
{ name: "emphsMngSeNm", fieldName: "emphsMngSeNm", header: { text: "집중강우\n중점관리\n구역구분" }, mergeCells: true },
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, mergeCells: true, sortdisable: true },
|
||||
{ name: 'emphsMngSeNm', fieldName: 'emphsMngSeNm', header: { text: '집중강우\n중점관리\n구역구분' }, mergeCells: true },
|
||||
{
|
||||
name: 'displayYear',
|
||||
fieldName: 'displayYear',
|
||||
@@ -514,233 +512,38 @@ const rawList = [
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{ name: "totalWholMnhlCnt", fieldName: "totalWholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totalStep1MnhlCnt", fieldName: "totalStep1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totalStep2MnhlCnt", fieldName: "totalStep2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totalStep3MnhlCnt", fieldName: "totalStep3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totalStep4MnhlCnt", fieldName: "totalStep4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totalStep5MnhlCnt", fieldName: "totalStep5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2015년 이전 (yy14) ──────────────────────────────────
|
||||
{ name: "yy14WholMnhlCnt", fieldName: "yy14WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step1MnhlCnt", fieldName: "yy14Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step2MnhlCnt", fieldName: "yy14Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step3MnhlCnt", fieldName: "yy14Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step4MnhlCnt", fieldName: "yy14Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step5MnhlCnt", fieldName: "yy14Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2015년 (yy15) ───────────────────────────────────────
|
||||
{ name: "yy15WholMnhlCnt", fieldName: "yy15WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step1MnhlCnt", fieldName: "yy15Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step2MnhlCnt", fieldName: "yy15Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step3MnhlCnt", fieldName: "yy15Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step4MnhlCnt", fieldName: "yy15Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step5MnhlCnt", fieldName: "yy15Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2016년 (yy16) ───────────────────────────────────────
|
||||
{ name: "yy16WholMnhlCnt", fieldName: "yy16WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step1MnhlCnt", fieldName: "yy16Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step2MnhlCnt", fieldName: "yy16Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step3MnhlCnt", fieldName: "yy16Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step4MnhlCnt", fieldName: "yy16Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step5MnhlCnt", fieldName: "yy16Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2017년 (yy17) ───────────────────────────────────────
|
||||
{ name: "yy17WholMnhlCnt", fieldName: "yy17WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step1MnhlCnt", fieldName: "yy17Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step2MnhlCnt", fieldName: "yy17Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step3MnhlCnt", fieldName: "yy17Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step4MnhlCnt", fieldName: "yy17Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step5MnhlCnt", fieldName: "yy17Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2018년 (yy18) ───────────────────────────────────────
|
||||
{ name: "yy18WholMnhlCnt", fieldName: "yy18WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step1MnhlCnt", fieldName: "yy18Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step2MnhlCnt", fieldName: "yy18Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step3MnhlCnt", fieldName: "yy18Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step4MnhlCnt", fieldName: "yy18Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step5MnhlCnt", fieldName: "yy18Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2019년 (yy19) ───────────────────────────────────────
|
||||
{ name: "yy19WholMnhlCnt", fieldName: "yy19WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step1MnhlCnt", fieldName: "yy19Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step2MnhlCnt", fieldName: "yy19Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step3MnhlCnt", fieldName: "yy19Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step4MnhlCnt", fieldName: "yy19Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step5MnhlCnt", fieldName: "yy19Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2020년 (yy20) ───────────────────────────────────────
|
||||
{ name: "yy20WholMnhlCnt", fieldName: "yy20WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step1MnhlCnt", fieldName: "yy20Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step2MnhlCnt", fieldName: "yy20Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step3MnhlCnt", fieldName: "yy20Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step4MnhlCnt", fieldName: "yy20Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step5MnhlCnt", fieldName: "yy20Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2021년 (yy21) ───────────────────────────────────────
|
||||
{ name: "yy21WholMnhlCnt", fieldName: "yy21WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step1MnhlCnt", fieldName: "yy21Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step2MnhlCnt", fieldName: "yy21Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step3MnhlCnt", fieldName: "yy21Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step4MnhlCnt", fieldName: "yy21Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step5MnhlCnt", fieldName: "yy21Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2022년 (yy22) ───────────────────────────────────────
|
||||
{ name: "yy22WholMnhlCnt", fieldName: "yy22WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step1MnhlCnt", fieldName: "yy22Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step2MnhlCnt", fieldName: "yy22Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step3MnhlCnt", fieldName: "yy22Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step4MnhlCnt", fieldName: "yy22Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step5MnhlCnt", fieldName: "yy22Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2023년 (yy23) ───────────────────────────────────────
|
||||
{ name: "yy23WholMnhlCnt", fieldName: "yy23WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step1MnhlCnt", fieldName: "yy23Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step2MnhlCnt", fieldName: "yy23Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step3MnhlCnt", fieldName: "yy23Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step4MnhlCnt", fieldName: "yy23Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step5MnhlCnt", fieldName: "yy23Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2024년 (yy24) ───────────────────────────────────────
|
||||
{ name: "yy24WholMnhlCnt", fieldName: "yy24WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step1MnhlCnt", fieldName: "yy24Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step2MnhlCnt", fieldName: "yy24Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step3MnhlCnt", fieldName: "yy24Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step4MnhlCnt", fieldName: "yy24Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step5MnhlCnt", fieldName: "yy24Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2025년 (yy25) ───────────────────────────────────────
|
||||
{ name: "yy25WholMnhlCnt", fieldName: "yy25WholMnhlCnt", header: { text: "계" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step1MnhlCnt", fieldName: "yy25Step1MnhlCnt", header: { text: "주철" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step2MnhlCnt", fieldName: "yy25Step2MnhlCnt", header: { text: "주철(조화)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step3MnhlCnt", fieldName: "yy25Step3MnhlCnt", header: { text: "콘크리트" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step4MnhlCnt", fieldName: "yy25Step4MnhlCnt", header: { text: "기타" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step5MnhlCnt", fieldName: "yy25Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
{ name: "rmrk", fieldName: "rmrk", header: { text: "비고" }, editable: false },
|
||||
{ name: 'wholMnhlCnt', fieldName: 'wholMnhlCnt', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'frlvlMnhlCnt', fieldName: 'frlvlMnhlCnt', header: { text: '주철' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sclvlMnhlCnt', fieldName: 'sclvlMnhlCnt', header: { text: '주철(조화)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'thlvlMnhlCnt', fieldName: 'thlvlMnhlCnt', header: { text: '콘크리트' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'folvlMnhlCnt', fieldName: 'folvlMnhlCnt', header: { text: '기타' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'filvlMnhlCnt', fieldName: 'filvlMnhlCnt', header: { text: '추락방지시설\n설치맨홀(개)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: "addrGroup",
|
||||
header: { text: "행정구역" },
|
||||
name: 'addrGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: "ctpvNm", footerUserSpans: [{ colspan: 5 }, { colspan: 5 }] },
|
||||
"sggNm",
|
||||
"admdstNm",
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 5 }, { colspan: 5 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
],
|
||||
},
|
||||
"emphsMngSeNm",
|
||||
"displayYear",
|
||||
'emphsMngSeNm',
|
||||
'displayYear',
|
||||
{
|
||||
name: "totGroup",
|
||||
header: { text: "총계" },
|
||||
items: [
|
||||
{ name: "totMtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["totalWholMnhlCnt", "totalStep1MnhlCnt", "totalStep2MnhlCnt", "totalStep3MnhlCnt", "totalStep4MnhlCnt"] },
|
||||
"totalStep5MnhlCnt",
|
||||
],
|
||||
name: 'mtrlGroup',
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: ['wholMnhlCnt', 'frlvlMnhlCnt', 'sclvlMnhlCnt', 'thlvlMnhlCnt', 'folvlMnhlCnt'],
|
||||
},
|
||||
{
|
||||
name: "yy14Group",
|
||||
header: { text: "2015년 이전" }, // ← _14Y
|
||||
items: [
|
||||
{ name: "yy14MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy14WholMnhlCnt", "yy14Step1MnhlCnt", "yy14Step2MnhlCnt", "yy14Step3MnhlCnt", "yy14Step4MnhlCnt"] },
|
||||
"yy14Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy15Group",
|
||||
header: { text: "2015년" }, // ← _15Y
|
||||
items: [
|
||||
{ name: "yy15MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy15WholMnhlCnt", "yy15Step1MnhlCnt", "yy15Step2MnhlCnt", "yy15Step3MnhlCnt", "yy15Step4MnhlCnt"] },
|
||||
"yy15Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy16Group",
|
||||
header: { text: "2016년" }, // ← _16Y
|
||||
items: [
|
||||
{ name: "yy16MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy16WholMnhlCnt", "yy16Step1MnhlCnt", "yy16Step2MnhlCnt", "yy16Step3MnhlCnt", "yy16Step4MnhlCnt"] },
|
||||
"yy16Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy17Group",
|
||||
header: { text: "2017년" },
|
||||
items: [
|
||||
{ name: "yy17MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy17WholMnhlCnt", "yy17Step1MnhlCnt", "yy17Step2MnhlCnt", "yy17Step3MnhlCnt", "yy17Step4MnhlCnt"] },
|
||||
"yy17Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy18Group",
|
||||
header: { text: "2018년" },
|
||||
items: [
|
||||
{ name: "yy18MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy18WholMnhlCnt", "yy18Step1MnhlCnt", "yy18Step2MnhlCnt", "yy18Step3MnhlCnt", "yy18Step4MnhlCnt"] },
|
||||
"yy18Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy19Group",
|
||||
header: { text: "2019년" },
|
||||
items: [
|
||||
{ name: "yy19MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy19WholMnhlCnt", "yy19Step1MnhlCnt", "yy19Step2MnhlCnt", "yy19Step3MnhlCnt", "yy19Step4MnhlCnt"] },
|
||||
"yy19Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy20Group",
|
||||
header: { text: "2020년" },
|
||||
items: [
|
||||
{ name: "yy20MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy20WholMnhlCnt", "yy20Step1MnhlCnt", "yy20Step2MnhlCnt", "yy20Step3MnhlCnt", "yy20Step4MnhlCnt"] },
|
||||
"yy20Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy21Group",
|
||||
header: { text: "2021년" },
|
||||
items: [
|
||||
{ name: "yy21MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy21WholMnhlCnt", "yy21Step1MnhlCnt", "yy21Step2MnhlCnt", "yy21Step3MnhlCnt", "yy21Step4MnhlCnt"] },
|
||||
"yy21Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy22Group",
|
||||
header: { text: "2022년" },
|
||||
items: [
|
||||
{ name: "yy22MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy22WholMnhlCnt", "yy22Step1MnhlCnt", "yy22Step2MnhlCnt", "yy22Step3MnhlCnt", "yy22Step4MnhlCnt"] },
|
||||
"yy22Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy23Group",
|
||||
header: { text: "2023년" },
|
||||
items: [
|
||||
{ name: "yy23MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy23WholMnhlCnt", "yy23Step1MnhlCnt", "yy23Step2MnhlCnt", "yy23Step3MnhlCnt", "yy23Step4MnhlCnt"] },
|
||||
"yy23Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy24Group",
|
||||
header: { text: "2024년" },
|
||||
items: [
|
||||
{ name: "yy24MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy24WholMnhlCnt", "yy24Step1MnhlCnt", "yy24Step2MnhlCnt", "yy24Step3MnhlCnt", "yy24Step4MnhlCnt"] },
|
||||
"yy24Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy25Group",
|
||||
header: { text: "2025년" },
|
||||
items: [
|
||||
{ name: "yy25MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy25WholMnhlCnt", "yy25Step1MnhlCnt", "yy25Step2MnhlCnt", "yy25Step3MnhlCnt", "yy25Step4MnhlCnt"] },
|
||||
"yy25Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
"rmrk",
|
||||
],
|
||||
'filvlMnhlCnt',
|
||||
'rmrk',
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
/** ST00020003 관종별 현황 — 검토 화면용 동적 컬럼 생성
|
||||
* 필드명: prlg_whol_{year}, lyng_prlg_{year}, dmltn_prlg_{year}
|
||||
* (total의 getST00020003Config와 동일 필드, oldPipeRt 제외)
|
||||
@@ -813,100 +616,8 @@ export const getST00020003RvwConfig = (statsYr: string | number) => {
|
||||
};
|
||||
};
|
||||
|
||||
/** ST00020005 맨홀 현황 — 검토 화면용 동적 컬럼 생성
|
||||
* 필드명: wholMnhlCnt{year}, step1~5MnhlCnt{year}
|
||||
* (total의 getST00020005Config와 동일 필드)
|
||||
*/
|
||||
export const getST00020005RvwConfig = (statsYr: string | number) => {
|
||||
const firstYear = 2014;
|
||||
const lastYear = Number(statsYr) || dayjs().year();
|
||||
const yearRange = Array.from({ length: lastYear - firstYear + 1 }, (_, i) => firstYear + i);
|
||||
|
||||
const makeFooterValueCallback = (divisionIndex: number) => ({
|
||||
valueCallback: (grid: GridView) => {
|
||||
const dataSource = grid.getDataSource();
|
||||
const uniqueValues = new Set<string>();
|
||||
for (let i = 0; i < dataSource.getRowCount(); i++) {
|
||||
const val = dataSource.getValue(i, 'displayYear');
|
||||
if (val) uniqueValues.add(String(val));
|
||||
}
|
||||
const divisionValues = Array.from(uniqueValues);
|
||||
return divisionValues.length > divisionIndex
|
||||
? divisionValues[divisionIndex] + '합계'
|
||||
: '합계';
|
||||
},
|
||||
});
|
||||
|
||||
const mnhlYearCols = (year: number) => [
|
||||
{ name: `wholMnhlCnt${year}`, fieldName: `wholMnhlCnt${year}`, header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: `step1MnhlCnt${year}`, fieldName: `step1MnhlCnt${year}`, header: { text: '주철' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: `step2MnhlCnt${year}`, fieldName: `step2MnhlCnt${year}`, header: { text: '주철(조화)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: `step3MnhlCnt${year}`, fieldName: `step3MnhlCnt${year}`, header: { text: '콘크리트' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: `step4MnhlCnt${year}`, fieldName: `step4MnhlCnt${year}`, header: { text: '기타' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: `step5MnhlCnt${year}`, fieldName: `step5MnhlCnt${year}`, header: { text: '추락방지시설\n설치맨홀(개)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
];
|
||||
|
||||
const mnhlYearLayout = (year: number) => ({
|
||||
name: `yr${year}Group`,
|
||||
header: { text: year === firstYear ? '2015년 이전' : `${year}년` },
|
||||
items: [
|
||||
{
|
||||
name: `yr${year}MtrlGroup`,
|
||||
header: { text: '맨홀뚜껑 재질(개)' },
|
||||
items: [`wholMnhlCnt${year}`, `step1MnhlCnt${year}`, `step2MnhlCnt${year}`, `step3MnhlCnt${year}`, `step4MnhlCnt${year}`],
|
||||
},
|
||||
`step5MnhlCnt${year}`,
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
tabKey: 'ST00020005',
|
||||
tabLabel: '맨홀 현황',
|
||||
rowStartNum: 3,
|
||||
fixedColumns: 3,
|
||||
columns: [
|
||||
{ name: 'ctpvNm', fieldName: 'ctpvNm', header: { text: '시도' }, editable: false, styleName: 'rg-cell-readonly', mergeCells: true, sortdisable: true, footer: [makeFooterValueCallback(0), makeFooterValueCallback(1)] },
|
||||
{ name: 'sggNm', fieldName: 'sggNm', header: { text: '시군구' }, editable: false, styleName: 'rg-cell-readonly', mergeCells: true, sortdisable: true },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly', mergeCells: true, sortdisable: true },
|
||||
{ name: 'emphsMngSeNm', fieldName: 'emphsMngSeNm', header: { text: '집중강우\n중점관리\n구역구분' }, editable: false, styleName: 'rg-cell-readonly', mergeCells: true },
|
||||
{ name: 'displayYear', fieldName: 'displayYear', header: { text: '구분' }, editable: false, styleName: 'rg-cell-readonly', sortdisable: true, footer: [makeFooterValueCallback(0), makeFooterValueCallback(1)] },
|
||||
{ name: 'totWholMnhlCnt', fieldName: 'totWholMnhlCnt', header: { text: '계' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'totStep1MnhlCnt', fieldName: 'totStep1MnhlCnt', header: { text: '주철' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'totStep2MnhlCnt', fieldName: 'totStep2MnhlCnt', header: { text: '주철(조화)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'totStep3MnhlCnt', fieldName: 'totStep3MnhlCnt', header: { text: '콘크리트' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'totStep4MnhlCnt', fieldName: 'totStep4MnhlCnt', header: { text: '기타' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'totStep5MnhlCnt', fieldName: 'totStep5MnhlCnt', header: { text: '추락방지시설\n설치맨홀(개)' }, footer: footerIntArrayByDivision, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false, styleName: 'rg-cell-readonly' },
|
||||
...yearRange.flatMap(mnhlYearCols),
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
],
|
||||
columnLayout: [
|
||||
{
|
||||
name: 'addrGroup',
|
||||
header: { text: '행정구역' },
|
||||
items: [
|
||||
{ column: 'ctpvNm', footerUserSpans: [{ colspan: 5 }, { colspan: 5 }] },
|
||||
'sggNm',
|
||||
'admdstNm',
|
||||
],
|
||||
},
|
||||
'emphsMngSeNm',
|
||||
'displayYear',
|
||||
{
|
||||
name: 'totGroup',
|
||||
header: { text: '연도별총계' },
|
||||
items: [
|
||||
{ name: 'totMtrlGroup', header: { text: '맨홀뚜껑 재질(개)' }, items: ['totWholMnhlCnt', 'totStep1MnhlCnt', 'totStep2MnhlCnt', 'totStep3MnhlCnt', 'totStep4MnhlCnt'] },
|
||||
'totStep5MnhlCnt',
|
||||
],
|
||||
},
|
||||
...yearRange.map(mnhlYearLayout),
|
||||
'rmrk',
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
export const SewagePipeColumnInfoListRvw = rawList
|
||||
.filter((tab) => tab.tabKey !== 'ST00020003_PLACEHOLDER' && tab.tabKey !== 'ST00020005_PLACEHOLDER')
|
||||
.filter((tab) => tab.tabKey !== 'ST00020003_PLACEHOLDER')
|
||||
.map((tab) => ({
|
||||
...tab,
|
||||
columns: tab.columns.map((col) => ({
|
||||
@@ -925,15 +636,5 @@ const st00020003RvwPlaceholder = {
|
||||
columnLayout: [] as ReturnType<typeof getST00020003RvwConfig>['columnLayout'],
|
||||
};
|
||||
|
||||
const st00020005RvwPlaceholder = {
|
||||
tabKey: 'ST00020005',
|
||||
tabLabel: '맨홀 현황',
|
||||
rowStartNum: 3,
|
||||
fixedColumns: 3,
|
||||
columns: [] as ReturnType<typeof getST00020005RvwConfig>['columns'],
|
||||
columnLayout: [] as ReturnType<typeof getST00020005RvwConfig>['columnLayout'],
|
||||
};
|
||||
|
||||
// ST00020003: index 2, ST00020005: 끝에 추가
|
||||
// ST00020003: index 2
|
||||
SewagePipeColumnInfoListRvw.splice(2, 0, st00020003RvwPlaceholder);
|
||||
SewagePipeColumnInfoListRvw.push(st00020005RvwPlaceholder);
|
||||
@@ -700,232 +700,34 @@ const rawSewagePipeTotList = [
|
||||
],
|
||||
},
|
||||
|
||||
// ST00020005 맨홀 현황은 연도 범위가 동적이므로 rawSewagePipeTotList에 포함하지 않고
|
||||
// getST00020005Config() 로 런타임에 생성합니다.
|
||||
{
|
||||
tabKey: "ST00020005_PLACEHOLDER",
|
||||
tabLabel: "맨홀 현황",
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
{ 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: "emphsMngSeNm", fieldName: "emphsMngSeNm", header: { text: "집중강우\n중점관리\n구역구분" }, editable: false },
|
||||
|
||||
{ name: "totWholMnhlCnt", fieldName: "totWholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep1MnhlCnt", fieldName: "totStep1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep2MnhlCnt", fieldName: "totStep2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep3MnhlCnt", fieldName: "totStep3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep4MnhlCnt", fieldName: "totStep4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep5MnhlCnt", fieldName: "totStep5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2015년 이전 (yy14) ──────────────────────────────────
|
||||
{ name: "yy14WholMnhlCnt", fieldName: "yy14WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step1MnhlCnt", fieldName: "yy14Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step2MnhlCnt", fieldName: "yy14Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step3MnhlCnt", fieldName: "yy14Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step4MnhlCnt", fieldName: "yy14Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy14Step5MnhlCnt", fieldName: "yy14Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2015년 (yy15) ───────────────────────────────────────
|
||||
{ name: "yy15WholMnhlCnt", fieldName: "yy15WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step1MnhlCnt", fieldName: "yy15Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step2MnhlCnt", fieldName: "yy15Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step3MnhlCnt", fieldName: "yy15Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step4MnhlCnt", fieldName: "yy15Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy15Step5MnhlCnt", fieldName: "yy15Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2016년 (yy16) ───────────────────────────────────────
|
||||
{ name: "yy16WholMnhlCnt", fieldName: "yy16WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step1MnhlCnt", fieldName: "yy16Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step2MnhlCnt", fieldName: "yy16Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step3MnhlCnt", fieldName: "yy16Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step4MnhlCnt", fieldName: "yy16Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy16Step5MnhlCnt", fieldName: "yy16Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2017년 (yy17) ───────────────────────────────────────
|
||||
{ name: "yy17WholMnhlCnt", fieldName: "yy17WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step1MnhlCnt", fieldName: "yy17Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step2MnhlCnt", fieldName: "yy17Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step3MnhlCnt", fieldName: "yy17Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step4MnhlCnt", fieldName: "yy17Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy17Step5MnhlCnt", fieldName: "yy17Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2018년 (yy18) ───────────────────────────────────────
|
||||
{ name: "yy18WholMnhlCnt", fieldName: "yy18WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step1MnhlCnt", fieldName: "yy18Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step2MnhlCnt", fieldName: "yy18Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step3MnhlCnt", fieldName: "yy18Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step4MnhlCnt", fieldName: "yy18Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy18Step5MnhlCnt", fieldName: "yy18Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2019년 (yy19) ───────────────────────────────────────
|
||||
{ name: "yy19WholMnhlCnt", fieldName: "yy19WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step1MnhlCnt", fieldName: "yy19Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step2MnhlCnt", fieldName: "yy19Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step3MnhlCnt", fieldName: "yy19Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step4MnhlCnt", fieldName: "yy19Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy19Step5MnhlCnt", fieldName: "yy19Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2020년 (yy20) ───────────────────────────────────────
|
||||
{ name: "yy20WholMnhlCnt", fieldName: "yy20WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step1MnhlCnt", fieldName: "yy20Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step2MnhlCnt", fieldName: "yy20Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step3MnhlCnt", fieldName: "yy20Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step4MnhlCnt", fieldName: "yy20Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy20Step5MnhlCnt", fieldName: "yy20Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2021년 (yy21) ───────────────────────────────────────
|
||||
{ name: "yy21WholMnhlCnt", fieldName: "yy21WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step1MnhlCnt", fieldName: "yy21Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step2MnhlCnt", fieldName: "yy21Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step3MnhlCnt", fieldName: "yy21Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step4MnhlCnt", fieldName: "yy21Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy21Step5MnhlCnt", fieldName: "yy21Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2022년 (yy22) ───────────────────────────────────────
|
||||
{ name: "yy22WholMnhlCnt", fieldName: "yy22WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step1MnhlCnt", fieldName: "yy22Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step2MnhlCnt", fieldName: "yy22Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step3MnhlCnt", fieldName: "yy22Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step4MnhlCnt", fieldName: "yy22Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy22Step5MnhlCnt", fieldName: "yy22Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2023년 (yy23) ───────────────────────────────────────
|
||||
{ name: "yy23WholMnhlCnt", fieldName: "yy23WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step1MnhlCnt", fieldName: "yy23Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step2MnhlCnt", fieldName: "yy23Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step3MnhlCnt", fieldName: "yy23Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step4MnhlCnt", fieldName: "yy23Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy23Step5MnhlCnt", fieldName: "yy23Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2024년 (yy24) ───────────────────────────────────────
|
||||
{ name: "yy24WholMnhlCnt", fieldName: "yy24WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step1MnhlCnt", fieldName: "yy24Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step2MnhlCnt", fieldName: "yy24Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step3MnhlCnt", fieldName: "yy24Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step4MnhlCnt", fieldName: "yy24Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy24Step5MnhlCnt", fieldName: "yy24Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
|
||||
// ── 2025년 (yy25) ───────────────────────────────────────
|
||||
{ name: "yy25WholMnhlCnt", fieldName: "yy25WholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step1MnhlCnt", fieldName: "yy25Step1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step2MnhlCnt", fieldName: "yy25Step2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step3MnhlCnt", fieldName: "yy25Step3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step4MnhlCnt", fieldName: "yy25Step4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "yy25Step5MnhlCnt", fieldName: "yy25Step5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: "addrGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm"] },
|
||||
"emphsMngSeNm",
|
||||
{
|
||||
name: "totGroup",
|
||||
header: { text: "연도별총계" },
|
||||
items: [
|
||||
{ name: "totMtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["totWholMnhlCnt", "totStep1MnhlCnt", "totStep2MnhlCnt", "totStep3MnhlCnt", "totStep4MnhlCnt"] },
|
||||
"totStep5MnhlCnt",
|
||||
tabKey: "ST00020005",
|
||||
tabLabel: "맨홀 현황",
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
{ 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: "emphsMngSeNm", fieldName: "emphsMngSeNm", header: { text: "집중강우\n중점관리\n구역구분" }, editable: false },
|
||||
{ name: "wholMnhlCnt", fieldName: "wholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "frlvlMnhlCnt", fieldName: "frlvlMnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "sclvlMnhlCnt", fieldName: "sclvlMnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "thlvlMnhlCnt", fieldName: "thlvlMnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "folvlMnhlCnt", fieldName: "folvlMnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "filvlMnhlCnt", fieldName: "filvlMnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: "addrGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm", "admdstNm"] },
|
||||
"emphsMngSeNm",
|
||||
{
|
||||
name: "mtrlGroup",
|
||||
header: { text: "맨홀뚜껑 재질(개)" },
|
||||
items: ["wholMnhlCnt", "frlvlMnhlCnt", "sclvlMnhlCnt", "thlvlMnhlCnt", "folvlMnhlCnt"],
|
||||
},
|
||||
"filvlMnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy14Group",
|
||||
header: { text: "2015년 이전" }, // ← _14Y
|
||||
items: [
|
||||
{ name: "yy14MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy14WholMnhlCnt", "yy14Step1MnhlCnt", "yy14Step2MnhlCnt", "yy14Step3MnhlCnt", "yy14Step4MnhlCnt"] },
|
||||
"yy14Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy15Group",
|
||||
header: { text: "2015년" }, // ← _15Y
|
||||
items: [
|
||||
{ name: "yy15MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy15WholMnhlCnt", "yy15Step1MnhlCnt", "yy15Step2MnhlCnt", "yy15Step3MnhlCnt", "yy15Step4MnhlCnt"] },
|
||||
"yy15Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy16Group",
|
||||
header: { text: "2016년" }, // ← _16Y
|
||||
items: [
|
||||
{ name: "yy16MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy16WholMnhlCnt", "yy16Step1MnhlCnt", "yy16Step2MnhlCnt", "yy16Step3MnhlCnt", "yy16Step4MnhlCnt"] },
|
||||
"yy16Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy17Group",
|
||||
header: { text: "2017년" },
|
||||
items: [
|
||||
{ name: "yy17MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy17WholMnhlCnt", "yy17Step1MnhlCnt", "yy17Step2MnhlCnt", "yy17Step3MnhlCnt", "yy17Step4MnhlCnt"] },
|
||||
"yy17Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy18Group",
|
||||
header: { text: "2018년" },
|
||||
items: [
|
||||
{ name: "yy18MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy18WholMnhlCnt", "yy18Step1MnhlCnt", "yy18Step2MnhlCnt", "yy18Step3MnhlCnt", "yy18Step4MnhlCnt"] },
|
||||
"yy18Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy19Group",
|
||||
header: { text: "2019년" },
|
||||
items: [
|
||||
{ name: "yy19MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy19WholMnhlCnt", "yy19Step1MnhlCnt", "yy19Step2MnhlCnt", "yy19Step3MnhlCnt", "yy19Step4MnhlCnt"] },
|
||||
"yy19Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy20Group",
|
||||
header: { text: "2020년" },
|
||||
items: [
|
||||
{ name: "yy20MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy20WholMnhlCnt", "yy20Step1MnhlCnt", "yy20Step2MnhlCnt", "yy20Step3MnhlCnt", "yy20Step4MnhlCnt"] },
|
||||
"yy20Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy21Group",
|
||||
header: { text: "2021년" },
|
||||
items: [
|
||||
{ name: "yy21MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy21WholMnhlCnt", "yy21Step1MnhlCnt", "yy21Step2MnhlCnt", "yy21Step3MnhlCnt", "yy21Step4MnhlCnt"] },
|
||||
"yy21Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy22Group",
|
||||
header: { text: "2022년" },
|
||||
items: [
|
||||
{ name: "yy22MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy22WholMnhlCnt", "yy22Step1MnhlCnt", "yy22Step2MnhlCnt", "yy22Step3MnhlCnt", "yy22Step4MnhlCnt"] },
|
||||
"yy22Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy23Group",
|
||||
header: { text: "2023년" },
|
||||
items: [
|
||||
{ name: "yy23MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy23WholMnhlCnt", "yy23Step1MnhlCnt", "yy23Step2MnhlCnt", "yy23Step3MnhlCnt", "yy23Step4MnhlCnt"] },
|
||||
"yy23Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy24Group",
|
||||
header: { text: "2024년" },
|
||||
items: [
|
||||
{ name: "yy24MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy24WholMnhlCnt", "yy24Step1MnhlCnt", "yy24Step2MnhlCnt", "yy24Step3MnhlCnt", "yy24Step4MnhlCnt"] },
|
||||
"yy24Step5MnhlCnt",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "yy25Group",
|
||||
header: { text: "2025년" },
|
||||
items: [
|
||||
{ name: "yy25MtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["yy25WholMnhlCnt", "yy25Step1MnhlCnt", "yy25Step2MnhlCnt", "yy25Step3MnhlCnt", "yy25Step4MnhlCnt"] },
|
||||
"yy25Step5MnhlCnt",
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
// 2. 동적 컬럼(ST00020003) 생성 함수
|
||||
@@ -987,79 +789,7 @@ export const getST00020003Config = (statsYr: string | number) => {
|
||||
};
|
||||
};
|
||||
|
||||
/** ST00020005 — 맨홀 현황 동적 컬럼 생성
|
||||
* 응답 필드: wholMnhlCnt{year}, step1~5MnhlCnt{year}
|
||||
* firstYear: 데이터 시작 연도(기본 2014), lastYear: 조회 연도(statsYr)
|
||||
*/
|
||||
export const getST00020005Config = (statsYr: string | number) => {
|
||||
const firstYear = 2014;
|
||||
const lastYear = Number(statsYr) || new Date().getFullYear();
|
||||
|
||||
const mnhlYearCols = (year: number) => [
|
||||
{ name: `wholMnhlCnt${year}`, fieldName: `wholMnhlCnt${year}`, header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: `step1MnhlCnt${year}`, fieldName: `step1MnhlCnt${year}`, header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: `step2MnhlCnt${year}`, fieldName: `step2MnhlCnt${year}`, header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: `step3MnhlCnt${year}`, fieldName: `step3MnhlCnt${year}`, header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: `step4MnhlCnt${year}`, fieldName: `step4MnhlCnt${year}`, header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: `step5MnhlCnt${year}`, fieldName: `step5MnhlCnt${year}`, header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
];
|
||||
|
||||
const mnhlYearLayout = (year: number) => ({
|
||||
name: `yr${year}Group`,
|
||||
header: { text: year === firstYear ? `${firstYear}년 이전` : `${year}년` },
|
||||
items: [
|
||||
{
|
||||
name: `yr${year}MtrlGroup`,
|
||||
header: { text: "맨홀뚜껑 재질(개)" },
|
||||
items: [
|
||||
`wholMnhlCnt${year}`,
|
||||
`step1MnhlCnt${year}`,
|
||||
`step2MnhlCnt${year}`,
|
||||
`step3MnhlCnt${year}`,
|
||||
`step4MnhlCnt${year}`,
|
||||
],
|
||||
},
|
||||
`step5MnhlCnt${year}`,
|
||||
],
|
||||
});
|
||||
|
||||
const yearRange = Array.from({ length: lastYear - firstYear + 1 }, (_, i) => firstYear + i);
|
||||
|
||||
return {
|
||||
tabKey: "ST00020005",
|
||||
tabLabel: "맨홀 현황",
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
columns: [
|
||||
{ name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false },
|
||||
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false },
|
||||
{ name: "emphsMngSeNm", fieldName: "emphsMngSeNm", header: { text: "집중강우\n중점관리\n구역구분" }, editable: false },
|
||||
{ name: "totWholMnhlCnt", fieldName: "totWholMnhlCnt", header: { text: "계" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep1MnhlCnt", fieldName: "totStep1MnhlCnt", header: { text: "주철" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep2MnhlCnt", fieldName: "totStep2MnhlCnt", header: { text: "주철(조화)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep3MnhlCnt", fieldName: "totStep3MnhlCnt", header: { text: "콘크리트" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep4MnhlCnt", fieldName: "totStep4MnhlCnt", header: { text: "기타" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
{ name: "totStep5MnhlCnt", fieldName: "totStep5MnhlCnt", header: { text: "추락방지시설\n설치맨홀(개)" }, valueType: ValueType.NUMBER, dataFormat: "#,##0", editable: false },
|
||||
...yearRange.flatMap(mnhlYearCols),
|
||||
],
|
||||
columnLayout: [
|
||||
{ name: "addrGroup", header: { text: "행정구역" }, items: ["ctpvNm", "sggNm"] },
|
||||
"emphsMngSeNm",
|
||||
{
|
||||
name: "totGroup",
|
||||
header: { text: "연도별총계" },
|
||||
items: [
|
||||
{ name: "totMtrlGroup", header: { text: "맨홀뚜껑 재질(개)" }, items: ["totWholMnhlCnt", "totStep1MnhlCnt", "totStep2MnhlCnt", "totStep3MnhlCnt", "totStep4MnhlCnt"] },
|
||||
"totStep5MnhlCnt",
|
||||
],
|
||||
},
|
||||
...yearRange.map(mnhlYearLayout),
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
export const SewagePipeColumnInfoListTot: ColumnInfoList[] = rawSewagePipeTotList
|
||||
.filter((tab) => tab.tabKey !== "ST00020005_PLACEHOLDER")
|
||||
.map((tab) => ({ ...tab, columns: tab.columns.map((col) => ({ ...col, editable: false as const })) }));
|
||||
|
||||
const st00020003PlaceholderTab: ColumnInfoList = {
|
||||
@@ -1071,14 +801,4 @@ const st00020003PlaceholderTab: ColumnInfoList = {
|
||||
columnLayout: [],
|
||||
};
|
||||
|
||||
const st00020005PlaceholderTab: ColumnInfoList = {
|
||||
tabKey: "ST00020005",
|
||||
tabLabel: "맨홀 현황",
|
||||
rowStartNum: 2,
|
||||
fixedColumns: 2,
|
||||
columns: [],
|
||||
columnLayout: [],
|
||||
};
|
||||
|
||||
SewagePipeColumnInfoListTot.splice(2, 0, st00020003PlaceholderTab);
|
||||
SewagePipeColumnInfoListTot.push(st00020005PlaceholderTab);
|
||||
SewagePipeColumnInfoListTot.splice(2, 0, st00020003PlaceholderTab);
|
||||
+13
-44
@@ -412,43 +412,19 @@ export interface SeweragePipeInputPipeDiameterStatusSubmitRequest extends Sewera
|
||||
submitList: SeweragePipeInputPipeDiameterStatusSaveItem[];
|
||||
}
|
||||
|
||||
/** 맨홀 현황 — 연도별 통계 항목 */
|
||||
export interface SeweragePipeInputManholeYearlyStatItem {
|
||||
manhYr: string;
|
||||
wholMnhlCnt: number;
|
||||
step1MnhlCnt: number;
|
||||
step2MnhlCnt: number;
|
||||
step3MnhlCnt: number;
|
||||
step4MnhlCnt: number;
|
||||
step5MnhlCnt: number;
|
||||
}
|
||||
|
||||
type SeweragePipeInputManholeLegacyYy = 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25;
|
||||
type SeweragePipeInputManholeLegacySuffix =
|
||||
| "WholMnhlCnt"
|
||||
| "Step1MnhlCnt"
|
||||
| "Step2MnhlCnt"
|
||||
| "Step3MnhlCnt"
|
||||
| "Step4MnhlCnt"
|
||||
| "Step5MnhlCnt";
|
||||
type SeweragePipeInputManholeLegacyYearField =
|
||||
`yy${SeweragePipeInputManholeLegacyYy}${SeweragePipeInputManholeLegacySuffix}`;
|
||||
|
||||
/** 맨홀 현황 — 목록 항목 */
|
||||
export interface SeweragePipeInputManholeStatusItem
|
||||
extends Partial<Record<SeweragePipeInputManholeLegacyYearField, number>> {
|
||||
export interface SeweragePipeInputManholeStatusItem {
|
||||
sggNm: string;
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
emphsMngSeCd: string;
|
||||
emphsMngSeNm: string;
|
||||
totalWholMnhlCnt: number;
|
||||
totalStep1MnhlCnt: number;
|
||||
totalStep2MnhlCnt: number;
|
||||
totalStep3MnhlCnt: number;
|
||||
totalStep4MnhlCnt: number;
|
||||
totalStep5MnhlCnt: number;
|
||||
yearlyStats?: SeweragePipeInputManholeYearlyStatItem[];
|
||||
wholMnhlCnt: number;
|
||||
frlvlMnhlCnt: number;
|
||||
sclvlMnhlCnt: number;
|
||||
thlvlMnhlCnt: number;
|
||||
folvlMnhlCnt: number;
|
||||
filvlMnhlCnt: number;
|
||||
rmrk: string;
|
||||
verificationResult?: SeweragePipeInputVerificationResult;
|
||||
}
|
||||
@@ -467,23 +443,16 @@ export interface SeweragePipeInputManholeResponse {
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 저장 — yearlyStats 항목 */
|
||||
export interface SeweragePipeInputManholeStatusSaveYearlyStatItem {
|
||||
manhYr: string;
|
||||
wholMnhlCnt: number;
|
||||
step1MnhlCnt: number;
|
||||
step2MnhlCnt: number;
|
||||
step3MnhlCnt: number;
|
||||
step4MnhlCnt: number;
|
||||
step5MnhlCnt: number;
|
||||
}
|
||||
|
||||
/** 맨홀 현황 저장 — saveList 항목 */
|
||||
export interface SeweragePipeInputManholeStatusSaveItem {
|
||||
emphsMngSeCd: string | null;
|
||||
admdstCd: string | null;
|
||||
admdstNm: string | null;
|
||||
yearlyStats: SeweragePipeInputManholeStatusSaveYearlyStatItem[];
|
||||
emphsMngSeCd: string | null;
|
||||
frlvlMnhlCnt: number;
|
||||
sclvlMnhlCnt: number;
|
||||
thlvlMnhlCnt: number;
|
||||
folvlMnhlCnt: number;
|
||||
filvlMnhlCnt: number;
|
||||
rmrk: string | null;
|
||||
}
|
||||
|
||||
|
||||
+23
-1
@@ -169,9 +169,31 @@ export interface CheckInputPeriodResponse {
|
||||
data: CheckInputPeriodItem[];
|
||||
}
|
||||
|
||||
/** 입력기간(INPT) 중 `current`인 항목 (없으면 null) */
|
||||
export function getCurrentInputPeriod(
|
||||
periods: CheckInputPeriodItem[] | null | undefined,
|
||||
): CheckInputPeriodItem | null {
|
||||
return (periods ?? []).find((p) => p.seType === "INPT" && p.current === true) ?? null;
|
||||
}
|
||||
|
||||
/** 입력기간(INPT) 중 현재 구간이면 true */
|
||||
export function isInputPeriodCurrent(periods: CheckInputPeriodItem[] | null | undefined): boolean {
|
||||
return (periods ?? []).some((p) => p.seType === "INPT" && p.current === true);
|
||||
return getCurrentInputPeriod(periods) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 입력기간이면 일반검증 항목 등록·수정 차단 안내, 아니면 null
|
||||
*/
|
||||
export function getInputPeriodVerificationManageBlockedMessage(
|
||||
periods: CheckInputPeriodItem[] | null | undefined,
|
||||
): string | null {
|
||||
const v = getCurrentInputPeriod(periods);
|
||||
if (!v) return null;
|
||||
const from = formatCheckInputYmdAsDash(v.bgngYmd);
|
||||
const to = formatCheckInputYmdAsDash(v.endYmd);
|
||||
const range =
|
||||
from && to ? `${from} ~ ${to}` : [from, to].filter(Boolean).join(" ~ ");
|
||||
return `입력기간에는 검증항목을 등록하거나 수정할 수 없습니다.\n(입력기간: ${range})`;
|
||||
}
|
||||
|
||||
/** `YYYYMMDD` → `yyyy-mm-dd` (그 외 형식은 그대로 반환) */
|
||||
|
||||
@@ -256,19 +256,14 @@ export interface SewagePipeReviewManholeItem {
|
||||
displayYear: string;
|
||||
rowType: 'OLD' | 'CURR';
|
||||
emphsMngSeCd: string;
|
||||
emphsMngSeNm?: string;
|
||||
|
||||
totWholMnhlCnt: number;
|
||||
totStep1MnhlCnt: number;
|
||||
totStep2MnhlCnt: number;
|
||||
totStep3MnhlCnt: number;
|
||||
totStep4MnhlCnt: number;
|
||||
totStep5MnhlCnt: number;
|
||||
|
||||
emphsMngSeNm?: string | null;
|
||||
wholMnhlCnt: number;
|
||||
frlvlMnhlCnt: number;
|
||||
sclvlMnhlCnt: number;
|
||||
thlvlMnhlCnt: number;
|
||||
folvlMnhlCnt: number;
|
||||
filvlMnhlCnt: number;
|
||||
rmrk: string | null;
|
||||
|
||||
/** 연도별 동적 필드 (wholMnhlCnt{year} ~ step5MnhlCnt{year}) */
|
||||
[key: string]: string | number | null | undefined;
|
||||
}
|
||||
|
||||
export interface SewagePipeManholeResponseData {
|
||||
|
||||
+7
-12
@@ -162,8 +162,7 @@ export interface SewagePipePipeDiamStatusResponse {
|
||||
|
||||
/**
|
||||
* 맨홀 현황 응답 아이템 인터페이스
|
||||
* 연도별 동적 필드: wholMnhlCnt{year}, step1~5MnhlCnt{year}
|
||||
* ex) wholMnhlCnt2014, step1MnhlCnt2025
|
||||
* rowType: SIDO_SUM(시도 합계/총계), BIZ_SUM(집중강우중점관리구역·그외)
|
||||
*/
|
||||
export interface FcltyManholeSummaryItem {
|
||||
ctpvNm: string;
|
||||
@@ -174,16 +173,12 @@ export interface FcltyManholeSummaryItem {
|
||||
rowType: string;
|
||||
emphsMngSeCd: string;
|
||||
emphsMngSeNm: string;
|
||||
|
||||
totWholMnhlCnt: number;
|
||||
totStep1MnhlCnt: number;
|
||||
totStep2MnhlCnt: number;
|
||||
totStep3MnhlCnt: number;
|
||||
totStep4MnhlCnt: number;
|
||||
totStep5MnhlCnt: number;
|
||||
|
||||
/** 연도별 동적 필드 (wholMnhlCnt{year} ~ step5MnhlCnt{year}) */
|
||||
[key: string]: string | number;
|
||||
wholMnhlCnt: number;
|
||||
frlvlMnhlCnt: number;
|
||||
sclvlMnhlCnt: number;
|
||||
thlvlMnhlCnt: number;
|
||||
folvlMnhlCnt: number;
|
||||
filvlMnhlCnt: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,8 +24,8 @@ function LoginPage() {
|
||||
await authService.login({ userId, password });
|
||||
try {
|
||||
await statisticsApi.refreshAllCommonCodes();
|
||||
} catch {
|
||||
// 로그인 성공 후 캐시 동기화 실패는 진입을 막지 않음
|
||||
} catch(error) {
|
||||
console.error('로그인 실패');
|
||||
}
|
||||
window.location.href = "/statistics";
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user