From db74c07df89d5bea899af9b1379eadc306f6996c Mon Sep 17 00:00:00 2001 From: leedj312 Date: Fri, 4 Jul 2025 22:26:55 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=B0=ED=95=A8=EB=8C=80=EC=9E=A5=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/wr/app/matMng/coMat/coMatRvw/page.tsx | 33 ++++--- .../app/ruseFcltMng/fcltReg/pbnstReg/page.tsx | 90 +++++++++++++------ .../ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx | 38 ++++++++ .../prfmncReg/pbnstPrfmncReg/page.tsx | 39 +++++--- .../wr/app/store/matDmd/coMatRvw/headList.tsx | 4 +- apps/wr/components/lib/func/commom.tsx | 33 ++++--- .../ui/form/coMat/conCostForm/conCostForm.tsx | 11 ++- .../pbnPrfExcelModal/pbnPrfExcelModal.tsx | 49 ++++++---- .../fcltReg/pbnstRegModal/pbnstRegModal.tsx | 81 ++++++++++++++--- 9 files changed, 282 insertions(+), 96 deletions(-) create mode 100644 apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx diff --git a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx index c1e601320..46aeacbf3 100644 --- a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx +++ b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx @@ -9,6 +9,7 @@ import { } from "@/app/store/matDmd/coMatRvw/type"; import { formH1Class, formTableName } from "@/components/lib/class/comClass"; import { + formatPhoneNumber, getCity, getdmdMatFlag, tableData, @@ -33,7 +34,7 @@ import { import ListDiv from "@common/business_components/ui/list_div"; import { Button, Input, Label } from "@common/components/ui"; import { useEffect, useRef, useState } from "react"; -import { useForm } from "react-hook-form"; +import { useForm, useWatch } from "react-hook-form"; import toast, { Toaster } from "react-hot-toast"; import { z } from "zod"; import moment from "moment"; @@ -68,6 +69,7 @@ export default function CoMatRvw() { const [selectData, setSelectData] = useState( {} as DmdCoReqType ); + const [selectionVersion, setSelectionVersion] = useState(0); const getSearch = ( startYear: number, @@ -91,39 +93,46 @@ export default function CoMatRvw() { const form = useForm>({ resolver: zodResolver(DmdCoReqSchema), + shouldUnregister: true }); + const TableCellClick = (index: number) => { console.log(coMatRvwRes); if (coMatRvwRes && coMatRvwRes[index]) { - setSelectData(coMatRvwRes[index]); + setSelectionVersion((v) => v + 1); // 행을 클릭할 때마다 버전을 1씩 증가 } }; + const useUsgCdWatch = useWatch({ control: form.control, name: "useUsgCd" }); useEffect(() => { - if (form?.getValues("useUsgCd")) { + + console.log(' useUsgCdWatch page ' ,useUsgCdWatch) + if (useUsgCdWatch) { form.setValue( "demandCst.usgPrcsProcs", usageProcData?.find( - (item) => item.usage === (form?.getValues("useUsgCd") as string) + (item) => item.usage === useUsgCdWatch )?.process ?? "" ); } - }, [form.watch("useUsgCd")]); + }, [useUsgCdWatch, form,selectionVersion]); useEffect(() => { if (coMatRvwRes.length > 0) { const data = coMatRvwRes?.map((item, index) => { let flag = ""; - flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg ??""); + + flag = getdmdMatFlag(item?.demandMatching?.splyFcltFlg ||undefined); + return { ...item, ctpvCd: item.demandCo?.ctpvCd, sggCd: item.demandCo?.sggCd, dmdCoNm: item.demandCo?.dmdCoNm, daddr: item.demandCo?.daddr, - telno: item.demandCo?.telno, - regDt: moment(item?.demandCo?.regDt).format("YYYY-MM-DD"), + telno: formatPhoneNumber(item?.demandCo?.telno||''), + dmndTmng: item?.dmndTmng, splyFcltFlg: flag, }; }); @@ -151,8 +160,8 @@ export default function CoMatRvw() { useEffect(() => { if (selectData) { - console.log(selectData); form.reset(selectData); + setSelectionVersion((v) => v + 1); // 강제로 바뀌었다고 알리기 } }, [selectData, form]); return ( @@ -269,7 +278,7 @@ export default function CoMatRvw() { >
- + {/* */}

수요신청 상세현황 @@ -660,9 +669,9 @@ export default function CoMatRvw() { - + - + {/* */} diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 174f268d0..8d7e32c66 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -35,6 +35,10 @@ import { useFieldArray, useForm, type FieldErrors } from "react-hook-form"; // F import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; +import { createDefaultPbnstItem } from "./utilsZod"; + + + export default function PublicReuseFaciltyInsert() { const { code, @@ -100,7 +104,7 @@ export default function PublicReuseFaciltyInsert() { fcOpers: fclt.fcOpers, }; }); - await pbnstRuseFcltUpdate(pbnst as customPbnst[]); + await pbnstRuseFcltUpdate(pbnst as customPbnst[]) await pbnstRuseBizUpdate(bizs); }; @@ -115,21 +119,43 @@ export default function PublicReuseFaciltyInsert() { path: (string | number)[] = [] ): { message: string; path: (string | number)[] }[] => { if (!errorObject) return []; - - return Object.keys(errorObject).flatMap((key) => { - const value = errorObject[key]; - const currentKey = !isNaN(parseInt(key)) ? parseInt(key) : key; - const newPath = [...path, currentKey]; - if (value && typeof value === "object") { - if (typeof value.message === "string") { - return [{ message: value.message, path: newPath }]; // 에러 메시지와 경로 반환 - } - return findAllErrors(value, newPath); + + // Zod에서 배열 에러는 바로 배열로 전달됨 (예: items: [ {}, {...}, ... ]) + if (Array.isArray(errorObject)) { + return errorObject.flatMap((entry, index) => + findAllErrors(entry, [...path, index]) + ); + } + + if (typeof errorObject === "object") { + const entries: { message: string; path: (string | number)[] }[] = []; + + if (typeof errorObject.message === "string") { + entries.push({ message: errorObject.message, path }); } - return []; - }); + + if (Array.isArray(errorObject._errors)) { + for (const msg of errorObject._errors) { + entries.push({ message: msg, path }); + } + } + + const keys = Object.keys(errorObject).filter( + (k) => k !== "message" && k !== "_errors" + ); + + for (const key of keys) { + entries.push(...findAllErrors(errorObject[key], [...path, key])); + } + + return entries; + } + + return []; }; const errorList = findAllErrors(errors); + + console.log(' errors ', errors) if (errorList.length > 0) { errorList.forEach((errorInfo) => { const { message, path } = errorInfo; @@ -160,6 +186,9 @@ export default function PublicReuseFaciltyInsert() { }); } }; + useEffect(() => { + console.log("form errors:", form.formState.errors); + }, [form.formState.errors]); useEffect(() => { if (code.sggCd.length && pbnstHasuRes.length > 0) { @@ -184,6 +213,7 @@ export default function PublicReuseFaciltyInsert() { useEffect(() => { if (pbnst.pbnstRes && pbnst.pbnstRes?.length > 0) { + form.reset({ items: pbnstRegArrayZod.parse(pbnst.pbnstRes) }); } else { form.reset({ items: [] }); @@ -204,21 +234,23 @@ export default function PublicReuseFaciltyInsert() { if (pbnstRes && pbnstRes.length > 0) { const lastPbnst = pbnstRes[pbnstRes.length - 1]; if (lastPbnst && selecTableRow) { - append( - pbnstRegZod.parse({ - pbnstRuseFcltPk: - String(selecTableRow.bscFctCd) + String(pbnstRes.length + 1), - ruseUtztnFcltNm: "", - fcBizs: [ - fcBizSchema.parse({ - pbnstRuseFcltFk: - String(lastPbnst.pbnstRuseFcltPk) + - String(pbnstRes.length + 1), - cycl: 1, - }), - ] as fcBizType[], - }) - ); + // append( + // pbnstRegZod.parse({ + // pbnstRuseFcltPk: + // String(selecTableRow.bscFctCd) + String(pbnstRes.length + 1), + // ruseUtztnFcltNm: null, + // fcBizs: [ + // fcBizSchema.parse({ + // pbnstRuseFcltFk: + // String(lastPbnst.pbnstRuseFcltPk) + + // String(pbnstRes.length + 1), + // cycl: 1, + // }), + // ] as fcBizType[], + // }) + // ); + append(createDefaultPbnstItem(selecTableRow, pbnstRes.length)); + setIsRuseReg({ isModal: true }); } } else { @@ -396,7 +428,7 @@ export default function PublicReuseFaciltyInsert() { form={form} // form prop 전달 setPbnstInsert={(data) => { if (data) { - pbnstInsert(data); // pbnstInsert 함수 호출 + // pbnstInsert(data); // pbnstInsert 함수 호출 setIsRuseReg({ isModal: false }); } }} diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx new file mode 100644 index 000000000..14224fce2 --- /dev/null +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/utilsZod.tsx @@ -0,0 +1,38 @@ +import type { fcBizType, pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; + +export function createDefaultPbnstItem( + selecTableRow: pubHasuType, + index: number + ) { + const pk = String(selecTableRow.bscFctCd) + String(index + 1); + + return { + pbnstRuseFcltPk: pk, + swtrmtFcltFk: "", + ruseUtztnFcltNm: "", // 필수 입력이므로 빈 문자열로 + fcltCpct: 0, + ruseCpct: 0, + splyExtraCpct: 0, + regDt: null, + rgtr: "test", + mdfcnDt: null, + mdfr: "test", + fcFiles: [], + fcBizs: [ + createDefaultBiz(pk, 1), // 첫 차수 + ], + fcOpers: [], + }; + } + + + export function createDefaultBiz( + pbnstRuseFcltFk: string, + cycl: number + ): fcBizType { + return { + pbnstRuseFcltFk, + cycl, + // 필요한 값 있으면 여기에 추가 + } as fcBizType; + } \ No newline at end of file diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index 10dd7ccb6..f86367a17 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -37,6 +37,7 @@ import { type PrfType, } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; +import data from "@common/components/ui/icon-finder/data"; export default function prfmncPrfmncReg() { const { code, prfmnc, prfmncHasuInit, prfmnRegData } = useWrStore( @@ -78,9 +79,6 @@ export default function prfmncPrfmncReg() { } }, [inputData, searchYear, pbnstRuseFcltPk, prfmncHasuInit, pageNation]); - - - const cellClick = useCallback( (index: number | undefined, headId: string) => { if (index !== undefined) { @@ -88,16 +86,22 @@ export default function prfmncPrfmncReg() { isModal: false, data: prfmncRes[index] || ({} as FcPrfType), }); - const inUsageData = structuredClone(initValInUsage).map(row => ({ + const inUsageData = structuredClone(initValInUsage).map((row) => ({ ...row, 구분: "장내용수", })); - const outUsageData = structuredClone(initValOutUsage).map(row => ({ + const outUsageData = structuredClone(initValOutUsage).map((row) => ({ ...row, 구분: "장외용수", })); - const inSubtotal = { ...structuredClone(subTotalObj), 구분: "장내용수" }; - const outSubtotal = { ...structuredClone(subTotalObj), 구분: "장외용수" }; + const inSubtotal = { + ...structuredClone(subTotalObj), + 구분: "장내용수", + }; + const outSubtotal = { + ...structuredClone(subTotalObj), + 구분: "장외용수", + }; if (prfmncRes[index]?.prfList) { prfmncRes[index].prfList?.forEach((prfItem) => { const month = Number(prfItem?.ym?.slice(4)); // "MM" @@ -133,7 +137,11 @@ export default function prfmncPrfmncReg() { }); inUsageData.push(inSubtotal); outUsageData.push(outSubtotal); - const usageTotalObj: { [key: string]: any } = { ...structuredClone(totalObj), 구분: "총합계", 용수명: "" }; + const usageTotalObj: { [key: string]: any } = { + ...structuredClone(totalObj), + 구분: "총합계", + 용수명: "", + }; for (const key in usageTotalObj) { if (["usage", "gubun", "edit"].includes(key)) continue; const val = @@ -156,7 +164,7 @@ export default function prfmncPrfmncReg() { useEffect(() => { if (!prfmnc.isInit) { - prfmncHasuInit('1', "41"); + prfmncHasuInit("1", "41"); } }, [prfmnc.isInit, prfmncHasuInit]); useEffect(() => { @@ -203,7 +211,7 @@ export default function prfmncPrfmncReg() {
-