Merge branch 'iipbs/st/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/st/dev
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-total {
|
||||
@apply !bg-[#e3eaf2];
|
||||
}
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-selected-row {
|
||||
@apply !bg-[#dbeafe];
|
||||
}
|
||||
.rg-grid .rg-body .rg-table .rg-data-row .rg-data-cell.rg-cell-rowtype-biz-sum {
|
||||
@apply !bg-[#ffe9cf];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import CompactDataGrid from "./CompactDataGrid";
|
||||
import type { SplitDataGridProps } from "../type/DataGrid.type";
|
||||
|
||||
import CompactDataGrid from "./CompactDataGrid";
|
||||
|
||||
const SplitDataGrid = ({
|
||||
leftColumnInfo,
|
||||
rightColumnInfo,
|
||||
@@ -11,6 +12,8 @@ const SplitDataGrid = ({
|
||||
rightRowData,
|
||||
setLeftRowData,
|
||||
setRightRowData,
|
||||
leftOnRowClick,
|
||||
leftCellStyleCallback,
|
||||
enableSort = false,
|
||||
}: SplitDataGridProps) => {
|
||||
return (
|
||||
@@ -18,10 +21,12 @@ const SplitDataGrid = ({
|
||||
<CompactDataGrid
|
||||
columnInfo={leftColumnInfo}
|
||||
fixedColumns={leftFixedColumns}
|
||||
showHeaderCheckbox={showHeaderCheckbox}
|
||||
showHeaderCheckbox={false}
|
||||
enableSort={enableSort}
|
||||
rowData={leftRowData}
|
||||
setRowData={setLeftRowData}
|
||||
onRowClick={leftOnRowClick}
|
||||
cellStyleCallback={leftCellStyleCallback}
|
||||
/>
|
||||
<CompactDataGrid
|
||||
columnInfo={rightColumnInfo}
|
||||
|
||||
@@ -1,41 +1,338 @@
|
||||
import { useRef, useState } from 'react';
|
||||
|
||||
import SearchForm from '@/components/module/SearchForm';
|
||||
import DataGrid from '@/components/module/DataGrid';
|
||||
import SplitDataGrid from '@/components/module/SplitDataGrid';
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from '@common/components';
|
||||
import SubmitButton from '@/components/button/SumitButton';
|
||||
import SaveButton from '@/components/button/SaveButton';
|
||||
import OperateDataButton from '@/components/button/OperateDataButton';
|
||||
import UpdateOperateDataButton from '@/components/button/UpdateOperateDataButton';
|
||||
import { useConfirm } from '@frontend-opensource/use-react-hooks';
|
||||
|
||||
import type { ColumnInfo, ColumnInfoList } from '@/components/type/DataGrid.type';
|
||||
import type { SearchFormValues } from '@/components/type/SearchForm.type';
|
||||
import { PublicSewageFactInpColumnList } from '@/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactInpColumn';
|
||||
import { statisticsInputPublicSewageFacilityApiService } from '@/entities/statistics/api/input/statistics-public-sewage-facility-input-service';
|
||||
import type { PublicSewageFacilityRequestParams } from '@/entities/statistics/model/input/statistics-public-sewage-facility-input-interface';
|
||||
import { toGridRows } from '@/components/util/grid/gridFunction';
|
||||
import { useAlertStore } from '@/shared/lib';
|
||||
import { statisticsInputSewSupplyRateApi } from '@/entities/statistics/api/input/statistics-input-sew-supply-rate-service';
|
||||
import { statisticsInputPublicSewageFacilityApiService } from '@/entities/statistics/api/input/statistics-public-sewage-facility-input-service';
|
||||
import { statisticsApi } from '@/entities/statistics/api/statistics-service';
|
||||
import type {
|
||||
PublicSewageFacilityRequestParams,
|
||||
PublicSewageFacilitySaveItem,
|
||||
PublicSewageFacilitySaveRequest,
|
||||
PublicSewageMappingTargetsRequestParams,
|
||||
} from '@/entities/statistics/model/input/statistics-public-sewage-facility-input-interface';
|
||||
import {
|
||||
type CheckInputPeriodItem,
|
||||
getVerificationPeriodActionBlockedMessage,
|
||||
isInputPeriodCurrent,
|
||||
} from '@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface';
|
||||
import type { StatisticsInputSubmitInfoFormData } from '@/entities/statistics/model/statistics-input-submit-info-schema';
|
||||
import type { cancelSubmitRequest, ImrStatusResponse, SewerageStatusInfo } from '@/entities/statistics/model/statistics-interface';
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from '@common/components';
|
||||
|
||||
import { getUserInfo } from '../../../../../../packages/common/components/src/api';
|
||||
|
||||
import SubmitDailog from './SubmitDailog';
|
||||
|
||||
import CancelSubmitButton from '@/components/button/CancelSubmitButton';
|
||||
import NotApplicableCheckButton from '@/components/button/NotApplicableCheckButton';
|
||||
import SaveButton from '@/components/button/SaveButton';
|
||||
import SubmitButton from '@/components/button/SumitButton';
|
||||
import UpdateOperateDataButton from '@/components/button/UpdateOperateDataButton';
|
||||
import DataGrid from '@/components/module/DataGrid';
|
||||
import SearchForm from '@/components/module/SearchForm';
|
||||
import SplitDataGrid from '@/components/module/SplitDataGrid';
|
||||
import type { CellStyleCallbackParams, ColumnInfo, ColumnInfoList } from '@/components/type/DataGrid.type';
|
||||
import type { SearchFormValues } from '@/components/type/SearchForm.type';
|
||||
import { doList } from '@/components/util/column/input/DoList';
|
||||
import { PublicSewageFactInpColumnList } from '@/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactInpColumn';
|
||||
import { toGridRows } from '@/components/util/grid/gridFunction';
|
||||
import { useAdminStore } from '@/store/admin-store';
|
||||
|
||||
type TabToolbarSnapshot = {
|
||||
showSaveInToolbar: boolean;
|
||||
showEnterableToolbarButtons: boolean;
|
||||
showActionToolbarCard: boolean;
|
||||
};
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || '')
|
||||
? Boolean(values?.gugun && values.gugun !== 'ALL')
|
||||
: true;
|
||||
}
|
||||
|
||||
const computeTabEnterable = (
|
||||
statusInfo: SewerageStatusInfo | null | undefined,
|
||||
periodEnterable: boolean,
|
||||
): boolean => {
|
||||
if (statusInfo?.laeSbmsnSttsCd) {
|
||||
if (['2', '3'].includes(statusInfo.laeSbmsnSttsCd)) {
|
||||
return false;
|
||||
}
|
||||
return periodEnterable;
|
||||
}
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
statusInfo: SewerageStatusInfo | null,
|
||||
hasRowData: boolean,
|
||||
treatAsSearched: boolean,
|
||||
searchContext: SearchFormValues | null,
|
||||
periodEnterable: boolean,
|
||||
isAdminInfo: boolean,
|
||||
): TabToolbarSnapshot {
|
||||
const gugunOk = buildGugunOkForToolbar(searchContext);
|
||||
const enterable = computeTabEnterable(statusInfo, periodEnterable);
|
||||
const showSaveInToolbar = (enterable || isAdminInfo) && gugunOk;
|
||||
const showEnterableToolbarButtons = enterable && gugunOk;
|
||||
const showActionToolbarCard =
|
||||
(hasRowData || treatAsSearched) &&
|
||||
(showSaveInToolbar ||
|
||||
(statusInfo?.laeSbmsnSttsCd === '2' &&
|
||||
(isAdminInfo || (enterable && gugunOk))));
|
||||
return { showSaveInToolbar, showEnterableToolbarButtons, showActionToolbarCard };
|
||||
}
|
||||
|
||||
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
async function waitForImrJobCompleted(
|
||||
jobId: string,
|
||||
getStatus: (id: string) => Promise<ImrStatusResponse>,
|
||||
options?: {
|
||||
pollIntervalMs?: number;
|
||||
maxAttempts?: number;
|
||||
},
|
||||
): Promise<void> {
|
||||
const pollIntervalMs = options?.pollIntervalMs ?? 2000;
|
||||
const maxAttempts = options?.maxAttempts ?? 150;
|
||||
for (let i = 0; i < maxAttempts; i++) {
|
||||
const res = await getStatus(jobId);
|
||||
if (res.status === 'COMPLETED' && Number(res.job_prog) === 100) return;
|
||||
if (res.status === 'FAILED' || res.status === 'ERROR' || res.status === 'CANCELLED') {
|
||||
throw new Error(res.error_msg || `IMR 검증이 ${res.status} 상태로 종료되었습니다.`);
|
||||
}
|
||||
await sleep(pollIntervalMs);
|
||||
}
|
||||
throw new Error('IMR 검증 완료 대기 시간이 초과되었습니다.');
|
||||
}
|
||||
|
||||
// 하수도 통계 관리 > 06. 공공하수처리시설
|
||||
const PublicSewageFacilityInp = () => {
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [hasSearched, setHasSearched] = useState(false);
|
||||
const [isNotApplicable, setIsNotApplicable] = useState(false);
|
||||
const [showIsNotApplicable, setShowIsNotApplicable] = useState(false);
|
||||
const [searchValues, setSearchValues] = useState<SearchFormValues | null>(null);
|
||||
const [lastSearchedValues, setLastSearchedValues] = useState<SearchFormValues | null>(null);
|
||||
const [tabStatusInfoMap, setTabStatusInfoMap] = useState<Map<string, SewerageStatusInfo | null>>(new Map());
|
||||
const [tabStatsCdMap, setTabStatsCdMap] = useState<Map<string, string>>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<Map<string, TabToolbarSnapshot>>(() => new Map());
|
||||
const [inputPeriodEnterable, setInputPeriodEnterable] = useState(true);
|
||||
const [periodCheckList, setPeriodCheckList] = useState<CheckInputPeriodItem[]>([]);
|
||||
const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
const [selectedMainFacilitySn, setSelectedMainFacilitySn] = useState<string | null>(null);
|
||||
|
||||
const periodEnterableRef = useRef(true);
|
||||
const searchDoneRef = useRef(false);
|
||||
|
||||
const submitFunc = () => {
|
||||
console.log('submit');
|
||||
// 제출 로직
|
||||
void (async () => {
|
||||
if (activeTab !== 'ST00060001') {
|
||||
alert('ST00060002 제출 API 연동 전입니다.');
|
||||
return;
|
||||
}
|
||||
if (!lastSearchedValues || !searchParamRef.current) {
|
||||
alert('먼저 조회를 진행해주세요.');
|
||||
return;
|
||||
}
|
||||
const currentData = rowDataMap.get('ST00060001') ?? [];
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert('제출할 데이터가 없습니다.');
|
||||
return;
|
||||
}
|
||||
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
|
||||
if (verificationBlocked) {
|
||||
alert(verificationBlocked);
|
||||
return;
|
||||
}
|
||||
if (await confirm('제출 하시겠습니까?')) {
|
||||
setShowDailog(true);
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
const buildFacilitySaveList = (currentData: Record<string, string | number>[]): PublicSewageFacilitySaveItem[] => {
|
||||
const toNumber = (v: unknown): number => {
|
||||
if (v === null || v === undefined) return 0;
|
||||
if (v === '') return 0;
|
||||
const num = typeof v === 'string' ? parseFloat(v.replace(/,/g, '')) : (v as number);
|
||||
return Number.isFinite(num) ? num : 0;
|
||||
};
|
||||
|
||||
const toNullableString = (v: unknown): string | null => {
|
||||
if (v === null || v === undefined) return null;
|
||||
const s = typeof v === 'string' ? v : String(v);
|
||||
return s.trim() === '' ? null : s;
|
||||
};
|
||||
|
||||
return currentData.map((d) => ({
|
||||
admdstCd: String(d.admdstCd ?? ''),
|
||||
admdstNm: String(d.admdstNm ?? ''),
|
||||
swtrmtFcltCd: String(d.swtrmtFcltCd ?? ''),
|
||||
swtrmtFcltNm: String(d.swtrmtFcltNm ?? ''),
|
||||
fcltSn: String(d.fcltSn ?? ''),
|
||||
fcltPstnCn: d.fcltPstnCn === '' ? null : toNullableString(d.fcltPstnCn),
|
||||
inflwSwagePhysQnt: toNumber(d.inflwSwagePhysQnt),
|
||||
inflwSwageBoilQnt: toNumber(d.inflwSwageBoilQnt),
|
||||
inflwSwageAltdQnt: toNumber(d.inflwSwageAltdQnt),
|
||||
prcsPhysCpct: toNumber(d.prcsPhysCpct),
|
||||
prcsBoilCpct: toNumber(d.prcsBoilCpct),
|
||||
prcsAltdCpct: toNumber(d.prcsAltdCpct),
|
||||
prxyCtrtCn: d.prxyCtrtCn === '' ? null : toNullableString(d.prxyCtrtCn),
|
||||
sftyAcdntEvntcsCnt: toNumber(d.sftyAcdntEvntcsCnt),
|
||||
rmrk: toNullableString(d.rmrk),
|
||||
}));
|
||||
};
|
||||
|
||||
const getNoApplicableForRequest = (): boolean => {
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const enterable = computeTabEnterable(activeTabStatus, inputPeriodEnterable);
|
||||
const showEnterableToolbarButtons = enterable && gugunOk;
|
||||
const noApplicableVisible = showEnterableToolbarButtons && showIsNotApplicable;
|
||||
return noApplicableVisible ? Boolean(isNotApplicable) : false;
|
||||
};
|
||||
|
||||
const executeSubmit = async (submitInfo: StatisticsInputSubmitInfoFormData) => {
|
||||
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
|
||||
if (verificationBlocked) {
|
||||
alert(verificationBlocked);
|
||||
return;
|
||||
}
|
||||
if (activeTab !== 'ST00060001') {
|
||||
alert('ST00060002 제출 API 연동 전입니다.');
|
||||
return;
|
||||
}
|
||||
if (!lastSearchedValues || !searchParamRef.current) {
|
||||
alert('먼저 조회를 진행해주세요.');
|
||||
return;
|
||||
}
|
||||
const currentData = rowDataMap.get('ST00060001') ?? [];
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert('제출할 데이터가 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const submitList = buildFacilitySaveList(currentData);
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const statsCdForTab = tabStatsCdMap.get(activeTab) ?? activeTab;
|
||||
const requestData = {
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : lastSearchedValues.gugun ?? '',
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
userId: userInfo.userUnqId,
|
||||
noApplicable: getNoApplicableForRequest(),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
laeIdfrNm: submitInfo.laeIdfrNm,
|
||||
laeIdfrJbgdNm: submitInfo.laeIdfrJbgdNm,
|
||||
laeIdfrDeptNm: submitInfo.laeIdfrDeptNm,
|
||||
laeIdfrTelNo: submitInfo.laeIdfrTelNo,
|
||||
submitList,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputPublicSewageFacilityApiService.submitPublicSewageFacility(requestData);
|
||||
if (response.status === 'success') {
|
||||
if (response.data?.finalStatus === '5') {
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? '',
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? '',
|
||||
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === '4' ? '4' : '2',
|
||||
gen_verify_stts_cd: response.data?.nvpassed ? '1' : '2',
|
||||
};
|
||||
try {
|
||||
const imrResponse = await statisticsApi.callImrService(imrParam);
|
||||
if (imrResponse.job_id) {
|
||||
await waitForImrJobCompleted(
|
||||
imrResponse.job_id,
|
||||
(id) => statisticsApi.getImrStatus(id),
|
||||
);
|
||||
}
|
||||
alert('제출되었습니다.');
|
||||
} catch {
|
||||
alert('제출은 완료되었으나 IMR 검증 처리 중 오류가 발생했습니다.');
|
||||
}
|
||||
} else {
|
||||
alert(response.message || '제출 처리 결과를 확인해주세요.');
|
||||
}
|
||||
await loadPublicSewageFacilityActiveTabData(
|
||||
'ST00060001',
|
||||
searchParamRef.current,
|
||||
lastSearchedValues,
|
||||
);
|
||||
} else {
|
||||
alert(response.message || '데이터 제출 중 오류가 발생했습니다.');
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const saveFunc = () => {
|
||||
console.log('save');
|
||||
// 저장 로직
|
||||
};
|
||||
void (async () => {
|
||||
if (activeTab !== 'ST00060001') {
|
||||
alert('ST00060002 저장 API 연동 전입니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
const getOperateDataFunc = () => {
|
||||
console.log('get operate data');
|
||||
// 운영 데이터 가져오기
|
||||
if (!lastSearchedValues || !searchParamRef.current) {
|
||||
alert('먼저 조회를 진행해주세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentData = rowDataMap.get('ST00060001') ?? [];
|
||||
if (!currentData || currentData.length === 0) {
|
||||
alert('저장할 데이터가 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(await confirm("저장 하시겠습니까?"))) return;
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const saveList = buildFacilitySaveList(currentData);
|
||||
|
||||
const param: PublicSewageFacilitySaveRequest = {
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : lastSearchedValues.gugun ?? '',
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
userId: userInfo.userUnqId,
|
||||
superAdmin: isAdminInfo ? 'superAdmin' : '',
|
||||
noApplicable: getNoApplicableForRequest(),
|
||||
saveList,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputPublicSewageFacilityApiService.savePublicSewageFacility(param);
|
||||
if (response.status === 'success') {
|
||||
alert('저장되었습니다.');
|
||||
await loadPublicSewageFacilityActiveTabData(
|
||||
'ST00060001',
|
||||
searchParamRef.current,
|
||||
lastSearchedValues,
|
||||
);
|
||||
} else {
|
||||
alert(response.message || '데이터 저장 중 오류가 발생했습니다.');
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
const updateOperateDataButtonFunc = () => {
|
||||
@@ -51,6 +348,29 @@ const PublicSewageFacilityInp = () => {
|
||||
const firstTabKey = PublicSewageFactInpColumnList[0]?.tabKey ?? 'ST00060001';
|
||||
const searchParamRef = useRef<PublicSewageFacilityRequestParams | null>(null);
|
||||
|
||||
const commitToolbarSnapshotForLoadedTab = (
|
||||
tabKey: string,
|
||||
statusInfo: SewerageStatusInfo | null,
|
||||
hasRowData: boolean,
|
||||
searchContext: SearchFormValues | null,
|
||||
) => {
|
||||
setToolbarSnapshotByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(
|
||||
tabKey,
|
||||
computeTabToolbarSnapshot(
|
||||
statusInfo,
|
||||
hasRowData,
|
||||
searchDoneRef.current,
|
||||
searchContext,
|
||||
periodEnterableRef.current,
|
||||
isAdminInfo,
|
||||
),
|
||||
);
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
const buildPublicSewageFacilityParams = (values: SearchFormValues): PublicSewageFacilityRequestParams => ({
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
@@ -71,6 +391,7 @@ const PublicSewageFacilityInp = () => {
|
||||
const loadPublicSewageFacilityActiveTabData = async (
|
||||
tabKey: string,
|
||||
param: PublicSewageFacilityRequestParams,
|
||||
searchContext: SearchFormValues | null,
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
if (tabKey === 'ST00060001') {
|
||||
@@ -79,6 +400,9 @@ const PublicSewageFacilityInp = () => {
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
setSelectedMainFacilitySn(null);
|
||||
const statusInfo = response.data.statusInfo ?? null;
|
||||
const statsCd = response.data.commonInfo.statsCd || tabKey;
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const list = response.data.publicSewageFacilityList ?? [];
|
||||
const convertedData = list.map((item) => ({
|
||||
@@ -86,11 +410,30 @@ const PublicSewageFacilityInp = () => {
|
||||
...item,
|
||||
rmrk: item.rmrk ?? null,
|
||||
}));
|
||||
setRowDataMap((prev) => {
|
||||
|
||||
if (list.length === 0) {
|
||||
setShowIsNotApplicable(true);
|
||||
} else {
|
||||
setShowIsNotApplicable(false);
|
||||
}
|
||||
|
||||
const gridRows = toGridRows(convertedData);
|
||||
setTabStatusInfoMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set('ST00060001', toGridRows(convertedData));
|
||||
next.set(tabKey, statusInfo);
|
||||
return next;
|
||||
});
|
||||
setTabStatsCdMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, statsCd);
|
||||
return next;
|
||||
});
|
||||
setRowDataMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set('ST00060001', gridRows);
|
||||
return next;
|
||||
});
|
||||
commitToolbarSnapshotForLoadedTab(tabKey, statusInfo, gridRows.length > 0, searchContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,6 +443,9 @@ const PublicSewageFacilityInp = () => {
|
||||
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
|
||||
return false;
|
||||
}
|
||||
setSelectedMainFacilitySn(null);
|
||||
const statusInfo = response.data.statusInfo ?? null;
|
||||
const statsCd = response.data.commonInfo.statsCd || tabKey;
|
||||
const list = response.data.mainFacilityList ?? [];
|
||||
const leftRows = list.map((item) => ({
|
||||
swtrmtFcltNm: item.swtrmtFcltNm,
|
||||
@@ -115,12 +461,24 @@ const PublicSewageFacilityInp = () => {
|
||||
sggNm: item.sggNm ?? '',
|
||||
admdstNm: item.admdstNm,
|
||||
}));
|
||||
const leftGridRows = toGridRows(leftRows);
|
||||
setTabStatusInfoMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, statusInfo);
|
||||
return next;
|
||||
});
|
||||
setTabStatsCdMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, statsCd);
|
||||
return next;
|
||||
});
|
||||
setRowDataMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set('MainFacility', toGridRows(leftRows));
|
||||
next.set('MainFacility', leftGridRows);
|
||||
next.set('MainFacilityTarget', []);
|
||||
return next;
|
||||
});
|
||||
commitToolbarSnapshotForLoadedTab(tabKey, statusInfo, leftGridRows.length > 0, searchContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -137,22 +495,44 @@ const PublicSewageFacilityInp = () => {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const param = buildPublicSewageFacilityParams(values);
|
||||
const periodResponse = await statisticsInputSewSupplyRateApi.checkInputPeriod(values.year || '');
|
||||
if (periodResponse.status !== 'success') {
|
||||
alert(periodResponse.message);
|
||||
return;
|
||||
}
|
||||
const periods = Array.isArray(periodResponse.data) ? periodResponse.data : [];
|
||||
setPeriodCheckList(periods);
|
||||
const periodOk = isInputPeriodCurrent(periods);
|
||||
periodEnterableRef.current = periodOk;
|
||||
setInputPeriodEnterable(periodOk);
|
||||
|
||||
const yearChangedFromLastSearch =
|
||||
hasSearched &&
|
||||
(searchParamRef.current?.statsYr ?? '') !== (param.statsYr ?? '');
|
||||
lastSearchedValues != null &&
|
||||
(lastSearchedValues.year ?? '') !== (values.year ?? '');
|
||||
|
||||
// 조회 시 이전 선택 로우 강조 초기화
|
||||
setSelectedMainFacilitySn(null);
|
||||
|
||||
if (yearChangedFromLastSearch) {
|
||||
setRowDataMap(new Map());
|
||||
setTabStatusInfoMap(new Map());
|
||||
setTabStatsCdMap(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
}
|
||||
|
||||
searchParamRef.current = param;
|
||||
setLastSearchedValues(values);
|
||||
searchDoneRef.current = true;
|
||||
setHasSearched(true);
|
||||
|
||||
setIsLoading(true);
|
||||
const param = buildPublicSewageFacilityParams(values);
|
||||
searchParamRef.current = param;
|
||||
const tabKeyToLoad = yearChangedFromLastSearch ? firstTabKey : activeTabRef.current;
|
||||
await loadPublicSewageFacilityActiveTabData(tabKeyToLoad, param);
|
||||
await loadPublicSewageFacilityActiveTabData(tabKeyToLoad, param, values);
|
||||
} catch {
|
||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
@@ -165,12 +545,76 @@ const PublicSewageFacilityInp = () => {
|
||||
if (!hasSearched || tabRowDataExists(tabKey) || !searchParamRef.current) return;
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await loadPublicSewageFacilityActiveTabData(tabKey, searchParamRef.current);
|
||||
await loadPublicSewageFacilityActiveTabData(tabKey, searchParamRef.current, lastSearchedValues);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setIsLoading(false);
|
||||
setHasSearched(false);
|
||||
setIsNotApplicable(false);
|
||||
setShowIsNotApplicable(false);
|
||||
|
||||
setRowDataMap(new Map());
|
||||
setTabStatusInfoMap(new Map());
|
||||
setTabStatsCdMap(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
|
||||
setInputPeriodEnterable(true);
|
||||
periodEnterableRef.current = true;
|
||||
setPeriodCheckList([]);
|
||||
|
||||
searchParamRef.current = null;
|
||||
searchDoneRef.current = false;
|
||||
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
setLastSearchedValues(null);
|
||||
setSelectedMainFacilitySn(null);
|
||||
};
|
||||
|
||||
const cnacelSubmitFunc = async () => {
|
||||
try {
|
||||
if (await confirm('제출된 내용을 취소하시겠습니까?')) {
|
||||
const verificationBlocked = getVerificationPeriodActionBlockedMessage(periodCheckList);
|
||||
if (verificationBlocked) {
|
||||
alert(verificationBlocked);
|
||||
return;
|
||||
}
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const statsCdForCancel = tabStatsCdMap.get(activeTab) ?? activeTab;
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues?.bsnmCd ?? '',
|
||||
ctpvNm: lastSearchedValues?.sido ?? '',
|
||||
sggNm: lastSearchedValues?.gugun ?? '',
|
||||
statsYr: lastSearchedValues?.year ?? '',
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForCancel,
|
||||
};
|
||||
|
||||
const response = await statisticsApi.cancelSubmit(requestData);
|
||||
|
||||
if (response.status === 'success') {
|
||||
if (searchParamRef.current) {
|
||||
await loadPublicSewageFacilityActiveTabData(
|
||||
activeTab,
|
||||
searchParamRef.current,
|
||||
lastSearchedValues,
|
||||
);
|
||||
}
|
||||
alert('제출 취소되었습니다.');
|
||||
} else {
|
||||
alert(response.message ?? '제출 취소 중 오류가 발생했습니다.');
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
alert('제출 취소 중 오류가 발생했습니다.');
|
||||
}
|
||||
};
|
||||
|
||||
const getGridColumnInfo = (
|
||||
tab: ColumnInfoList,
|
||||
): ColumnInfo => ({
|
||||
@@ -178,18 +622,95 @@ const PublicSewageFacilityInp = () => {
|
||||
columnLayout: tab.columnLayout ?? [],
|
||||
});
|
||||
|
||||
const handleMainFacilityRowClick = async (rowData: Record<string, string | number>) => {
|
||||
if (!searchParamRef.current) {
|
||||
alert('먼저 조회를 진행해주세요.');
|
||||
return;
|
||||
}
|
||||
const fcltSn = String(rowData.fcltSn ?? '');
|
||||
if (!fcltSn) {
|
||||
alert('시설 일련번호가 없습니다.');
|
||||
return;
|
||||
}
|
||||
setSelectedMainFacilitySn(fcltSn);
|
||||
|
||||
const param: PublicSewageMappingTargetsRequestParams = {
|
||||
sewerBzmnCd: searchParamRef.current.sewerBzmnCd ?? '',
|
||||
ctpvNm: searchParamRef.current.ctpvNm ?? '',
|
||||
sggNm: searchParamRef.current.sggNm ?? '',
|
||||
statsYr: searchParamRef.current.statsYr ?? '',
|
||||
fcltSn,
|
||||
};
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputPublicSewageFacilityApiService.getMappingTargets(param);
|
||||
if (response.status !== 'success') {
|
||||
alert(response.message || '매핑 대상 조회 중 오류가 발생했습니다.');
|
||||
return;
|
||||
}
|
||||
const mappedTargetRows = (response.data ?? []).map((item) => ({
|
||||
...item,
|
||||
__checked: item.mappedYn === 'Y' ? 'Y' : '',
|
||||
}));
|
||||
setRowDataMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set('MainFacilityTarget', toGridRows(mappedTargetRows));
|
||||
return next;
|
||||
});
|
||||
} catch {
|
||||
alert('매핑 대상 조회 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const leftMainFacilityCellStyleCallback = ({ row }: CellStyleCallbackParams) => {
|
||||
if (!selectedMainFacilitySn) return;
|
||||
return String(row.fcltSn ?? '') === selectedMainFacilitySn ? 'rg-cell-selected-row' : undefined;
|
||||
};
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(activeTab),
|
||||
hasSearched,
|
||||
searchContextForToolbar,
|
||||
inputPeriodEnterable,
|
||||
isAdminInfo,
|
||||
);
|
||||
const { showSaveInToolbar, showEnterableToolbarButtons, showActionToolbarCard } = activeTabToolbar;
|
||||
const isMainFacilityTab = activeTab === 'ST00060002';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm fctName={true} onSubmit={handleSearch} />
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
|
||||
<UpdateOperateDataButton updateOperateDataButtonFunc={updateOperateDataButtonFunc} />
|
||||
<OperateDataButton getOperateDataFunc={getOperateDataFunc} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
<SaveButton saveFunc={saveFunc} />
|
||||
<SearchForm
|
||||
fctName={true}
|
||||
onSubmit={handleSearch}
|
||||
onReset={handleReset}
|
||||
onValuesChange={setSearchValues}
|
||||
/>
|
||||
{showActionToolbarCard && (
|
||||
<div className="card !py-0">
|
||||
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
||||
{showEnterableToolbarButtons && !isMainFacilityTab && (
|
||||
<>
|
||||
{showIsNotApplicable && <NotApplicableCheckButton isCheck={isNotApplicable} setIsCheck={setIsNotApplicable} />}
|
||||
<UpdateOperateDataButton updateOperateDataButtonFunc={updateOperateDataButtonFunc} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
</>
|
||||
)}
|
||||
{!isMainFacilityTab && activeTabStatus?.laeSbmsnSttsCd === '2' && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isLoading && <div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
|
||||
<div className="relative size-[5rem]">
|
||||
<LoadingWithAnimation color="primary" />
|
||||
@@ -216,10 +737,22 @@ const PublicSewageFacilityInp = () => {
|
||||
rightColumnInfo={getGridColumnInfo(tab.right)}
|
||||
leftFixedColumns={tab.left.fixedColumns}
|
||||
rightFixedColumns={tab.right.fixedColumns}
|
||||
showHeaderCheckbox={false}
|
||||
showHeaderCheckbox={true}
|
||||
enableSort={false}
|
||||
leftRowData={rowDataMap.get(leftKey) ?? []}
|
||||
rightRowData={rowDataMap.get(rightKey) ?? []}
|
||||
leftOnRowClick={
|
||||
tab.tabKey === 'ST00060002'
|
||||
? (row) => {
|
||||
void handleMainFacilityRowClick(row);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
leftCellStyleCallback={
|
||||
tab.tabKey === 'ST00060002'
|
||||
? leftMainFacilityCellStyleCallback
|
||||
: undefined
|
||||
}
|
||||
setLeftRowData={(updater) => {
|
||||
setRowDataMap((prev) => {
|
||||
const next = new Map(prev);
|
||||
@@ -256,6 +789,7 @@ const PublicSewageFacilityInp = () => {
|
||||
columnInfo={gridColumnInfo}
|
||||
rowStartNum={tab.rowStartNum}
|
||||
fixedColumns={tab.fixedColumns}
|
||||
statusInfo={activeTabStatus}
|
||||
rowData={rowDataMap.get(tab.tabKey) ?? []}
|
||||
setRowData={(updater) => {
|
||||
setRowDataMap((prev) => {
|
||||
@@ -277,6 +811,14 @@ const PublicSewageFacilityInp = () => {
|
||||
})}
|
||||
</Tabs>
|
||||
</div>
|
||||
<SubmitDailog
|
||||
open={showDailog}
|
||||
onOpenChange={setShowDailog}
|
||||
statusInfo={activeTabStatus}
|
||||
onConfirm={executeSubmit}
|
||||
submitMode="normal"
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1756,7 +1756,7 @@ const SewagePipeInp = () => {
|
||||
/>
|
||||
{showEnterableToolbarButtons && (
|
||||
<>
|
||||
<LastYearDataButton getLastYearDataFunc={() => void getLastYearDataFunc()} />
|
||||
{activeTab !== 'ST00020002' && <LastYearDataButton getLastYearDataFunc={() => void getLastYearDataFunc()} />}
|
||||
<SubmitButton submitFunc={() => void submitFunc(false)} />
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -295,9 +295,9 @@ const SeweragePenetrationRateInp = () => {
|
||||
statsCd: statsCd,
|
||||
};
|
||||
|
||||
// if (isAdminInfo) {
|
||||
// params.superAdmin = 'superAdmin';
|
||||
// }
|
||||
if (isAdminInfo) {
|
||||
params.superAdmin = 'superAdmin';
|
||||
}
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
|
||||
@@ -11,16 +11,21 @@ import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { SewagePipeColumnInfoListTot } from "@/components/util/column/total/SewagePipeTotColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import type { SewagePipeTotalRequest } from "@/entities/statistics/model/statistics-total/statistics-sewage-pipe-total-interface";
|
||||
import CellColorInfo from "./CellColorInfo";
|
||||
|
||||
const firstTabKey = SewagePipeColumnInfoListTot[0]?.tabKey ?? "ST00020001";
|
||||
|
||||
function buildSewagePipeTotSearchParam(values: SearchFormValues): SewagePipeTotalRequest {
|
||||
const isSummaryEnabled = values.isSummary !== 'ALL';
|
||||
const summaryYearCnt = isSummaryEnabled ? Number(values.isSummary) : undefined;
|
||||
|
||||
return {
|
||||
ctpvNm: values.sido === "ALL" ? "" : values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
statsYr: values.year,
|
||||
rowDataYn: values.isDetail,
|
||||
...(isSummaryEnabled ? { summaryYearCnt } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -164,7 +169,7 @@ const SewagePipeTot = () => {
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<SearchForm isDetail={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
|
||||
<SearchForm isDetail={true} isSummary={true} onSubmit={handleSearch} onReset={handleReset} sidoSelectText="전체" />
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
|
||||
<div className="relative size-[5rem]">
|
||||
@@ -172,6 +177,7 @@ const SewagePipeTot = () => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<CellColorInfo />
|
||||
<div className="flex flex-col gap-[0.6rem] mx-[0.6rem]">
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
@@ -221,10 +227,11 @@ const SewagePipeTot = () => {
|
||||
fixedColumns={info.fixedColumns}
|
||||
enableSort={false}
|
||||
cellStyleCallback={({ row }) => {
|
||||
const rowType = String(row.rowType ?? "");
|
||||
if (rowType === "DETAIL") return undefined;
|
||||
if (rowType === "BIZ_SUM") return "rg-cell-rowtype-biz-sum";
|
||||
return "rg-cell-rowtype-other";
|
||||
const rowType = String(row.rowType ?? '');
|
||||
if (rowType === 'DETAIL') return undefined;
|
||||
if (rowType === 'BIZ_SUM') return 'rg-cell-rowtype-biz-sum';
|
||||
if (rowType === 'SUMMARY') return 'rg-cell-rowtype-summary';
|
||||
return 'rg-cell-rowtype-other';
|
||||
}}
|
||||
/>
|
||||
</TabsContent>
|
||||
|
||||
+16
-18
@@ -1,6 +1,11 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useConfirm } from '@frontend-opensource/use-react-hooks';
|
||||
|
||||
import { useAlertStore } from '@/shared/lib';
|
||||
import { NoData } from '@/shared/ui/no-data';
|
||||
import { generalverificationApiService } from '@/entities/statistics/api/general-verification-service';
|
||||
import type { VerifyDetailData, VerifyDetailResponseDto } from '@/entities/statistics/model/general-verification-interface';
|
||||
import {
|
||||
Button,
|
||||
Table,
|
||||
@@ -9,17 +14,13 @@ import {
|
||||
TableHead,
|
||||
TableRow,
|
||||
} from "@common/components";
|
||||
import FormulaComponents from './FormulaComponents';
|
||||
import { LoadingWithAnimation } from '@common/components';
|
||||
import FomulaDialog from './FomulaDialog';
|
||||
|
||||
import { useAlertStore } from '@/shared/lib';
|
||||
import { useConfirm } from '@frontend-opensource/use-react-hooks';
|
||||
|
||||
import { generalverificationApiService } from '@/entities/statistics/api/general-verification-service';
|
||||
import type { VerifyDetailData, VerifyDetailResponseDto } from '@/entities/statistics/model/general-verification-interface';
|
||||
import { getUserInfo } from '../../../../../../../packages/common/components/src/api';
|
||||
|
||||
import FomulaDialog from './FomulaDialog';
|
||||
import FormulaComponents from './FormulaComponents';
|
||||
|
||||
interface DetailComponentProps {
|
||||
selectedVrfcRow: number | null;
|
||||
}
|
||||
@@ -107,19 +108,16 @@ const DetailComponent = ({ selectedVrfcRow }: DetailComponentProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 여러 항목일 때 마지막이 단항 연산자면: 이전 항목들 연산자는 무조건 null
|
||||
// 여러 항목일 때 마지막이 단항 연산자면:
|
||||
// 이전 항목들의 연산자는 '?'일 때만 등록 허용 (자동 null 보정하지 않음)
|
||||
if (rows.length > 1 && lastIsUnary) {
|
||||
for (let i = 0; i < rows.length - 1; i++) {
|
||||
const prev = rows[i];
|
||||
if (prev) prev.cmprOpert = null;
|
||||
}
|
||||
setFormulaList((prev) => {
|
||||
if (prev.length <= 1) return prev;
|
||||
const next = prev.map((item, idx) =>
|
||||
idx < prev.length - 1 && item != null ? { ...item, cmprOpert: null } : item,
|
||||
const invalidUnaryPrevIdx = rows.slice(0, -1).findIndex((r) => r.cmprOpert !== '?');
|
||||
if (invalidUnaryPrevIdx !== -1) {
|
||||
alert(
|
||||
`마지막 항목이 단항 연산자(is_null, !is_null, floor)일 때는 이전 항목의 연산자를 '?'로 선택해야 합니다.\n(순번: ${invalidUnaryPrevIdx + 1})`,
|
||||
);
|
||||
return next;
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 마지막 항목의 연산자는 (단항 연산자 케이스 제외) 무조건 null 처리
|
||||
|
||||
@@ -365,6 +365,10 @@ export type SplitDataGridProps = {
|
||||
setRightRowData: React.Dispatch<
|
||||
React.SetStateAction<Record<string, string | number>[]>
|
||||
>;
|
||||
/** 좌측 분할 그리드 행 클릭 이벤트 */
|
||||
leftOnRowClick?: (rowData: Record<string, string | number>) => void;
|
||||
/** 좌측 분할 그리드 셀 스타일 콜백 */
|
||||
leftCellStyleCallback?: CellStyleCallback;
|
||||
/** 전체 정렬 기능 on/off (기본값: false) */
|
||||
enableSort?: boolean;
|
||||
};
|
||||
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary";
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import { footerDecimal1, footerDecimal3,footerInt } from "@/components/util/grid/footerSummary";
|
||||
|
||||
/**
|
||||
* 하수도 통계 관리 > 06. 공공하수처리시설
|
||||
*/
|
||||
@@ -112,6 +113,7 @@ export const PublicSewageFactColumn = {
|
||||
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '처리시설일련번호' }, visible: false, editable: false, valueType: ValueType.TEXT, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'swtrmtFcltCd', fieldName: 'swtrmtFcltCd', header: { text: '하수처리시설코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
],
|
||||
|
||||
+39
-2
@@ -1,9 +1,16 @@
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { stClient } from "@/shared/api/client";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
|
||||
import type {
|
||||
PublicSewageMainFacilityResponse,
|
||||
PublicSewageFacilityRequestParams,
|
||||
PublicSewageFacilityResponse,
|
||||
PublicSewageFacilitySaveRequest,
|
||||
PublicSewageFacilitySaveResponse,
|
||||
PublicSewageFacilitySubmitRequest,
|
||||
PublicSewageFacilitySubmitResponse,
|
||||
PublicSewageMainFacilityResponse,
|
||||
PublicSewageMappingTargetsRequestParams,
|
||||
PublicSewageMappingTargetsResponse,
|
||||
StatisticsInputPublicSewageFacilityService,
|
||||
} from "../../model/input/statistics-public-sewage-facility-input-interface";
|
||||
|
||||
@@ -23,6 +30,36 @@ export class StatisticsInputPublicSewageFacilityApiService implements Statistics
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getMappingTargets(
|
||||
param: PublicSewageMappingTargetsRequestParams,
|
||||
): Promise<PublicSewageMappingTargetsResponse> {
|
||||
const response = await stClient.get<PublicSewageMappingTargetsResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/main-facility/mapping-targets`,
|
||||
{ params: param },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async savePublicSewageFacility(
|
||||
param: PublicSewageFacilitySaveRequest,
|
||||
): Promise<PublicSewageFacilitySaveResponse> {
|
||||
const response = await stClient.post<PublicSewageFacilitySaveResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/facility/save`,
|
||||
param,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async submitPublicSewageFacility(
|
||||
param: PublicSewageFacilitySubmitRequest,
|
||||
): Promise<PublicSewageFacilitySubmitResponse> {
|
||||
const response = await stClient.post<PublicSewageFacilitySubmitResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUT}/public-sewage-facility/facility/submit`,
|
||||
param,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const statisticsInputPublicSewageFacilityApiService = new StatisticsInputPublicSewageFacilityApiService();
|
||||
|
||||
+109
@@ -139,7 +139,116 @@ export interface PublicSewageMainFacilityResponse {
|
||||
data: PublicSewageMainFacilityResponseData;
|
||||
}
|
||||
|
||||
/** ST00060002 메인시설 클릭 시 우측 매핑대상 조회 요청 */
|
||||
export interface PublicSewageMappingTargetsRequestParams {
|
||||
sewerBzmnCd: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
statsYr: string;
|
||||
fcltSn: string;
|
||||
}
|
||||
|
||||
/** ST00060002 메인시설 클릭 시 우측 매핑대상 조회 항목 */
|
||||
export interface PublicSewageMappingTargetItem {
|
||||
fcltSn: string;
|
||||
admdstNm: string;
|
||||
swtrmtFcltCd: string;
|
||||
swtrmtFcltNm: string;
|
||||
fcltPstnCn: string;
|
||||
mappedYn: string;
|
||||
mainFcltSn: string;
|
||||
isMainYn: string;
|
||||
}
|
||||
|
||||
/** ST00060002 메인시설 클릭 시 우측 매핑대상 조회 응답 */
|
||||
export interface PublicSewageMappingTargetsResponse {
|
||||
status: string;
|
||||
message?: string;
|
||||
data: PublicSewageMappingTargetItem[];
|
||||
}
|
||||
|
||||
/** ST00060001 공공하수처리시설 저장 — saveList 항목 */
|
||||
export interface PublicSewageFacilitySaveItem {
|
||||
admdstCd: string;
|
||||
admdstNm: string;
|
||||
swtrmtFcltCd: string;
|
||||
swtrmtFcltNm: string;
|
||||
fcltSn: string;
|
||||
fcltPstnCn: string | null;
|
||||
|
||||
inflwSwagePhysQnt: number;
|
||||
inflwSwageBoilQnt: number;
|
||||
inflwSwageAltdQnt: number;
|
||||
|
||||
prcsPhysCpct: number;
|
||||
prcsBoilCpct: number;
|
||||
prcsAltdCpct: number;
|
||||
|
||||
prxyCtrtCn: string | null;
|
||||
sftyAcdntEvntcsCnt: number;
|
||||
rmrk: string | null;
|
||||
}
|
||||
|
||||
/** ST00060001 공공하수처리시설 저장 API 요청 */
|
||||
export interface PublicSewageFacilitySaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin: string;
|
||||
|
||||
/**
|
||||
* 저장 요청에서 "해당없음" 처리 여부가 함께 전달되는 경우를 고려합니다.
|
||||
* (백엔드 스펙에 따라 필수 여부는 달라질 수 있어 optional로 둡니다.)
|
||||
*/
|
||||
noApplicable?: boolean;
|
||||
|
||||
saveList: PublicSewageFacilitySaveItem[];
|
||||
}
|
||||
|
||||
export interface PublicSewageFacilitySaveResponse {
|
||||
data?: string;
|
||||
message?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
/** 공공하수처리시설 입력 제출 공통 본문 (`submitList` 제외) */
|
||||
export interface PublicSewageFacilitySubmitRequestBase {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
noApplicable?: boolean;
|
||||
laePicNm: string;
|
||||
laePicTelNo: string;
|
||||
laeKbrdrDeptNm: string;
|
||||
laeKbrdrJbgdNm: string;
|
||||
laeIdfrNm: string;
|
||||
laeIdfrTelNo: string;
|
||||
laeIdfrDeptNm: string;
|
||||
laeIdfrJbgdNm: string;
|
||||
}
|
||||
|
||||
/** ST00060001 공공하수처리시설 제출 API 요청 (`submitList` 행은 저장과 동일) */
|
||||
export interface PublicSewageFacilitySubmitRequest extends PublicSewageFacilitySubmitRequestBase {
|
||||
submitList: PublicSewageFacilitySaveItem[];
|
||||
}
|
||||
|
||||
export interface PublicSewageFacilitySubmitResponse {
|
||||
data: {
|
||||
finalStatus: string;
|
||||
nvpassed: boolean;
|
||||
}
|
||||
message?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface StatisticsInputPublicSewageFacilityService {
|
||||
getPublicSewageFacility(param: PublicSewageFacilityRequestParams): Promise<PublicSewageFacilityResponse>;
|
||||
getPublicSewageMainFacility(param: PublicSewageFacilityRequestParams): Promise<PublicSewageMainFacilityResponse>;
|
||||
getMappingTargets(param: PublicSewageMappingTargetsRequestParams): Promise<PublicSewageMappingTargetsResponse>;
|
||||
savePublicSewageFacility(param: PublicSewageFacilitySaveRequest): Promise<PublicSewageFacilitySaveResponse>;
|
||||
submitPublicSewageFacility(param: PublicSewageFacilitySubmitRequest): Promise<PublicSewageFacilitySubmitResponse>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user