diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index cef70a624..7516fa3d5 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -33,6 +33,7 @@ import { hasAdmdstCdColumn, isExcelImportAdmdstCdInvalid, mergeExcelImportWithExistingRows, + parseExcelImportCellValue, prepareGridColumnsForExcelExport, releaseFixedOptionsForExcelExport, resolveColumnStyleName, @@ -1346,6 +1347,11 @@ useEffect(() => { columnLayout, { skipNonEditable: false }, ); + const valueTypeByFieldName = new Map( + columns + .filter((c) => c.fieldName) + .map((c) => [c.fieldName as string, c.valueType]), + ); // 데이터 행 읽기 const dataRows: Record[] = []; @@ -1367,36 +1373,13 @@ useEffect(() => { ]; const fieldName = excelColumnFieldNames[colIndex]; const allFieldName = excelColumnFieldNamesAll[colIndex]; - - let cellValue: string | number = ""; - if ( - cell && - cell.v !== undefined && - cell.v !== null - ) { - // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 - if ( - cell.t === "n" || - (typeof cell.v === "number" && - !isNaN(cell.v)) - ) { - cellValue = cell.v as number; - } else { - const stringValue = String(cell.v); - // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 - const numericValue = Number( - stringValue.replace(/,/g, ""), - ); - if ( - !isNaN(numericValue) && - stringValue.trim() !== "" - ) { - cellValue = numericValue; - } else { - cellValue = stringValue; - } - } - } + const typeFieldName = fieldName || allFieldName; + const cellValue = parseExcelImportCellValue( + cell, + typeFieldName + ? valueTypeByFieldName.get(typeFieldName) + : undefined, + ); if (allFieldName === "admdstCd" && cellValue !== "") { rowAdmdstCd = cellValue; diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 3da27a42d..5c60f1a51 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -53,6 +53,7 @@ import { hasAdmdstCdColumn, isExcelImportAdmdstCdInvalid, mergeExcelImportWithExistingRows, + parseExcelImportCellValue, prepareGridColumnsForExcelExport, releaseFixedOptionsForExcelExport, resolveColumnStyleName, @@ -611,6 +612,11 @@ const TabDataGrid = ({ columnLayout, { skipNonEditable: false }, ); + const valueTypeByFieldName = new Map( + columns + .filter((c) => c.fieldName) + .map((c) => [c.fieldName as string, c.valueType]), + ); // 데이터 행 읽기 const dataRows: Record[] = []; @@ -625,23 +631,13 @@ const TabDataGrid = ({ const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; const fieldName = excelColumnFieldNames[colIndex]; const allFieldName = excelColumnFieldNamesAll[colIndex]; - - let cellValue: string | number = ''; - if (cell && cell.v !== undefined && cell.v !== null) { - // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 - if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { - cellValue = cell.v as number; - } else { - const stringValue = String(cell.v); - // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 - const numericValue = Number(stringValue.replace(/,/g, '')); - if (!isNaN(numericValue) && stringValue.trim() !== '') { - cellValue = numericValue; - } else { - cellValue = stringValue; - } - } - } + const typeFieldName = fieldName || allFieldName; + const cellValue = parseExcelImportCellValue( + cell, + typeFieldName + ? valueTypeByFieldName.get(typeFieldName) + : undefined, + ); if (allFieldName === 'admdstCd' && cellValue !== '') { rowAdmdstCd = cellValue; diff --git a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index d79f6be23..4ea9895f1 100644 --- a/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -620,7 +620,6 @@ function buildExcretaSlurgeProcessingStatusSaveItem( rcycQnt: toGridNumber(row.rcycQnt), olandLfvlm: toGridNumber(row.olandLfvlm), incnrQnt: toGridNumber(row.incnrQnt), - oceanInputQnt: toGridNumber(row.oceanInputQnt), fuelQnt: toGridNumber(row.fuelQnt), etcQnt: toGridNumber(row.etcQnt), unprcsQnt: toGridNumber(row.unprcsQnt), diff --git a/apps/st/src/components/statistics/input/StatisticsReviewHistory.tsx b/apps/st/src/components/statistics/input/StatisticsReviewHistory.tsx index bc89e8b35..03540e9ea 100644 --- a/apps/st/src/components/statistics/input/StatisticsReviewHistory.tsx +++ b/apps/st/src/components/statistics/input/StatisticsReviewHistory.tsx @@ -20,8 +20,8 @@ const StatisticsReviewHistory = () => { { name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false }, { name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false }, { name: "menuNm", fieldName: "menuNm", header: { text: "통계항목" }, editable: false }, - { name: "chckerOpinionSm", fieldName: "chckerOpinionSm", header: { text: "검토자의견" }, editable: false }, - { name: "wrterOpinionSm", fieldName: "wrterOpinionSm", header: { text: "처리내역" }, editable: false }, + { name: "splmntOpnnCn", fieldName: "splmntOpnnCn", header: { text: "검토자의견" }, editable: false }, + { name: "rjctOpnnCn", fieldName: "rjctOpnnCn", header: { text: "반려의견" }, editable: false }, ]; const columnLayout = [ @@ -29,8 +29,8 @@ const StatisticsReviewHistory = () => { "ctpvNm", "sggNm", "menuNm", - "chckerOpinionSm", - "wrterOpinionSm", + "splmntOpnnCn", + "rjctOpnnCn", ]; const handleSearch = async (values: SearchFormValues) => { diff --git a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx index 45bd3a755..9f8bc2ad2 100644 --- a/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/ExcretaTreatmentFacilityRvw.tsx @@ -49,7 +49,6 @@ const ExcretaTreatmentFacilityRvw = () => { const [reviewOpinionContext, setReviewOpinionContext] = useState(null); const [latestReviewOpinion, setLatestReviewOpinion] = useState(""); - const [latestProcessHistory, setLatestProcessHistory] = useState(""); const [lastSearchValues, setLastSearchValues] = useState(null); const columnInfo = useMemo(() => { @@ -116,7 +115,6 @@ const ExcretaTreatmentFacilityRvw = () => { setStatsStatusInfo({}); setReviewOpinionContext(null); setLatestReviewOpinion(""); - setLatestProcessHistory(""); setLastSearchValues(null); setReviewOpinionOpen(false); setReturnDialogOpen(false); @@ -170,14 +168,12 @@ const ExcretaTreatmentFacilityRvw = () => { statsCd: statsInfo.statsCd ?? "", }); setLatestReviewOpinion(statsInfo.splmntOpnnCn ?? ""); - setLatestProcessHistory(statsInfo.splmntRsltCn ?? ""); setRowData(toGridRows(convertedData as unknown as object[])); } else { setRowData([]); setStatsStatusInfo({}); setReviewOpinionContext(null); setLatestReviewOpinion(""); - setLatestProcessHistory(""); alert(response.message || "데이터가 없습니다."); } } catch { @@ -216,7 +212,6 @@ const ExcretaTreatmentFacilityRvw = () => { const row = detailRes.data?.[0]; setLatestReviewOpinion(row?.splmntOpnnCn ?? ""); - setLatestProcessHistory(row?.splmntRsltCn ?? ""); setReviewOpinionOpen(true); } catch { alert("검토의견 조회 중 오류가 발생했습니다."); @@ -234,10 +229,8 @@ const ExcretaTreatmentFacilityRvw = () => { setStatsStatusInfo((prev) => ({ ...prev, splmntOpnnCn: param.splmntOpnnCn, - splmntRsltCn: param.splmntRsltCn, })); setLatestReviewOpinion(param.splmntOpnnCn); - setLatestProcessHistory(param.splmntRsltCn); } catch { alert("저장 중 오류가 발생했습니다."); } @@ -297,7 +290,6 @@ const ExcretaTreatmentFacilityRvw = () => { onOpenChange={setReviewOpinionOpen} context={reviewOpinionContext} initialReviewOpinion={latestReviewOpinion} - initialProcessHistory={latestProcessHistory} onSave={saveReviewOpinion} /> { }, [activeStatsStatusInfo.statsCd, lastSearchValues]); const latestReviewOpinion = activeStatsStatusInfo.splmntOpnnCn ?? ""; - const latestProcessHistory = activeStatsStatusInfo.splmntRsltCn ?? ""; const submitDialogContext = useMemo(() => { if (lastSearchValues == null) return null; @@ -284,7 +283,6 @@ const PrivateSewageFacilityRvw = () => { next.set(activeTab, { ...(next.get(activeTab) ?? {}), splmntOpnnCn: row?.splmntOpnnCn ?? "", - splmntRsltCn: row?.splmntRsltCn ?? "", }); return next; }); @@ -307,7 +305,6 @@ const PrivateSewageFacilityRvw = () => { next.set(activeTab, { ...(next.get(activeTab) ?? {}), splmntOpnnCn: param.splmntOpnnCn, - splmntRsltCn: param.splmntRsltCn, }); return next; }); @@ -411,7 +408,6 @@ const PrivateSewageFacilityRvw = () => { onOpenChange={setReviewOpinionOpen} context={reviewOpinionContext} initialReviewOpinion={latestReviewOpinion} - initialProcessHistory={latestProcessHistory} onSave={saveReviewOpinion} /> { const [reviewOpinionContext, setReviewOpinionContext] = useState(null); const [latestReviewOpinion, setLatestReviewOpinion] = useState(""); - const [latestProcessHistory, setLatestProcessHistory] = useState(""); const [lastSearchValues, setLastSearchValues] = useState(null); const columnInfo = useMemo(() => { @@ -100,7 +99,6 @@ const PublicSewageFacilityRvw = () => { setStatsStatusInfo({}); setReviewOpinionContext(null); setLatestReviewOpinion(""); - setLatestProcessHistory(""); setLastSearchValues(null); setSubmitDialogOpen(false); }; @@ -143,16 +141,12 @@ const PublicSewageFacilityRvw = () => { setLatestReviewOpinion( response.data.statsStatusInfo.splmntOpnnCn ?? "", ); - setLatestProcessHistory( - response.data.statsStatusInfo.splmntRsltCn ?? "", - ); setRowData(toGridRows(convertedData as unknown as object[])); } else { setRowData([]); setStatsStatusInfo({}); setReviewOpinionContext(null); setLatestReviewOpinion(""); - setLatestProcessHistory(""); alert(response.message || "데이터가 없습니다."); } } catch (error) { @@ -192,7 +186,6 @@ const PublicSewageFacilityRvw = () => { const row = detailRes.data?.[0]; setLatestReviewOpinion(row?.splmntOpnnCn ?? ""); - setLatestProcessHistory(row?.splmntRsltCn ?? ""); setReviewOpinionOpen(true); } catch { alert("검토의견 조회 중 오류가 발생했습니다."); @@ -210,10 +203,8 @@ const PublicSewageFacilityRvw = () => { setStatsStatusInfo((prev) => ({ ...prev, splmntOpnnCn: param.splmntOpnnCn, - splmntRsltCn: param.splmntRsltCn, })); setLatestReviewOpinion(param.splmntOpnnCn); - setLatestProcessHistory(param.splmntRsltCn); } catch { alert("저장 중 오류가 발생했습니다."); } @@ -267,7 +258,6 @@ const PublicSewageFacilityRvw = () => { onOpenChange={setReviewOpinionOpen} context={reviewOpinionContext} initialReviewOpinion={latestReviewOpinion} - initialProcessHistory={latestProcessHistory} onSave={saveReviewOpinion} /> { const [reviewOpinionContext, setReviewOpinionContext] = useState(null); const [latestReviewOpinion, setLatestReviewOpinion] = useState(""); - const [latestProcessHistory, setLatestProcessHistory] = useState(""); const [lastSearchValues, setLastSearchValues] = useState(null); const columnInfo = useMemo(() => { @@ -111,7 +110,6 @@ const PumpingStationRvw = () => { setStatsStatusInfo({}); setReviewOpinionContext(null); setLatestReviewOpinion(""); - setLatestProcessHistory(""); setLastSearchValues(null); setReviewOpinionOpen(false); setReturnDialogOpen(false); @@ -157,14 +155,12 @@ const PumpingStationRvw = () => { statsCd: statsInfo.statsCd ?? "", }); setLatestReviewOpinion(statsInfo.splmntOpnnCn ?? ""); - setLatestProcessHistory(statsInfo.splmntRsltCn ?? ""); setRowData(toGridRows(convertedData)); } else { setRowData([]); setStatsStatusInfo({}); setReviewOpinionContext(null); setLatestReviewOpinion(""); - setLatestProcessHistory(""); alert(response.message || "데이터가 없습니다."); } } catch { @@ -203,7 +199,6 @@ const PumpingStationRvw = () => { const row = detailRes.data?.[0]; setLatestReviewOpinion(row?.splmntOpnnCn ?? ""); - setLatestProcessHistory(row?.splmntRsltCn ?? ""); setReviewOpinionOpen(true); } catch { alert("검토의견 조회 중 오류가 발생했습니다."); @@ -221,10 +216,8 @@ const PumpingStationRvw = () => { setStatsStatusInfo((prev) => ({ ...prev, splmntOpnnCn: param.splmntOpnnCn, - splmntRsltCn: param.splmntRsltCn, })); setLatestReviewOpinion(param.splmntOpnnCn); - setLatestProcessHistory(param.splmntRsltCn); } catch { alert("저장 중 오류가 발생했습니다."); } @@ -284,7 +277,6 @@ const PumpingStationRvw = () => { onOpenChange={setReviewOpinionOpen} context={reviewOpinionContext} initialReviewOpinion={latestReviewOpinion} - initialProcessHistory={latestProcessHistory} onSave={saveReviewOpinion} /> void | Promise; } @@ -41,18 +39,15 @@ export function ReviewOpinionDialog({ onOpenChange, context, initialReviewOpinion = "", - initialProcessHistory = "", onSave, }: ReviewOpinionDialogProps) { const { setMessage: alert } = useAlertStore((state) => state); const [reviewOpinion, setReviewOpinion] = useState(""); - const [processHistory, setProcessHistory] = useState(""); const [isSaving, setIsSaving] = useState(false); const [reviewOpinionError, setReviewOpinionError] = useState(false); const resetForm = () => { setReviewOpinion(""); - setProcessHistory(""); setReviewOpinionError(false); }; @@ -64,8 +59,7 @@ export function ReviewOpinionDialog({ useEffect(() => { if (!open) return; setReviewOpinion(initialReviewOpinion); - setProcessHistory(initialProcessHistory); - }, [open, initialReviewOpinion, initialProcessHistory]); + }, [open, initialReviewOpinion]); const handleSave = async () => { if (reviewOpinion.trim() === "") { @@ -96,7 +90,6 @@ export function ReviewOpinionDialog({ sewerBzmnCd: context.sewerBzmnCd, statsCd: context.statsCd, splmntOpnnCn: reviewOpinion, - splmntRsltCn: processHistory, mdfrUuid: userInfo.userUnqId, }; await onSave?.(param); @@ -136,16 +129,6 @@ export function ReviewOpinionDialog({

)} -
- -