From dae440a4b4cee35b6d5e080cba893e61ab8fa9d1 Mon Sep 17 00:00:00 2001 From: leedj312 Date: Tue, 26 Aug 2025 17:46:51 +0900 Subject: [PATCH] =?UTF-8?q?=EC=88=98=EC=9A=94=EC=B2=98=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EC=8B=9C=20=EC=A3=BC=EC=86=8C=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=84=9C=EC=B9=98=EC=9D=B8=ED=92=8B=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/ui/sdmInsertForm/form.tsx | 586 ++++++++++-------- .../src/ui/search_input_address/index.tsx | 3 + 2 files changed, 337 insertions(+), 252 deletions(-) diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index 20a2050bc..5099db92e 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -1,47 +1,48 @@ import { Input } from "@common/components"; import { AsYouType } from "libphonenumber-js"; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from "react"; import type { ControllerRenderProps, UseFormReturn } from "react-hook-form"; import { FormField } from "../form"; import { FormUi } from "../form_ui"; import { SelectBox } from "../select"; import { SdmSearchForm } from "./sdmNameBox"; +import SearchInputAddress from "../search_input_address"; +import type { addressType } from "../search_input_address/findAddress"; // 수요처 정보 export type DemandCompType = { - index : number | ''; - dmdInfoId : string | ''; - bzmnNo : string | ''; - dmdCoNm : string | ''; - daddr : string | ''; - telno : string | ''; - rgtr : string | ''; - useUsgCd : string | ''; - ctpvCd : string | ''; - sggCd : string | ''; - dmdAplyPswd : string | ''; - wntUntprc : number | ''; - dmndTmng : Date | ''; - dmndQty : number | ''; - grssClfg : number | ''; - tn : number | ''; - combResdch : number | ''; - tph : number | ''; - trbt : number | ''; - ph : number | ''; - blgcOxygDmndQnt : number | ''; - clIonQnt : number | ''; - smll : number | ''; - cdtnv : number | ''; - crmty : number | ''; - rmrk : string | ''; - reqDt : string | ''; -} - + index: number | ""; + dmdInfoId: string | ""; + bzmnNo: string | ""; + dmdCoNm: string | ""; + daddr: string | ""; + telno: string | ""; + rgtr: string | ""; + useUsgCd: string | ""; + ctpvCd: string | ""; + sggCd: string | ""; + dmdAplyPswd: string | ""; + wntUntprc: number | ""; + dmndTmng: Date | ""; + dmndQty: number | ""; + grssClfg: number | ""; + tn: number | ""; + combResdch: number | ""; + tph: number | ""; + trbt: number | ""; + ph: number | ""; + blgcOxygDmndQnt: number | ""; + clIonQnt: number | ""; + smll: number | ""; + cdtnv: number | ""; + crmty: number | ""; + rmrk: string | ""; + reqDt: string | ""; +}; type SelectDataType = { - text: string; - val: string; + text: string; + val: string; }; interface FormSchema { @@ -52,7 +53,7 @@ interface FormSchema { daddr: string; telno: string; bznmTotNo?: string; - rgtr?: string | ''; + rgtr?: string | ""; dmdAplyPswd?: string; dmdAplyPswdConfirm?: string; } @@ -65,38 +66,50 @@ interface SdmRegFormProps { dataList: DemandCompType[]; rtnValue: (searchText: string, pageCnt: number) => void; setIsDuplicate: (value: boolean) => void; - updateList?:DemandCompType - readOnly?:boolean + updateList?: DemandCompType; + readOnly?: boolean; } -type FieldComponent = (field: ControllerRenderProps) => JSX.Element; +type FieldComponent = ( + field: ControllerRenderProps, +) => JSX.Element; -export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigunData, dataList, rtnValue, setIsDuplicate ,updateList,readOnly}: SdmRegFormProps) { - const [sidoValue, setSidoValue] = useState(''); - const [sigunValue, setSigunValue] = useState(''); - const [filteredSigunData, setFilteredSigunData] = useState([{ text: "전체", val: '0' }]); +export function SdmRegForm({ + form, + onCheckboxChange, + selectSidoData, + selectSigunData, + dataList, + rtnValue, + setIsDuplicate, + updateList, + readOnly, +}: SdmRegFormProps) { + const [sidoValue, setSidoValue] = useState(""); + const [sigunValue, setSigunValue] = useState(""); + const [filteredSigunData, setFilteredSigunData] = useState([ + { text: "전체", val: "0" }, + ]); const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true); - const [orgBznmNo, setOrgBznmNo] = useState(''); - const [updateCoNm, setUpdateNm] = useState('') + const [orgBznmNo, setOrgBznmNo] = useState(""); + const [updateCoNm, setUpdateNm] = useState(""); - - - const formatPhoneNumber = (value:string) => { + const formatPhoneNumber = (value: string) => { const input = value; const formatter = new AsYouType("KR"); const formatted = formatter.input(input); - return formatted + return formatted; }; // 사업자등록번호 포맷팅 함수 (3-2-5 형식) const formatBusinessNumber = (value: string) => { // 숫자만 추출 const digitsOnly = value.replace(/\D/g, ""); - + // 10자리까지만 처리 const limitedDigits = digitsOnly.slice(0, 10); - + // 3-2-5 형식으로 포맷팅 if (limitedDigits.length <= 3) { return limitedDigits; @@ -107,136 +120,166 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun } }; - - const initializeSigunData = useCallback((sidoCd: string) => { - if (sidoCd === '0') { - setSigunValue('0'); - setFilteredSigunData([{ text: "전체", val: '0' }]); - } else { - const newFilteredData = [ - { text: "전체", val: '0' }, - ...selectSigunData.filter((item: SelectDataType) => item.val.substring(0, 2) === sidoCd) - ]; - setSigunValue('0'); - setFilteredSigunData(newFilteredData); - } - }, [selectSigunData]); - - const onSelectValue = useCallback(( - val: string, - type: string, - field: ControllerRenderProps | undefined - ) => { - if(!updateList?.dmdInfoId) - switch (type) { - case "ctpvCd": - initializeSigunData(val); - setSidoValue(val); - field?.onChange(val); - form.setValue('dmdInfoId', ''); - form.setValue('bznmTotNo', ''); - break; - case "sggCd": - setSigunValue(val); - field?.onChange(val); - form.setValue('dmdInfoId', ''); - form.setValue('bznmTotNo', ''); - break; - } - }, [initializeSigunData, form,updateList]); - - const handleCheckboxChange = useCallback((checked: boolean) => { - setIsBznmTotNoDisabled(checked); - onCheckboxChange?.(checked); - }, [onCheckboxChange]); - - const setRtnValue = useCallback((searchText: string, pageCnt: number) => { - rtnValue(searchText, pageCnt); - }, [rtnValue]); - - const setRtnData = useCallback((item: DemandCompType) => { - const rtnCompData = item; - - form.setValue('dmdCoNm', rtnCompData?.dmdCoNm || ''); - form.setValue('dmdInfoId', rtnCompData?.dmdInfoId.substring(0,10) || ''); - form.setValue('bznmTotNo', rtnCompData?.dmdInfoId.substring(10,14)==='0000' ? '' : rtnCompData?.dmdInfoId.substring(10,14)); - - // 수요처 불러온 후 사업자번호를 바꿀경우를 대비함 - setOrgBznmNo(rtnCompData?.dmdInfoId); - const sidoCd = rtnCompData?.ctpvCd.trim() || ''; - setSidoValue(sidoCd); - form.setValue('ctpvCd', sidoCd); - initializeSigunData(sidoCd); - - setTimeout(() => { - const sigunCd = rtnCompData?.sggCd.trim() || ''; - setSigunValue(sigunCd); - form.setValue('sggCd', sigunCd); - }, 100); - - if(rtnCompData?.dmdInfoId.substring(10,14) === '0000') { - handleCheckboxChange(true); - } else { - handleCheckboxChange(false); - } - - form.setValue('daddr', rtnCompData?.daddr || ''); - form.setValue('telno', rtnCompData?.telno || ''); - - // 선택을 했을 때 중복 상태를 true로 설정 - setIsDuplicate(true); - }, [form, handleCheckboxChange, initializeSigunData, setIsDuplicate]); - - const setRtnText = useCallback((text: string) => { - form.setValue('dmdCoNm', text); - }, [form]); - - const bznNoChange = useCallback((e: React.ChangeEvent, noType: string, field?: ControllerRenderProps) => { - const value = e.target.value; - - if(noType === 'dmdInfoId') { - // 숫자만 추출하여 저장 (포맷팅 제거) - const digitsOnly = value.replace(/\D/g, ""); - - if(orgBznmNo.substring(0,10) === digitsOnly) { - setIsDuplicate(true); + const initializeSigunData = useCallback( + (sidoCd: string) => { + if (sidoCd === "0") { + setSigunValue("0"); + setFilteredSigunData([{ text: "전체", val: "0" }]); } else { - setIsDuplicate(false); + const newFilteredData = [ + { text: "전체", val: "0" }, + ...selectSigunData.filter( + (item: SelectDataType) => item.val.substring(0, 2) === sidoCd, + ), + ]; + setSigunValue("0"); + setFilteredSigunData(newFilteredData); } - field?.onChange(digitsOnly); - } else { - if(orgBznmNo.substring(10,14) === value) { - setIsDuplicate(true); - } else { - setIsDuplicate(false); - } - field?.onChange(value); - } - }, [orgBznmNo, setIsDuplicate]); + }, + [selectSigunData], + ); - - useEffect(() => { - form.setValue('rgtr', '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e'); - - if(updateList?.dmdInfoId){ - form.reset(updateList) - if(updateList?.dmdInfoId.slice(10,14) !== '0000') { - handleCheckboxChange( false); - form.setValue('bznmTotNo', updateList?.dmdInfoId.slice(10,14)); - } else { - handleCheckboxChange( true); + const onSelectValue = useCallback( + ( + val: string, + type: string, + field: ControllerRenderProps | undefined, + ) => { + if (!updateList?.dmdInfoId) + switch (type) { + case "ctpvCd": + initializeSigunData(val); + setSidoValue(val); + field?.onChange(val); + form.setValue("dmdInfoId", ""); + form.setValue("bznmTotNo", ""); + break; + case "sggCd": + setSigunValue(val); + field?.onChange(val); + form.setValue("dmdInfoId", ""); + form.setValue("bznmTotNo", ""); + break; } - form.setValue('dmdInfoId', updateList?.dmdInfoId.slice(0,10)); - setUpdateNm(updateList?.dmdCoNm) - // setSigunValue(updateList?.sggCd) - }else{ - handleCheckboxChange( true); - } - }, [updateList,form]); + }, + [initializeSigunData, form, updateList], + ); + + const handleCheckboxChange = useCallback( + (checked: boolean) => { + setIsBznmTotNoDisabled(checked); + onCheckboxChange?.(checked); + }, + [onCheckboxChange], + ); + + const setRtnValue = useCallback( + (searchText: string, pageCnt: number) => { + rtnValue(searchText, pageCnt); + }, + [rtnValue], + ); + + const setRtnData = useCallback( + (item: DemandCompType) => { + const rtnCompData = item; + + form.setValue("dmdCoNm", rtnCompData?.dmdCoNm || ""); + form.setValue("dmdInfoId", rtnCompData?.dmdInfoId.substring(0, 10) || ""); + form.setValue( + "bznmTotNo", + rtnCompData?.dmdInfoId.substring(10, 14) === "0000" + ? "" + : rtnCompData?.dmdInfoId.substring(10, 14), + ); + + // 수요처 불러온 후 사업자번호를 바꿀경우를 대비함 + setOrgBznmNo(rtnCompData?.dmdInfoId); + const sidoCd = rtnCompData?.ctpvCd.trim() || ""; + setSidoValue(sidoCd); + form.setValue("ctpvCd", sidoCd); + initializeSigunData(sidoCd); + + setTimeout(() => { + const sigunCd = rtnCompData?.sggCd.trim() || ""; + setSigunValue(sigunCd); + form.setValue("sggCd", sigunCd); + }, 100); + + if (rtnCompData?.dmdInfoId.substring(10, 14) === "0000") { + handleCheckboxChange(true); + } else { + handleCheckboxChange(false); + } + + form.setValue("daddr", rtnCompData?.daddr || ""); + form.setValue("telno", rtnCompData?.telno || ""); + + // 선택을 했을 때 중복 상태를 true로 설정 + setIsDuplicate(true); + }, + [form, handleCheckboxChange, initializeSigunData, setIsDuplicate], + ); + + const setRtnText = useCallback( + (text: string) => { + form.setValue("dmdCoNm", text); + }, + [form], + ); + + const bznNoChange = useCallback( + ( + e: React.ChangeEvent, + noType: string, + field?: ControllerRenderProps, + ) => { + const value = e.target.value; + + if (noType === "dmdInfoId") { + // 숫자만 추출하여 저장 (포맷팅 제거) + const digitsOnly = value.replace(/\D/g, ""); + + if (orgBznmNo.substring(0, 10) === digitsOnly) { + setIsDuplicate(true); + } else { + setIsDuplicate(false); + } + field?.onChange(digitsOnly); + } else { + if (orgBznmNo.substring(10, 14) === value) { + setIsDuplicate(true); + } else { + setIsDuplicate(false); + } + field?.onChange(value); + } + }, + [orgBznmNo, setIsDuplicate], + ); useEffect(() => { - console.log( 'form.formState.errors ', form.formState.errors) - },[form.formState.errors]) + form.setValue("rgtr", "2d4b151d-1828-41e0-91d9-4cd28ea1cc7e"); + + if (updateList?.dmdInfoId) { + form.reset(updateList); + if (updateList?.dmdInfoId.slice(10, 14) !== "0000") { + handleCheckboxChange(false); + form.setValue("bznmTotNo", updateList?.dmdInfoId.slice(10, 14)); + } else { + handleCheckboxChange(true); + } + form.setValue("dmdInfoId", updateList?.dmdInfoId.slice(0, 10)); + setUpdateNm(updateList?.dmdCoNm); + // setSigunValue(updateList?.sggCd) + } else { + handleCheckboxChange(true); + } + }, [updateList, form]); + + useEffect(() => { + console.log("form.formState.errors ", form.formState.errors); + }, [form.formState.errors]); const formFields: Array<{ name: keyof FormSchema; @@ -246,53 +289,64 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun { name: "ctpvCd", label: "시도", - component: (field) => ( + component: (field) => updateList?.dmdInfoId ? ( {field.onChange(e.target.value)} } - value={ selectSidoData.find(item => item.val === field.value?.trim() )?.text??''} - readOnly={!!updateList?.dmdInfoId} + onChange={(e) => { + field.onChange(e.target.value); + }} + value={ + selectSidoData.find((item) => item.val === field.value?.trim()) + ?.text ?? "" + } + readOnly={!!updateList?.dmdInfoId} /> ) : ( - onSelectValue(val.toString(), 'ctpvCd', field??'')} - className="" - value={sidoValue} - /> - ) - ) + + onSelectValue(val.toString(), "ctpvCd", field ?? "") + } + className="" + value={sidoValue} + /> + ), }, { name: "sggCd", label: "시군구", - component: (field) => ( + component: (field) => updateList?.dmdInfoId ? ( {field.onChange(e.target.value)} } - value={selectSigunData.find(item => item.val === field.value?.trim() )?.text??''} - readOnly={!!updateList?.dmdInfoId} + onChange={(e) => { + field.onChange(e.target.value); + }} + value={ + selectSigunData.find((item) => item.val === field.value?.trim()) + ?.text ?? "" + } + readOnly={!!updateList?.dmdInfoId} /> ) : ( - onSelectValue(val.toString(), 'sggCd', field)} - className="" - value={sigunValue} - /> - - ) - ) + + onSelectValue(val.toString(), "sggCd", field) + } + className="" + value={sigunValue} + /> + ), }, { name: "dmdCoNm", @@ -308,117 +362,138 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun readOnly={readOnly} {...field} /> - ) + ), }, { name: "dmdInfoId", label: "사업자등록번호", component: (field) => ( - bznNoChange(e, 'dmdInfoId', field)} - value={formatBusinessNumber(field.value || '')} + onChange={(e) => bznNoChange(e, "dmdInfoId", field)} + value={formatBusinessNumber(field.value || "")} readOnly={!!updateList?.dmdInfoId} /> - ) + ), }, { name: "bznmTotNo", label: "", component: (field) => ( - - bznNoChange(e, 'bznmTotNo', field)} - // {...field} - value={ field.value} + onChange={(e) => bznNoChange(e, "bznmTotNo", field)} + // {...field} + value={field.value} readOnly={!!updateList?.dmdInfoId} /> - ) + ), }, { name: "daddr", label: "사업자주소", component: (field) => ( - + { + field.onChange(rtnData.roadAddrPart1); + console.log("rtnData ", rtnData); + }} /> - ) + ), }, { name: "telno", label: "전화번호", - component: (field) => - - { - const formattedValue = formatPhoneNumber(field.value??''); // 초기 렌더링 시에도 포맷 적용 + component: (field) => { + const formattedValue = formatPhoneNumber(field.value ?? ""); // 초기 렌더링 시에도 포맷 적용 return ( - { - const value = e.target.value.replace(/\D/g, ''); // 숫자만 저장 - field.onChange(value); - }} - /> - )} + { + const value = e.target.value.replace(/\D/g, ""); // 숫자만 저장 + field.onChange(value); + }} + /> + ); + }, }, - + { name: "dmdAplyPswd", label: "패스워드", component: (field) => ( - - ) + ), }, { name: "dmdAplyPswdConfirm", label: "패스워드확인", component: (field) => ( - - ) - } - ] + ), + }, + ]; return ( <> {formFields - .filter(({ name }) => !(updateList?.dmdInfoId && (name === "dmdAplyPswd" || name === "dmdAplyPswdConfirm"))) + .filter( + ({ name }) => + !( + updateList?.dmdInfoId && + (name === "dmdAplyPswd" || name === "dmdAplyPswdConfirm") + ), + ) .map(({ name, label, component }) => { const error = form.formState.errors[name]; const inputId = `${name}-input`; const errorId = `${name}-error`; - const isRequired = ["ctpvCd", "sggCd", "dmdCoNm", "dmdInfoId", "daddr", "telno", "dmdAplyPswd", "dmdAplyPswdConfirm"].includes(name); + const isRequired = [ + "ctpvCd", + "sggCd", + "dmdCoNm", + "dmdInfoId", + "daddr", + "telno", + "dmdAplyPswd", + "dmdAplyPswdConfirm", + ].includes(name); return ( (
-