diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx index d216b88f6..44d039d7f 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx @@ -63,7 +63,7 @@ export const rainChkZod = z.object({ z.object({ chkgdnSn: z.number().nullable(), utztnUsgCd: z.string(), - ph: z.number().nullable(), + ph:z.string().nullish(), trbt: z.number().nullable(), grssClfg: z.number().nullable(), etc: z.string().nullable(), diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index 192bc43c3..629281f02 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -2,8 +2,17 @@ import { numSize } from "@/app/store/common/code/basicCode"; import type { TableUpperProps } from "@/app/store/common/type/header"; import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; -import { Checkbox, Input, TableCell, TableRow } from "@common/components/ui"; -import { formatCommaNumber, handleCommaNumberChange } from "./commom"; +import { + Checkbox, + Input, + TableCell, + TableRow, +} from "@common/components/ui"; +import { + formatCommaNumber, + handleCommaNumberChange, +} from "./commom"; +import moment from "moment"; export const rainChkTableData = (chkData: rainChkZodType[]) => { // 1. chkgdnSn + utztnUsgCd 기준 누계 정보 만들기 @@ -57,9 +66,7 @@ export const rswtChkTableData = (chkData: rswtChkZodType[]) => { // 1. chkgdnSn + utztnUsgCd 기준 누계 정보 만들기 const makeRswtData: any[] = []; - if (chkData && chkData.length > 0) { - chkData?.forEach((root) => { root.rswtrDetails.forEach((detail) => { let flatRswtChk = {}; @@ -96,20 +103,19 @@ export const chRowspanTable = ( toggleSelection: (pk: number, checked: boolean) => void, selectedIds: number[], handleCellClick: (index: number, headId: string) => void, - disable? : boolean + disable?: boolean ) => { - let order = 0 + let order = 0; // rowspan된 셀 렌더링 여부 추적용 const renderedMap = new Map>(); return ( <> {/* {makeTableData.map((row, rowIndex) => ( */} - {makeTableData && makeTableData.length > 0 ? (makeTableData.map((row, rowIndex) => ( - - {headList - .map((head) => { - + {makeTableData && makeTableData.length > 0 ? ( + makeTableData.map((row, rowIndex) => ( + + {headList.map((head) => { const key = head.id; const isMerged = head.mergeCell; const value = row[key]; @@ -118,7 +124,6 @@ export const chRowspanTable = ( if (isMerged) { const renderedSet = renderedMap.get(key) ?? new Set(); if (renderedSet.has(rowIndex)) { - return null; // 이미 렌더링된 셀은 skip } @@ -143,13 +148,13 @@ export const chRowspanTable = ( > ) : key === "order" ? ( ++order + ) : // value + ["anlOperCst", "dtfcltCpct", "prcsCpct"].includes( + head.id + ) ? ( + formatCommaNumber(value) ) : ( - // value - (["anlOperCst", "dtfcltCpct", "prcsCpct"].includes(head.id)) ? ( - formatCommaNumber(value) - ) : ( - <>{value} - ) + <>{value} )} ); @@ -163,23 +168,48 @@ export const chRowspanTable = ( onClick={() => handleCellClick(rowIndex, head.id)} > {head.edit === true ? ( - (["levyAmt", "anlOperCst", "dtfcltCpct", "prcsCpct"].includes(head.id)) ? ( + [ + "levyAmt", + "anlOperCst", + "dtfcltCpct", + "prcsCpct", + ].includes(head.id) ? ( { - handleCommaNumberChange(e, val => - handleChange(rowIndex, head.id, val)) + handleCommaNumberChange(e, (val) => + handleChange(rowIndex, head.id, val) + ); }} value={formatCommaNumber(value) || ""} disabled={!selectedIds.includes(row.chkgdnSn)} maxLength={numSize} onInput={(e: React.ChangeEvent) => { - if (head.type === 'number' && e.target.value.length > numSize) { + if ( + head.type === "number" && + e.target.value.length > numSize + ) { e.target.value = e.target.value.slice(0, numSize); } }} /> + ) : ["vltnDt"].includes(head.id) ? ( + { + // 브라우저에서 선택한 값은 "YYYY-MM-DD" + const rawDate = e.target.value; // e.g. "2025-06-01" + const yyyymmdd = moment(rawDate).format("YYYYMMDD"); + handleChange(rowIndex, head.id, yyyymmdd); + }} + value={ + value + ? moment(value, "YYYYMMDD").format("YYYY-MM-DD") + : "" + } + disabled={!selectedIds.includes(row.chkgdnSn)} + /> ) : ( ) => { - if (head.type === 'number' && e.target.value.length > numSize) { + if ( + head.type === "number" && + e.target.value.length > numSize + ) { e.target.value = e.target.value.slice(0, numSize); } }} /> ) + ) : [ + "totalSplyUswtrUtztnQnt", + "totalRuseFcltUtztnQnt", + "splyUswtrUtztnQnt", + "ruseFcltUtztnQnt", + "levyAmt", + ].includes(head.id) ? ( + + {formatCommaNumber(value)} + ) : ( - (["totalSplyUswtrUtztnQnt", "totalRuseFcltUtztnQnt", "splyUswtrUtztnQnt", "ruseFcltUtztnQnt", "levyAmt"].includes(head.id)) ? ( - - {formatCommaNumber(value)} - - ) : ( - <>{value} - ) + <>{value} )} ); })} - - ))) : ( + + )) + ) : ( - + 조회된 결과가 없습니다. @@ -221,16 +273,17 @@ export const chRowspanTable = ( ); }; -export const headVisibleChange = (headList: TableUpperProps[], isEdit: boolean) => { +export const headVisibleChange = ( + headList: TableUpperProps[], + isEdit: boolean +) => { return headList.forEach((head) => { - if (head.edit !== undefined) - head.edit = isEdit; - if (head.id === 'checkBox') { - head.visible = false + if (head.edit !== undefined) head.edit = isEdit; + if (head.id === "checkBox") { + head.visible = false; } - }); -} +}; const handleChange = ( rowIndex: number, @@ -253,8 +306,6 @@ const handleChange = ( }) ); }; -; - export const InputTableBody = ( chgRes: any[] | [], headList: TableUpperProps[], @@ -289,8 +340,10 @@ export const InputTableBody = ( return ( {headList.map((head, headIndex) => { - const isTextColumn = head.id === '구분' || head.id === '용수명'; - const textAlignClass = isTextColumn ? 'text-center' : 'text-right'; + const isTextColumn = head.id === "구분" || head.id === "용수명"; + const textAlignClass = isTextColumn + ? "text-center" + : "text-right"; // 총합계 행이면 "구분"에서 colSpan=2로 병합 if ( @@ -318,8 +371,13 @@ export const InputTableBody = ( // 총합계 행의 나머지 셀에도 색상 적용 if (data["구분"] === 0 || data["용수명"] === 0) { return ( - - {Number(data[head.id]) ? formatCommaNumber(data[head.id as keyof any]) : data[head.id as keyof any] ?? ""} + + {Number(data[head.id]) + ? formatCommaNumber(data[head.id as keyof any]) + : (data[head.id as keyof any] ?? "")} ); } @@ -328,21 +386,35 @@ export const InputTableBody = ( const rowSpan = getRowSpan(chgRes, head.id, dataIndex); if (rowSpan === 0) return null; return ( - - {Number(data[head.id]) ? formatCommaNumber(data[head.id as keyof any]) : data[head.id as keyof any] ?? ""} + + {Number(data[head.id]) + ? formatCommaNumber(data[head.id as keyof any]) + : (data[head.id as keyof any] ?? "")} ); } // 기본 셀 // return head.edit === true && data.edit !== false ? ( return isEditable && head.edit === true && data.edit !== false ? ( - + - handleCommaNumberChange(e, val => - handleChange(dataIndex, head.id, String(val), setInputData) + handleCommaNumberChange(e, (val) => + handleChange( + dataIndex, + head.id, + String(val), + setInputData + ) ) } value={formatCommaNumber(data[head.id as keyof any]) ?? ""} @@ -350,15 +422,20 @@ export const InputTableBody = ( /> ) : ( - +
- {Number(data[head.id]) ? formatCommaNumber(data[head.id as keyof any]) : data[head.id as keyof any] ?? ""} + {Number(data[head.id]) + ? formatCommaNumber(data[head.id as keyof any]) + : (data[head.id as keyof any] ?? "")}
); @@ -368,11 +445,14 @@ export const InputTableBody = ( })} {chgRes.length === 0 && ( - + 조회된 결과가 없습니다. )} ); -}; \ No newline at end of file +}; diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index fef689f46..7ba13e72a 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -150,6 +150,15 @@ export const formatCommaNumber = ( return num.toLocaleString(); }; +//내가 쓰는 값이 숫자이냐 아니냐 +export const isNumeric =(value: string) => { + if(value&&value.length>0){ + return value?.trim() !== "" && !isNaN(Number(value)); + }else{ + return false + } +} + export const getCityOrSgg = (ref: RefObject) => { let con; if (ref.current != null) @@ -163,6 +172,7 @@ export const getCityOrSgg = (ref: RefObject) => { export const safeDate = (value: any): Date | undefined => { const date = new Date(value); + console.log(' date ', date) return isNaN(date.getTime()) ? undefined : date; }; diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 0fb24366a..e3eaf4365 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -24,10 +24,11 @@ import { SelectBox } from "@common/business_components"; import { DatePicker, FormUi, UiModal } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import { Button, Input, Label } from "@common/components"; -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { useFieldArray, type UseFormReturn } from "react-hook-form"; import MngRegFormDetail from "../mngReg/mngRegFormDetail/mngRegFormDetail"; import { + //confirmToast, formatCommaNumber, handleCommaNumberChange, safeDate, @@ -38,6 +39,9 @@ import type { DemandCompType } from "@common/business_components/ui/sdmInsertFor import RuseMngTableForm from "@/components/ui/table/pbnstReg/ruseMngTableForm/ruseMngTableForm"; import type { SelectDataType } from "@common/business_components"; import { BuseWaterQulity } from "./buseWaterQulity/buseWaterQulity"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; +//import { useTranslation } from "react-i18next"; export function PbnstBuseForm({ indexMng = 0, @@ -54,6 +58,8 @@ export function PbnstBuseForm({ setIndexBiz: (index: number) => void; readonly?: boolean; }) { + const { t } = useTranslation("base"); + const { code, pbnst, @@ -157,22 +163,25 @@ export function PbnstBuseForm({ } }, [fcBizs, indexBiz, setIndexBiz]); // 2. Define a submit handler. - function addRuseFcltObj() { + const addRuseFcltObj = useCallback(async () => { + const formRuse = form.getValues(`items.${indexMng}`); const formBizs = form.getValues(`items.${indexMng}.fcBizs`); const pbnstBizCycle = formBizs.length; - // 🧩 새로운 fcBizs 기본 객체 생성 (필수값만 채우고 나머지는 default로) - const newItem = fcBizSchema.parse({ - cycl: pbnstBizCycle + 1, - pbnstRuseFcltId: formRuse.pbnstRuseFcltId, - fcOrgwts: undefined, - pplInstls: undefined, - fcDemands: undefined, - }); - appendBiz(newItem); - setIndexBiz(pbnstBizCycle); // 새로 추가된 차수로 포커스 이동 - } + const newItem = fcBizSchema.parse({ + cycl: pbnstBizCycle + 1, + pbnstRuseFcltId: formRuse.pbnstRuseFcltId, + fcOrgwts: [], + + pplInstls: [], + fcDemands: [], + }); + await appendBiz(newItem); + toast.success(t('insertRuseBiz',{cycle: pbnstBizCycle + 1})) + setIndexBiz(pbnstBizCycle); + }, [form, indexMng, indexBiz, appendBiz, setIndexBiz]); + const { fields: fcDemands, append: appendDemand } = useFieldArray({ control: form.control, name: `items.${indexMng}.fcBizs.${indexBiz}.fcDemands`, @@ -206,7 +215,7 @@ export function PbnstBuseForm({ } }, [ppiYn, indexMng, indexBiz]); - const plusHist = () => { + const plusHist = useCallback(() => { if ( form.getValues(`items.${indexMng}.fcBizs.${indexBiz}.pbnstRuseFcltBizSn`) ) { @@ -227,9 +236,9 @@ export function PbnstBuseForm({ cpct: 0, }); } - }; + }, [indexMng, indexBiz, appendPpl, form]); - const plusArray = () => { + const plusArray = useCallback(() => { appendDemand({ dmdCoNm: "", daddr: "", @@ -248,7 +257,7 @@ export function PbnstBuseForm({ dmdInfoId: "", //telno: "", }); - }; + }, [indexMng, indexBiz, appendDemand, form]); const removeSelected = () => { const nowPPl = form.getValues( @@ -293,7 +302,7 @@ export function PbnstBuseForm({ }, [form.formState, indexMng, indexBiz]); useEffect(() => { - console.log("form.formState ", form.formState); + //console.log("form.formState ", form.formState); }, [form.formState]); const pbnstBiz = form.watch(`items.${indexMng}.fcBizs`); @@ -489,17 +498,16 @@ export function PbnstBuseForm({
- - +
@@ -533,7 +541,10 @@ export function PbnstBuseForm({ 수요처 신규등록
-
+
{fcDemands.map((field, index) => (
{ setSelectedIds([])// 셀렉트 초기화를 위한 작업 if (rainChkData && rainChkData.length > 0) { - const rainChg = rainChkData?.map((item: any) => { const bud = tableData([item.building], { code }); + const rainyDetails= item.rainyDetails.map((detail)=>{ + return( + { + ...detail, + // 일단 테이블에서 사용하기 위해 넘버 전환 + ph: detail.ph&& !isNaN(detail.ph)?Number(detail.ph):detail.ph + } + ) + }) return { ...item, ...bud[0], + rainyDetails:rainyDetails, rowspan: item.rainyDetails?.length, }; }); + console.log('rainChg ', rainChg) setMakeTableData(rainChkTableData(rainChg)); } else { setMakeTableData([]); @@ -116,7 +126,8 @@ export default function RainChkgdTable({ if (findRain != undefined) { return { ...rd, - ph: Number(findRain.ph), + // 조드 타입과 맞추기위해 스트링 + ph: String(findRain.ph), trbt: Number(findRain.trbt), grssClfg: Number(findRain.grssClfg), etc: findRain.etc, diff --git a/apps/wr/public/locales/ko/message.json b/apps/wr/public/locales/ko/message.json index fb7af9ed2..fa122d798 100644 --- a/apps/wr/public/locales/ko/message.json +++ b/apps/wr/public/locales/ko/message.json @@ -22,5 +22,6 @@ "saveRowErrMsg": "수정을 원하는 행을 선택하고 저장버튼을 눌러주세요.", "costCalcErrMsg": "공사비 계산 진행 후 저장을 눌러주세요", "maxYearErrMsg": "최대 {{year}}년까지 선택가능합니다.", - "checkQtyMsg": "요구수량(m³/일)을 확인해주세요 계산할 수 없습니다." + "checkQtyMsg": "요구수량(m³/일)을 확인해주세요 계산할 수 없습니다.", + "insertRuseBiz": "{{cycle}}차 사업이 추가되었습니다." } \ No newline at end of file