Merge remote-tracking branch 'origin/iipbs/wr/dev' into iipbs/wr/form_fuction

This commit is contained in:
jyha00
2025-06-26 11:27:44 +09:00
27 changed files with 995 additions and 878 deletions
@@ -105,7 +105,7 @@ export default function RuseCaseMng() {
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<ListDiv>
<ListDiv className="overflow-x-auto">
<UiTable
headName={"물재이용사례 현황"}
tableData={[]}
@@ -40,7 +40,7 @@ export default function Home() {
useEffect(() => {
if (!htdfl.isInit) {
initHtdfl('41');
initHtdfl('0');
}
}, [htdfl.isInit, initHtdfl]);
@@ -82,7 +82,7 @@ export default function Home() {
setBdstChgProps({ isOpen: true, chgBuilding: chgBuilding });
};
useEffect(() => {
getHtdflBdstData(pageNation, "41");
getHtdflBdstData(pageNation, "0");
}, [pageNation]);
return (
@@ -42,14 +42,12 @@ export default function PublicReuseFaciltyInsert() {
searchFclts,
pubHasuInit,
pbnstRegClick,
pbnstMngData,
pbnstRuseFcltUpdate,
pubHasuSearch,
pbnstRuseBizUpdate,
} = useWrStore((state) => state);
const { pubFacHeadList, pbnstHasuRes, pbnstRes } = pbnst;
const [currentTab, setCurrentTab] = useState<string>("mng");
const [pbnstBiz, setPbnstBiz] = useState<fcBizType[]>();
const [isRuseReg, setIsRuseReg] = useState<{
isModal: boolean;
data: pubHasuType;
@@ -60,19 +58,15 @@ export default function PublicReuseFaciltyInsert() {
const [searchTxt, setSearchTxt] = useState<string>();
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
const [selectRow, setSelectRow] = useState<pubHasuType>();
const [pageNation, setPageNation] = useState<number>(1);
// const form = useForm<z.infer<typeof pbnstRegArrayZod>>({
// resolver: zodResolver(pbnstRegArrayZod),
// defaultValues: pbnstRegArrayZod.parse([]),
// mode: "onChange",
// });
const form = useForm<{
items: z.infer<typeof pbnstRegZod>[];
}>({
resolver: zodResolver(z.object({ items: pbnstRegArrayZod })),
defaultValues: { items: pbnstRegArrayZod.parse([]) },
mode:"onChange"
// defaultValues: { items: pbnstRegArrayZod.parse([]) },
mode: "onChange",
});
const {
fields: items,
@@ -84,21 +78,31 @@ export default function PublicReuseFaciltyInsert() {
});
useEffect(() => {
if (!pbnst.isInit) {
pubHasuInit("1", "11");
pubHasuInit("1", "41");
}
}, [pbnst.isInit, pubHasuInit]);
const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => {
const data = writeRgtrAndMdfr(valuse.items);
let bizs = [] as fcBizType[];
data.forEach((fclt) => {
bizs = [...bizs, ...fclt.fcBizs];
});
const pbnst =data.map((fclt) => {
return({
pbnstRuseFcltPk: fclt.pbnstRuseFcltPk,
fcltCpct: fclt.fcltCpct,
ruseCpct: fclt.ruseCpct,
splyExtraCpct: fclt.splyExtraCpct,
rgtr: fclt.rgtr,
mdfr: fclt.mdfr,
fcFiles: fclt.fcFiles,
fcOpers: fclt.fcOpers,
})
})
await pbnstRuseFcltUpdate(pbnst as customPbnst[]);
await pbnstRuseFcltUpdate(data);
await pbnstRuseBizUpdate(bizs);
await pbnstRuseBizUpdate(bizs);
};
useEffect(() => {
@@ -114,9 +118,8 @@ export default function PublicReuseFaciltyInsert() {
const cellClick = (val: number | undefined) => {
if (val === undefined) return;
const selectRow = pbnstHasuRes?.[val];
setSelectRow(pbnstHasuRes?.[val])
setSelectRow(pbnstHasuRes?.[val]);
if (selectRow) {
//setIsRuseReg({ ...isRuseReg, data: selectRow });
pbnstRegClick(selectRow);
}
};
@@ -126,8 +129,13 @@ export default function PublicReuseFaciltyInsert() {
};
useEffect(() => {
if (pbnst.pbnstRes) {
if (pbnst.pbnstRes&& pbnst.pbnstRes?.length>0) {
console.log("pbnst.pbnstRes", pbnstRes);
form.reset({ items: pbnstRegArrayZod.parse(pbnst.pbnstRes) });
}else{
console.log("pbnst.pbnstRes is null", pbnstRes);
form.reset({ items: [] });
}
}, [pbnst.pbnstRes]);
useEffect(() => {
@@ -137,39 +145,57 @@ export default function PublicReuseFaciltyInsert() {
}, [indexMng]);
useEffect(() => {
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
console.log("form errors:", form.formState.errors);
}, [form.formState.errors]);
const appendPbnstRuseFclt = useCallback(() => {
const selecTableRow = selectRow;
const appendPbnstRuseFclt = useCallback(() => {
if (pbnstRes && pbnstRes.length > 0) {
const lastPbnst = pbnstRes[pbnstRes.length - 1];
console.log('lastPbnst.swtrmtFcltFk ', lastPbnst)
if(lastPbnst){
if (lastPbnst && selecTableRow) {
append(
pbnstRegZod.parse({
pbnstRuseFcltPk: String(lastPbnst.pbnstRuseFcltPk) + String(pbnstRes.length + 1),
pbnstRuseFcltPk:
String(selecTableRow.bscFctCd) + String(pbnstRes.length + 1),
ruseUtztnFcltNm: "",
fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(lastPbnst.pbnstRuseFcltPk) + String(pbnstRes.length + 1),cycl:1})] as fcBizType[],
fcBizs: [
fcBizSchema.parse({
pbnstRuseFcltFk:
String(lastPbnst.pbnstRuseFcltPk) +
String(pbnstRes.length + 1),
cycl: 1,
}),
] as fcBizType[],
})
);
setIsRuseReg({ ...isRuseReg, isModal: true })
setIsRuseReg({ ...isRuseReg, isModal: true });
}
} else {
if(selectRow){
if (selecTableRow) {
append(
pbnstRegZod.parse({
pbnstRuseFcltPk: String(selectRow.bscFctCd)+'1',
ruseUtztnFcltNm: "",
regDt: null,
mdfcnDt: null,
fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(selectRow.bscFctCd)+'1',cycl:1})] as fcBizType[],
})
);
setIsRuseReg({ ...isRuseReg, isModal: true })
pbnstRegZod.parse({
pbnstRuseFcltPk: String(selecTableRow.bscFctCd)+'1',
ruseUtztnFcltNm: "",
regDt: null,
mdfcnDt: null,
fcBizs: [fcBizSchema.parse({pbnstRuseFcltFk:String(selecTableRow.bscFctCd)+'1',cycl:1})] as fcBizType[],
})
)
setIsRuseReg({ ...isRuseReg, isModal: true });
}
}
},[pbnstRegZod,pbnstRes,append,selectRow])
}, [pbnstRegZod, pbnstRes, append, selectRow, form]);
useEffect(() => {
// console.log(" page getgetvaslue ", form.getValues());
}, [form.getValues()]);
useEffect(() =>{
pubHasuInit(String(pageNation), "41");
},[pageNation,pubHasuInit])
return (
<>
<ContentsDiv>
@@ -192,8 +218,8 @@ export default function PublicReuseFaciltyInsert() {
size={"sm"}
onClick={(e) => {
searchTxt && searchTxt?.length > 0
? pubHasuSearch("1", "11", searchTxt)
: pubHasuInit("1", "11");
? pubHasuSearch(String(pageNation), "41", searchTxt)
: pubHasuInit(String(pageNation), "41");
}}
>
조회
@@ -202,13 +228,14 @@ export default function PublicReuseFaciltyInsert() {
size={"sm"}
className=""
onClick={() => {
pbnstMngData([] as customPbnst[]);
if(!selectRow){
toast.error("하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요")
return
}else{
appendPbnstRuseFclt()
// pbnstMngData([] as customPbnst[]);
if (!selectRow) {
toast.error(
"하수리시시설을 테이블을 선택하고 등록버튼을 눌러주세요"
);
return;
} else {
appendPbnstRuseFclt();
}
}}
>
@@ -227,11 +254,11 @@ export default function PublicReuseFaciltyInsert() {
<UiTable
tableData={bdstTable || []}
headlist={pubFacHeadList}
pageSize={100}
total={10}
pageSize={10}
total={100000}
headName={"공공 하수처리시설 등록"}
cellClick={cellClick}
onPageChange={(page: number) => {}}
onPageChange={setPageNation}
children={undefined}
/>
</ScrollArea>
@@ -260,6 +287,7 @@ export default function PublicReuseFaciltyInsert() {
formType="update"
form={form}
setIndexMng={(index: number) => {
console.log("setIndexMng", index);
setIndexMng(index);
}}
indexMng={indexMng}
@@ -286,10 +314,10 @@ export default function PublicReuseFaciltyInsert() {
data={isRuseReg.data || ({} as customPbnst)}
></PbnstRegModal>
}
bodyClass="w-[68vw] max-w-none h-[90vh]"
bodyClass="w-[68vw] max-w-none h-[90vh]"
open={isRuseReg.isModal}
onOpenChange={(open) => {
remove(form.getValues("items").length - 1)
remove(form.getValues("items").length - 1);
setIsRuseReg({ data: {} as pubHasuType, isModal: open });
}}
/>
@@ -16,15 +16,8 @@ import { Button, Label } from "@common/components/ui";
import HeadChModal from "@/components/ui/modal/sttn/headChModal/headChModal";
import { useCallback, useEffect, useRef, useState } from "react";
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
import type {
customPbnst,
pubHasuType,
} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import {
excelDownload,
getCityOrSgg,
yearOptions,
} from "@/components/lib/func/commom";
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { excelDownload, yearOptions } from "@/components/lib/func/commom";
import SearchInputText from "@/components/ui/searchInput/searchInput";
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
@@ -43,7 +36,6 @@ export default function PbnstSttn() {
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
const [pageNation, setPageNation] = useState(1);
const [isChHead, setIsChHead] = useState(false);
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>();
const [pbnDetaileData, setPbnDetaileData] = useState<{
@@ -87,14 +79,17 @@ export default function PbnstSttn() {
}
}, [pbnstSttn.isInit, pbnSttnInit, ref.current]);
useEffect(() => {
setBdstTable(pbnstSttn.pbnstSttnRes);
}, [pbnstSttn.pbnstSttnRes]);
useEffect(() => {
if (pbnRuseNm.length > 1)
pbnNmSearch("1", "23", ref.current, pbnRuseNm, searchYear);
}, [pbnRuseNm]);
// useEffect(() => {
// pbnstSttnSearch("1", "20", ref.current, pbnRuseNm, searchYear);
// }, [pageNation, ref.current, pbnRuseNm, searchYear, pbnstSttnSearch]);
// useEffect(() => {
// if (pbnRuseNm.length > 1)
// pbnNmSearch(String(pageNation), "23", ref.current, pbnRuseNm, searchYear);
// }, [pbnRuseNm,pageNation]);
useEffect(() => {
if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk)
@@ -104,15 +99,14 @@ export default function PbnstSttn() {
});
}, [pbnstSttn.pbnstDetail]);
useEffect(() => {
console.log('pbnDetaileData.isModal ', pbnDetaileData.isModal)
},[pbnDetaileData.isModal])
useEffect(() => {
console.log("pbnDetaileData.isModal ", pbnDetaileData.isModal);
}, [pbnDetaileData.isModal]);
return (
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
<div className="col-span-4">
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<Title title={"하수재이용 시설 현황"} />
<SearchBaseForm
selectSidoData={code.cityCd}
@@ -132,41 +126,32 @@ export default function PbnstSttn() {
</Button>
}
leftChildren={
<>
<div className="flex flex-row space-x-2">
<SelectBox
className="w-48 h-full text-2xl"
label="연도"
selectClass={""}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
</div>
<SearchInputText
label={"하수처리시설"}
initValue={pbnRuseNm ?? ""}
setValue={(searchNm?: string) => {
setPbnRuseNm(searchNm || "");
}}
setRtnData={function (rtnData: any[]): void {
setBdstTable(rtnData);
}}
searchList={pbnstSttn.pbnstSearchData || []}
></SearchInputText>
</>
<div className="col-span-3 flex items-center">
<SelectBox
className="w-48 h-full text-2xl"
label="연도"
selectClass={"w-full "}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
<Label className="w-64 mt-2 mx-4 text-xl text-gray-600">
{"하수처리시설명 "}
</Label>
<SearchInput
className={"text-2xl w-full ㅍ"}
label=""
textValue={pbnRuseNm || ""}
setText={(e) => {
setPbnRuseNm(e || "");
}}
/>
</div>
}
queryClick={function (returnType: ReturnType): void {
// '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}'
let con;
if (returnType.sigunValue != "0") {
con = returnType.sigunValue;
} else {
con = returnType.sidoValue;
}
// pbnstSttnSearch(1, "20", con);
pbnstSttnSearch("1", "20", returnType, pbnRuseNm, searchYear);
}}
excelClick={excelClick}
initClick={function (): void {}}
@@ -191,7 +176,15 @@ export default function PbnstSttn() {
cellClick={(index: number | undefined, headId: string) => {
cellCLick(index);
}}
onPageChange={setPageNation}
onPageChange={(page: number) => {
pbnstSttnSearch(
String(page),
String(13),
ref.current,
pbnRuseNm,
searchYear
);
}}
></UiTable>
</ListDiv>
</div>
@@ -2,7 +2,10 @@
import { useWrStore } from "@/app/store";
import { type rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn";
import type { rswtChkZodType, rswtrChkDetailsZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn";
import type {
rswtChkZodType,
rswtrChkDetailsZodType,
} from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn";
import {
excelArrayDownload,
excelDownload,
@@ -26,6 +29,7 @@ import ListDiv from "@common/business_components/ui/list_div";
import { Button, Label } from "@common/components/ui";
import { useCallback, useEffect, useState } from "react";
import { Toaster } from "react-hot-toast";
import { shallow } from "zustand/shallow";
//-----------------------
export default function Page() {
@@ -53,9 +57,9 @@ export default function Page() {
const [updateRainDetail, setUpdateRainDetail] = useState<rainChkZodType[]>(
[]
);
const [updateRswtDetail, setUpdateRSwtDetail] = useState<rswtrChkDetailsZodType[]>(
[]
);
const [updateRswtDetail, setUpdateRSwtDetail] = useState<
rswtrChkDetailsZodType[]
>([]);
const [deleteIdx, setDeleteIdx] = useState<number[]>([]);
const [selFcltDiv, setSelFcltDiv] = useState("RNB");
@@ -67,13 +71,14 @@ export default function Page() {
if (searchYear) rainChkInit(searchYear, "0");
};
const [searchYear, setSearchYear] = useState<string>(String(new Date().getFullYear()));
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
useEffect(() => {
if (!rainChkgdn.isInit) {
rainChkInit(new Date().getFullYear().toString(), "0");
isRainSttn(false)
isRainSttn(false);
setIsModal({ data: {}, open: false });
setIsRegExcel(false);
}
@@ -86,12 +91,14 @@ export default function Page() {
}, [rainChkgdn.isInit, rainChkInit]);
useEffect(() => {
if (rswtChkgdn.excelList[0]?.data.length > 1)
if (rswtChkgdn.excelList[0]&&rswtChkgdn.excelList[0]?.data.length > 1) {
excelArrayDownload(
"중수도시설 지도점검",
"sample_rs_chk.xlsx",
rswtChkgdn.excelList
);
}
}, [rswtChkgdn.excelList]);
useEffect(() => {
@@ -99,7 +106,8 @@ export default function Page() {
rainChkgdn.excelList,
"빗물이용시설 지도점검",
"sample_rainy.xlsx",
"A1:AN1"
"A1:AN1",
2
);
}, [rainChkgdn.excelList]);
@@ -125,8 +133,8 @@ export default function Page() {
);
useEffect(() => {
rainChkgdn.isSttn = false
rswtChkgdn.isSttn = false
rainChkgdn.isSttn = false;
rswtChkgdn.isSttn = false;
if (!rainChkgdn.isSttn && !rswtChkgdn.isSttn) {
rainChkHeadChange({ rainChkgdn }, true);
rswtChkHeadChange({ rswtChkgdn }, true);
@@ -138,20 +146,17 @@ export default function Page() {
if (selFcltDiv === "RNB") {
rainChkDelete(data);
} else {
rswtChkDelete(data)
rswtChkDelete(data);
}
}
};
const chkUpdateTable = (selFcltDiv: string) => {
if (selFcltDiv === "RNB") {
rainChkDetilUpdate(updateRainDetail)
rainChkDetilUpdate(updateRainDetail);
} else {
rswtChkDetilsUpdate(updateRswtDetail)
rswtChkDetilsUpdate(updateRswtDetail);
}
}
};
return (
<ContentsDiv>
@@ -161,7 +166,9 @@ export default function Page() {
<SearchDiv>
<SearchFormLeft>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-48 mt-2 text-xl text-gray-600">{'지도점검년도'}</Label>
<Label className="w-48 mt-2 text-xl text-gray-600">
{"지도점검년도"}
</Label>
<SelectBox
className="w-full h-full text-2xl"
label=""
@@ -174,7 +181,9 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">{'시설구분'}</Label>
<Label className="w-28 mt-2 text-xl text-gray-600">
{"시설구분"}
</Label>
<SelectBox
className={"w-full h-full text-2xl"}
label={""}
@@ -189,8 +198,7 @@ export default function Page() {
/>
</div>
</SearchFormLeft>
<SearchFormRight
className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<SearchFormRight className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<div className="space-y">
<div className="flex flex-row space-x-2">
<Button
@@ -212,7 +220,7 @@ export default function Page() {
<Button
size={"sm"}
onClick={() => {
chkUpdateTable(selFcltDiv)
chkUpdateTable(selFcltDiv);
}}
>
저장
@@ -51,6 +51,7 @@ export default function prfmncPrfmncReg() {
}>({ isModal: false, data: {} as FcPrfType });
const [inputData, setInputData] = useState<any[]>();
const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState<string>();
const [pageNation , setPageNation] = useState<number>(1);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
@@ -73,9 +74,12 @@ export default function prfmncPrfmncReg() {
pbnstRuseFcltPk
) as unknown as PrfType
);
prfmncHasuInit("1", "11");
prfmncHasuInit(String(pageNation), "41");
}
}, [inputData, searchYear, pbnstRuseFcltPk,prfmncHasuInit]);
}, [inputData, searchYear, pbnstRuseFcltPk,prfmncHasuInit,pageNation]);
const cellClick = useCallback(
(index: number | undefined, headId: string) => {
@@ -146,7 +150,7 @@ export default function prfmncPrfmncReg() {
useEffect(() => {
if (!prfmnc.isInit) {
prfmncHasuInit("1", "11");
prfmncHasuInit('1', "41");
}
}, [prfmnc.isInit, prfmncHasuInit]);
useEffect(() => {
@@ -229,13 +233,13 @@ export default function prfmncPrfmncReg() {
<UiTable
tableData={bdstTable || []}
headlist={pbnstPrfmncHeadList}
pageSize={100}
total={10}
pageSize={10}
total={10000}
headName={"하수재이용시설 목록"}
cellClick={(index: number | undefined, headId: string) => {
cellClick(index, headId);
}}
onPageChange={(page: number) => {}}
onPageChange={setPageNation}
children={undefined}
/>
</ScrollArea>
@@ -78,14 +78,13 @@ const irvwHistInit = async (
pageCnt: number,
startYear: string,
endYear: string,
sggCd?: string
) => {
let url = `/reuseFc/request/infoList/matched/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
console.log("sggCd ", sggCd);
if (sggCd) {
url += `/${sggCd}`;
}
// console.log("sggCd ", sggCd);
// if (sggCd) {
// url += `/${sggCd}`;
// }
const rvwHistRes = await getFetch(fetchType.WR, url);
@@ -108,7 +107,7 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (
pageCnt,
startYear,
endYear,
sggCd
// sggCd
);
return set((state: ruseHstryState) => ({
@@ -135,7 +134,6 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (
10,
new Date().getFullYear().toString(),
new Date().getFullYear().toString(),
"0"
);
return set((state: ruseHstryState) => ({
...state,
@@ -225,8 +223,6 @@ export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (
10,
new Date().getFullYear().toString(),
new Date().getFullYear().toString(),
"0",
'0'
);
}
} catch (e) {
@@ -1,10 +1,9 @@
import {
TEST_UUID,
type TableUpperProps,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import type {
SelectDataType,
sheetParameter,
SheetParameter,
} from "@common/business_components";
import {
deleteFectch,
@@ -25,6 +24,7 @@ import {
import { z } from "zod";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import { type chHeadType } from "../rainChkgdn/headList";
import type { TableUpperProps } from "@/app/store/common/type/header";
const rswtChkHeadList = rswtChkHeadListExport;
const rswtDetailHeadList = rswtDetailHeadListExport;
@@ -37,7 +37,7 @@ export type rswtChkgdnState = {
rswtDetailHeadList: TableUpperProps[];
rswtHeadNm: chHeadType[];
excelList: [typeof sheetParameter];
excelList: SheetParameter[];
rswtChkRes: rswtChkZodType[];
rswtChkPolGuide: rswtChkZodType[];
isInit: boolean;
@@ -70,7 +70,7 @@ export const rswtChkgdnStateExport: rswtChkgdnState = {
excelList: [{
data: [[]], headerNum: 0, headerRange: "A1:V3",
sheetName: "",
startCol: 0
startCol: '1'
}],
rswtChkRes: [],
rswtChkPolGuide: [],
@@ -176,9 +176,6 @@ export const rswtChkgdnActionsExport: (set: any) => rswtChkgdnActions = (
try {
const chData = await makeMdfrChk(rswtChk);
console.log("chData ", chData);
console.log("rswtChk ", rswtChk);
const res = await putFectch("/reuseChk/reuseWater", chData);
if (res.ok) {
@@ -4,6 +4,7 @@ import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type";
import type { FcPrfType, PrfType } from "./type";
import type { TableUpperProps } from "../../common/type/header";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import toast from "react-hot-toast";
const pbnstPrfmncHeadList = pbnstPrfmncHeadListExport;
const monthHeadList = monthHeadListExport;
@@ -32,7 +33,7 @@ export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions;
type pbnstPrfmncActions = {
prfmncHasuInit: (page: string, sggOrCity: string) => void;
prfmnRegData: (data:PrfType) =>void
prfmnRegData: (data: PrfType) => void;
};
const checkWrRegList = async () => {
@@ -46,21 +47,28 @@ const hasuListFetch = async (page: string, sggOrCity: string) => {
checkWrRegListRes?.fcltCds,
fetchType.COMMON
);
const data = checkWrRegListRes.fcPrfList.map((item: FcPrfType) => {
const findData = rainRes.data.find(
(fclt: pubHasuType) =>
fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11)
const findData = rainRes.data.map((item: pubHasuType) => {
const data = checkWrRegListRes?.fcPrfList.find(
(fclt: FcPrfType) =>
fclt.pbnstRuseFcltPk.substring(0, 11) === item?.bscFctCd
);
return {
sido: findData?.sido,
gugun: findData?.gugun,
bscFctNm: findData?.bscFctNm,
ruseUtztnFcltNm: item.ruseUtztnFcltNm,
pbnstRuseFcltPk: item.pbnstRuseFcltPk,
prfList : item.prfList
};
if(data !==undefined){
return( {
sido: item.sido,
gugun: item.gugun,
bscFctNm: item.bscFctNm,
bscFctCd: item.bscFctCd,
ruseUtztnFcltNm: data.ruseUtztnFcltNm,
pbnstRuseFcltPk: data.pbnstRuseFcltPk,
prfList: data.prfList,
});
}
});
return data;
return findData;
};
export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
set: any
@@ -82,31 +90,21 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
console.log(errorHasu);
}
},
prfmnRegData: async (data:PrfType,) => {
try{
prfmnRegData: async (data: PrfType) => {
try {
const ressponse = await postFectch(
"/reuseFc/pubFcPrf",
data,
fetchType.WR
);
console.log('ressponse ', ressponse)
if(ressponse.status === 200){
ToastFormUi({
body: "하수재이용 시설 실적 등록이 완료되었습니다. ",
title: "하수재이용 시설 실적 등록",
});
}
}catch(e){
console.log(e)
ToastFormUi({
body: "하수재이용 시설 실적 등록이 실패하였습니다. ",
title: "하수재이용 시설 실적 등록",
});
if (ressponse.status === 200) {
toast.success("하수재이용 시설 실적 등록이 완료되었습니다.");
}
} catch (e) {
console.log(e);
toast.error("하수재이용 시설 실적 등록이 실패하였습니다.");
}
},
};
@@ -24,6 +24,7 @@ import {
fcOrgwtsHeadListExport,
} from "./headList";
import type { TableUpperProps } from "@/app/store/common/type/header";
import toast from "react-hot-toast";
const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }];
const pubFacHeadList = pubFacHeadListExport;
@@ -62,9 +63,9 @@ type pubFacActions = {
appendRuseFclt(array: customPbnst[]): void;
fileDelete: (atflCd: string) => void;
fileDownLoad: (atflCd: string) => void;
pbnstMngData: (data: customPbnst[]) => void;
pbnstBizData(data: fcBizType): void;
getBizCycle: (pbnstObj: customPbnst) => void;
//pbnstMngData: (data: customPbnst[]) => void;
//pbnstBizData(data: fcBizType): void;
// getBizCycle: (pbnstObj: customPbnst) => void;
getpbnstInsertIndex: (data: pbnstInsertIndex) => void;
pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void;
pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void;
@@ -100,14 +101,20 @@ const checkWrRegList = async () => {
const hasuListFetch = async (page: string, sggOrCity: string, searchTxt?:string) => {
const checkWrRegListRes = await checkWrRegList();
let url = `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`;
console.log(' checkWrRegListRes ', checkWrRegListRes)
let url = `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity? sggOrCity : "11"}/0/1/SW`;
const data = checkWrRegListRes.filter((item:string) => item !== "")
console.log(' checkWrRegListRes ' )
if(searchTxt){
url= url +`/${searchTxt}`
}
const rainRes = await postFectch(
url,
checkWrRegListRes,
data,
fetchType.COMMON
);
@@ -200,7 +207,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
pbnstRegClick: async (pubHasuRes: pubHasuType) => {
try {
const pbnstRes = await initFetch(pubHasuRes.bscFctCd);
console.log('pbnstRes ' , pbnstRes)
return set((state: pubFacState) => ({
...state,
pbnst: {
@@ -234,14 +240,19 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
const response = await postFectch(
`/reuseFc/pubFc`,
JSON.stringify( pbnstRes)
pbnstRes
);
if( response.status === 200) {
toast.success(`${pbnstRes.ruseUtztnFcltNm} 하수재이용 시설이 등록되었습니다.`);
}
const pbnstHasuRes = await hasuListFetch('1', '0');
return set((state: pubFacState) => ({
...state,
pbnst: {
...state.pbnst,
pbnstRes: response.data,
pbnstRes: pbnstHasuRes,
isInit: false,
},
}));
@@ -334,41 +345,41 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => {
}
},
pbnstMngData: (data: customPbnst[]) => {
if (data.length > 0) {
}
return set((state: pubFacState) => {
state.pbnst.pbnstMngRegData = data;
state.pbnst.pbnstBizCycle =
data.length <= 0
? [{ text: "없음", val: "1" }]
: state.pbnst.pbnstBizCycle;
return state;
});
},
// pbnstMngData: (data: customPbnst[]) => {
// if (data.length > 0) {
// }
// return set((state: pubFacState) => {
// state.pbnst.pbnstMngRegData = data;
// state.pbnst.pbnstBizCycle =
// data.length <= 0
// ? [{ text: "없음", val: "1" }]
// : state.pbnst.pbnstBizCycle;
// return state;
// });
// },
pbnstBizData: (data: fcBizType) => {
return set((state: pubFacState) => {
if (state.pbnst.pbnstMngRegData) {
const regData = state.pbnst.pbnstMngRegData.find(
(item) => data.pbnstRuseFcltFk === item.pbnstRuseFcltPk
);
if (regData) {
const bizIdx = regData.fcBizs.findIndex(
(item) => item.pbnstRuseFcltBizPk == data.pbnstRuseFcltBizPk
);
// pbnstBizData: (data: fcBizType) => {
// return set((state: pubFacState) => {
// if (state.pbnst.pbnstMngRegData) {
// const regData = state.pbnst.pbnstMngRegData.find(
// (item) => data.pbnstRuseFcltFk === item.pbnstRuseFcltPk
// );
// if (regData) {
// const bizIdx = regData.fcBizs.findIndex(
// (item) => item.pbnstRuseFcltBizPk == data.pbnstRuseFcltBizPk
// );
if (bizIdx >= 0) {
regData.fcBizs[bizIdx] = data;
const pbnstData = state.pbnst.pbnstMngRegData
state.pbnst.pbnstMngRegData= [...pbnstData]
// if (bizIdx >= 0) {
// regData.fcBizs[bizIdx] = data;
// const pbnstData = state.pbnst.pbnstMngRegData
// state.pbnst.pbnstMngRegData= [...pbnstData]
}
}
}
return state;
});
},
// }
// }
// }
// return state;
// });
// },
getpbnstInsertIndex: async (data: pbnstInsertIndex) => {
return set((state: pubFacState) => {
state.pbnst.pbnsUpdateIndex = data;
@@ -57,7 +57,7 @@ export type PbnstDemandComType = {
dmdAplyPswd: string | '';
splyCpct: number | 0;
splyFmYn:string|'Y'
dmdInfoFk:string|''
// dmdInfoFk:string|''
}
const pubHasuZod = z.object({
@@ -129,7 +129,7 @@ const fcOrgwtSchema = z.object({
});
const dmdColist = z.object({
dmdInfoFk: z.string().default(''),
dmdInfoPk: z.string().default(''),
dmdCoNm: z.string().default(''),
daddr: z.string(),
useUsgCd: z.string().nullish(),
@@ -3,7 +3,76 @@ import { getFetch, postFectch, putFectch } from "@/components/lib/api";
import { z } from "zod";
import { makeMdfr, makeRstr } from "../bdstReg";
const validationMessages = {
required: (field: string) => `${field}을(를) 입력해주세요.`,
requiredSelect: (field: string) => `${field}을(를) 선택해주세요.`,
yearFormat: '4자리 연도만 입력하세요',
};
export const TEST_UUID= '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e'
const rainyObjSchema = z.object({
bdstReuseFcltFk: z.number().nullish(),
pntfColKnd: z.string().default(""),
pntfColArea: z.number().default(0),
dtfcltCpct: z.number().default(0),
filtrTrtmfctYn: z.string().default("Y").nullish(),
filtrTrtmfctCpct: z.number().nullish().default(0),
filtrTrtmfctPrs: z.string().default(""),
annRnwtQty: z.number().default(0),
oilqMeasMthd: z.string().default("").nullish(),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
}).refine((data) => data.pntfColKnd.length > 0, {
message: validationMessages.requiredSelect("종류"),
path: ["pntfColKnd"],
}).refine((data) => data.pntfColArea > 0, {
message: validationMessages.required("면적(m³)"),
path: ["pntfColArea"],
});
const reuseBuildingSchema = z.object({
bdstRuseFcltPk: z.number().nullish(),
bdstInfoFk:z.number().nullish(),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish(),
operMngCd: z.string().optional().default(""),
anlOperCst: z.number().default(0),
instlCstSprtYn: z.string().default("Y"),
instlCstSprtAmt: z.number().nullish(),
grntchBdstCertYn: z.string().default("Y"),
grntchBdstCertYr: z.string().default("")
.refine((year)=> year.length===0 || /^\d{4}$/.test(year),{
message: validationMessages.yearFormat
}),
grntchBdstCertNo: z.string().default(""),
grntchBdstCertGrd: z.string().default(""),
crgRdctYn: z.string().default("N").nullish(), /// 안쓰는 값
crgRdctBss: z.string().default("").nullish(), /// 안쓰는 값
crgRdctAmt: z.number().default(0), // 안쓰는 값
ruseFcltFlg: z.string().default(""),
bdstUsgCd: z.number().default(0),
lawTrgtYn: z.string().default("Y"),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
rainyObj: rainyObjSchema.default({})
}).refine((data) => data.bdstUsgCd > 0, {
message: validationMessages.requiredSelect("건축물용도"),
path: ["bdstUsgCd"],
});
const chgBuildingSchema = z.object({
bdstInfoFk: z.number().nullish(),
archChgPrmsnDt: z.coerce.date({required_error: validationMessages.required("허가일")}),
archChgArea: z.string().default("-"),
bdstChgNm: z.string().default(""),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
}).refine(data => data.bdstChgNm.length > 0, {
message: validationMessages.requiredSelect("구분"),
path: ["bdstChgNm"]
});
export const rainZod = z.object({
bdstInfoPk: z.number().optional(),
ctpvCd: z.number().default(0),
@@ -16,62 +85,9 @@ export const rainZod = z.object({
archChgArea: z.number().default(0),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
reuseBuilding: z.array(
z.object({
bdstRuseFcltPk: z.number().nullish(),
bdstInfoFk:z.number().nullish(),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish(),
operMngCd: z.string().optional().default(""),
anlOperCst: z.number().default(0),
instlCstSprtYn: z.string().default(""),
instlCstSprtAmt: z.number().nullish(),
grntchBdstCertYn: z.enum(["Y", "N"]).nullish(),
grntchBdstCertYr: z.string().default("")
.refine((year)=> year.length===0 || /^\d{4}$/.test(year),{
message:'4자리 연도만 입력하세요'
}),
grntchBdstCertNo: z.string().default(""),
grntchBdstCertGrd: z.string().default(""),
crgRdctYn: z.string().default("N").nullish(), /// 안쓰는 값
crgRdctBss: z.string().default("").nullish(), /// 안쓰는 값
crgRdctAmt: z.number().default(0), // 안쓰는 값
ruseFcltFlg: z.string().default(""),
bdstUsgCd: z.number().default(0),
lawTrgtYn: z.enum(["Y", "N"]),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
rainyObj: z.object({
bdstReuseFcltFk: z.number().nullish(),
pntfColKnd: z.string().default(""),
pntfColArea: z.number().default(0),
dtfcltCpct: z.number().default(0),
filtrTrtmfctYn: z.enum(["Y", "N"]).nullish(),
filtrTrtmfctCpct: z.number().nullish().default(0),
filtrTrtmfctPrs: z.string().default(""),
annRnwtQty: z.number().default(0),
oilqMeasMthd: z.string().default("").nullish(),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
}).default({})
})
).default([]),
chgBuilding: z.array(
z.object({
bdstInfoFk: z.number().nullish(),
archChgPrmsnDt: z.coerce.date(),
archChgArea: z.string().default("-"),
bdstChgNm: z.string().default(""),
rgtr:z.string().nullish(),
mdfr:z.string().nullish(),
})
).default([])
});
reuseBuilding: z.array(reuseBuildingSchema).default([]),
chgBuilding: z.array(chgBuildingSchema).default([])
})
export type chgBuilding={
bdstInfoFk?: number|null,
@@ -254,6 +270,3 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
}
}}
@@ -9,6 +9,7 @@ import { excelPbnstSttnParsing } from "./excel";
import type { FcPrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
import type { ReturnType } from "@common/business_components/ui";
import type { WaterReuseFacility } from "./type";
import moment from "moment";
const pbnstSttHeadList = pbnSttHeadListExport;
const pbnstSttNodeList = pbnstSttNodeListExport;
@@ -166,8 +167,8 @@ const hasuListFetch = async (
outUsage: usage.outUsage,
operMthd: item.operList[0]?.operMthd,
rprtvBzenty: item.operList[0]?.rprtvBzenty,
bgngDt: item.operList[0]?.bgngDt.toLocaleDateString ?? "",
endDt: item.operList[0]?.endDt.toLocaleDateString?? "",
bgngDt: moment(item.operList[0]?.bgngDt).format("YYYY-MM-DD") ?? "",
endDt: moment(item.operList[0]?.endDt).format("YYYY-MM-DD") ?? "",
searchNm: findData.bscFctNm,
searchPk: findData.bscFctCd,
prfList:item?.prfList??[]
+8 -5
View File
@@ -4,6 +4,7 @@ import {
type SelectDataType,
type ReturnType,
filePickedBlobArray,
type SheetParameter,
} from "@common/business_components/ui";
import type { RefObject } from "react";
@@ -81,7 +82,7 @@ export const excelDownload = (
export const excelArrayDownload = (
fileNm: string,
sampleFile: string,
sheetArray: []
sheetArray:SheetParameter []
) => {
if (!sheetArray) return;
fetch(`/${sampleFile}`, {}).then(async (response) => {
@@ -110,7 +111,12 @@ export const formatCommaNumber = (
value: number | string | undefined | null
): string => {
if (value === undefined || value === null || value === "") return "";
return Number(value).toLocaleString();
const num = Number(value);
// 숫자로 변환할 수 없는 값이 들어올 경우 빈 문자열을 반환하여 예상치 못한 "NaN" 출력을 방지합니다.
if (isNaN(num)) {
return "";
}
return num.toLocaleString();
};
export const getCityOrSgg = (ref: RefObject<ReturnType>) => {
@@ -153,6 +159,3 @@ export const getdmdMatFlag = (flag: string|undefined) => {
}
return flagMat;
};
File diff suppressed because it is too large Load Diff
@@ -37,7 +37,6 @@ export type FilesType = {
export function PbnstMngForm({
form,
formType,
firstFcltData,
indexMng,
setIndexMng,
}: {
@@ -51,12 +50,8 @@ export function PbnstMngForm({
code,
pbnst,
pbnstInsert,
pbnstMngData,
fileDelete,
fileDownLoad,
getBizCycle,
getpbnstInsertIndex,
appendRuseFclt,
} = useWrStore((state) => state);
const { pbnstRes } = pbnst;
@@ -67,8 +62,6 @@ export function PbnstMngForm({
const [mngMtdCode, setMngMtdCode] =
useState<{ name: string; val: SelectDataType[] }[]>();
const [progress, setProgress] = useState(0);
const {
fields: fcOpersField,
append,
@@ -221,12 +214,19 @@ export function PbnstMngForm({
}, [pbnst.pbnstMngRegData]);
useEffect(() => {
if (pbnst.pbnstRes && pbnst.pbnstRes?.length <= 0) return;
const fcltNmList = pbnst.pbnstRes?.map((item, index) => ({
text: item.ruseUtztnFcltNm,
val: String(index),
}));
if (fcltNmList) setFcltNm(fcltNmList);
if (pbnst.pbnstRes && pbnst.pbnstRes?.length >= 0) {
const fcltNmList = pbnst.pbnstRes?.map((item, index) => ({
text: item.ruseUtztnFcltNm,
val: String(index),
}));
console.log(' fcltNmList ', fcltNmList)
if (fcltNmList) setFcltNm(fcltNmList);
}else{
setFcltNm(null);
}
}, [pbnst.pbnstRes]);
// 2. Define a submit handler.
@@ -253,6 +253,16 @@ export function PbnstMngForm({
}
}, [code]);
useEffect(() =>{
// console.log(' fcltNm ', watchedItem?.ruseUtztnFcltNm)
},[watchedItem])
useEffect(() => {
console.log(" form indexMng ", indexMng);
}, [indexMng]);
return (
<div className=" !mx-[1.6rem] !p-0r">
<div>
@@ -266,33 +276,29 @@ export function PbnstMngForm({
</Label>
{formType === "update" ? (
<FormField
key={`items.${indexMng}.ruseUtztnFcltNm-key`}
control={form.control}
name={`items.${indexMng}.ruseUtztnFcltNm`}
render={({ field }) => (
<FormUi label="">
<SelectBox
label=""
selectArray={fcltNm ?? []}
onSelectValue={(val) => {
setIndexMng(Number(val));
field.onChange(val);
}}
value={field.value ?? ""}
className={""}
selectClass={undefined}
/>
</FormUi>
)}
/>
<FormUi label="">
<SelectBox
label=""
key={`fclt-selector-${indexMng}`}
selectArray={fcltNm ?? []}
onSelectValue={(val) => {
setIndexMng(Number(val));
}}
value={String(indexMng)}
className={""}
selectClass={undefined}
/>
</FormUi>
) : (
<FormField
control={form.control}
name={`items.${indexMng}.ruseUtztnFcltNm`}
key={`items-ruseUtztnFcltNm-${indexMng}`}
render={({ field }) => (
<FormUi label="">
<Input
className="!text-2xl"
placeholder=""
type="text"
@@ -60,8 +60,10 @@ export default function RainRegForm({
typeof item?.grntchBdstCertYr === "string"
? item?.grntchBdstCertYr
: "", // null → ""
// Ensure enum fields are null if empty string to trigger Zod default
rainyObj: {
...item?.rainyObj,
filtrTrtmfctYn: item?.rainyObj?.filtrTrtmfctYn === "" ? null : item?.rainyObj?.filtrTrtmfctYn,
},
})),
};
@@ -84,7 +86,6 @@ export default function RainRegForm({
useEffect(() => {
const subscription = form.watch((value) => {
});
console.log("subscription:", subscription)
return () => subscription.unsubscribe();
}, [form]);
@@ -147,6 +148,7 @@ export default function RainRegForm({
? new Date(field.value)
: new Date(), // Provide a default Date value
onChange: (date) => field.onChange(date),
}}
selectClass={"w-full"}
readOnly={readonly}
@@ -243,7 +245,7 @@ export default function RainRegForm({
label={""}
selectArray={code.yn}
onSelectValue={readonly ? () => { } : field.onChange}
value={field.value ?? code.yn[0]?.val}
value={field.value || code.yn[0]?.val}
readOnly={readonly}
/>
</FormUi>
@@ -278,12 +280,10 @@ export default function RainRegForm({
<FormUi label="처리공정">
<Input
className={selectClass}
placeholder="1,000,000"
type=""
placeholder=""
type="text"
value={field.value ?? ""}
onChange={(e) => {
if (!readonly) handleCommaNumberChange(e, field.onChange);
}}
onChange={field.onChange}
readOnly={filtrTrtmfctYn !== "Y"}
/>
</FormUi>
@@ -45,7 +45,7 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) {
const cityValue = String(val); // Ensure val is treated as a string
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
getSgg(data[0]?.val || "");
setObjSearch({ city: cityValue, sgg: '' });
};
@@ -111,6 +111,7 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) {
selectClass={selectClass}
selectArray={selectSgg || []}
onSelectValue={getSgg}
value={objSearch.sgg || ""}
>
{" "}
</SelectBox>
@@ -26,7 +26,7 @@ export function PbnstRegModal({
data: pubHasuType;
form: UseFormReturn<{ items: PbnstRegArrrayType }>;
}) {
const { pbnst, pbnstInsert, pbnstMngData } = useWrStore((state) => {
const { pbnst, pbnstInsert } = useWrStore((state) => {
return state;
});
const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>(
@@ -57,48 +57,18 @@ export function PbnstRegModal({
useEffect(() => {
if (data) {
const firstForm = form.getValues("items");
console.log('mngIndex ', firstForm.length)
setIndexMng(firstForm.length - 1)
// console.log(' firstForm ', firstForm)
// let regData;
// if (pbnstRes && pbnstRes?.length > 0) {
// regData = {
// swtrmtFcltFk: String(data.bscFctCd),
// pbnstRuseFcltPk: String(data.bscFctCd) + String(pbnstRes.length + 1),
// fcBizs: [
// {
// pbnstRuseFcltFk:
// String(data.bscFctCd) + String(pbnstRes.length + 1),
// cycl: 1,
// } as unknown as fcBizType,
// ],
// };
// //regData= pbnstRegZod.parse(regData)
// //setPbnstBdstForm(regData as unknown as customPbnst);
// // pbnstMngData([regData] as unknown as customPbnst[])
// } else {
// regData = {
// swtrmtFcltFk: String(data.bscFctCd),
// pbnstRuseFcltPk: String(data.bscFctCd + "1"),
// fcBizs: [
// {
// pbnstRuseFcltFk: String(data.bscFctCd + "1"),
// cycl: 1,
// } as unknown as fcBizType,
// ],
// };
// //regData= pbnstRegZod.parse(regData)
// // setPbnstBdstForm(regData as unknown as customPbnst);
// // pbnstMngData([regData] as unknown as customPbnst[])
// }
// regData = pbnstRegZod.parse(regData);
// setPbnstBdstForm(regData as unknown as customPbnst);
}
setIndexMng(firstForm.length - 1) }
}, [data, form]);
useEffect(() => {
console.log(' form.getValues() ' ,form.getValues())
}, [form.getValues()]);
return (
<>
<h1 className="text-2xl font-medium text-label pl-8">
@@ -21,8 +21,7 @@ import {
TableHeader,
TableRow,
} from "@common/components/ui";
import { read } from "fs";
import React, { useEffect, useState } from "react";
import React from "react";
type RuseMngTableProps = {
tableData: any[];
@@ -39,8 +38,6 @@ type RuseMngTableProps = {
const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>(
({ tableData, headList, upHeadList, code, onTableSet, indexMng, form,formNm,indexBiz }, ref) => {
console.log('tableData ', tableData)
return (
<>
<Table key={`table-${indexMng}-${indexBiz}`} variant="secondary">
@@ -119,6 +116,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>(
field.onChange(val);
}
}}
readOnly ={head.readonly ? true : false}
// Disabled prop removed as SelectBox does not support it
></SelectBox>
) : head.type === "date" ? (
@@ -133,6 +131,7 @@ const RuseMngTableForm = React.forwardRef<any, RuseMngTableProps>(
},
}}
selectClass={"w-full"}
readOnly ={head.readonly ? true : false}
/>
) : head.type === "checkbox" ? (
<Checkbox
Binary file not shown.
@@ -53,7 +53,8 @@ export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[]
if (item.data && item.data.length > 0) {
const numCols = item.data[0]?.length || 0;
const numRows = item.data.length;
const dataRange = workbook.activeSheet(index)?.sheet(index)?.range(`A1:${String.fromCharCode(65 + numCols - 1)}${numRows}`);
const lastColLetter = getExcelColumnLetter(numCols);
const dataRange = workbook.activeSheet(index)?.sheet(index)?.range(`A1:${lastColLetter}${numRows}`);
dataRange?.style((styleQ) => {
styleQ.verticalAlignment("center");
});
@@ -62,4 +63,60 @@ export const excelArrayStyle = async (data: ArrayBuffer, range: SheetParameter[]
}
makeExcelFile(workbook, fileNm)
}
}
export const excelStyleWithKoreanHeaders = async (
data: ArrayBuffer,
range: string = "A1:V3",
fileNm: string,
headerMapping: { [key: string]: string },
sampleData: any
) => {
const workbook = await XlsxPopulate.Workbook.fromData(data);
const sheet = workbook.activeSheet();
if (!sheet) {
throw new Error('워크시트를 찾을 수 없습니다.');
}
// 1. 영문 헤더를 한글로 교체
const englishHeaders = Object.keys(sampleData);
englishHeaders.forEach((englishHeader, index) => {
const koreanHeader = headerMapping[englishHeader] || englishHeader;
const cellAddress = String.fromCharCode(65 + index) + '1'; // A1, B1, C1, ...
sheet.cell(cellAddress).value(koreanHeader);
});
// 2. 헤더 스타일 적용
const headerCells = sheet.range(range);
headerCells?.style((styleQ) => {
makeCellStyle(styleQ);
});
// 3. 모든 데이터 셀에 세로 가운데 정렬 적용
const numCols = englishHeaders.length;
const numRows = sheet.usedRange()?.endCell()?.rowNumber() || 1;
if (numRows > 1) {
const dataRange = sheet.range(`A1:${String.fromCharCode(65 + numCols - 1)}${numRows}`);
dataRange?.style((styleQ) => {
styleQ.verticalAlignment("center");
styleQ.borderEach({ style: "thin", color: { rgb: "CCCCCC" } });
});
}
// 4. 파일 다운로드
await makeExcelFile(workbook, fileNm);
};
const getExcelColumnLetter = (colIndex: number): string => {
let letter = '';
while (colIndex > 0) {
const mod = (colIndex - 1) % 26;
letter = String.fromCharCode(65 + mod) + letter;
colIndex = Math.floor((colIndex - 1) / 26);
}
return letter;
};
@@ -1,5 +1,5 @@
import * as XLSX from 'xlsx';
import { excelArrayStyle, excelStyle } from './excelStyle';
import { excelArrayStyle, excelStyle, excelStyleWithKoreanHeaders } from './excelStyle';
type ExcelDownloadProps = {
data: JSON | JSON[];
@@ -164,4 +164,38 @@ export const filePickedBlobArray = (oFile: ArrayBuffer, fileNm: string, sheetArr
});
await excelArrayStyle(XLSX.write(wb, { bookType: "xlsx", type: "buffer" }), sheetArray, fileNm)
});
}
}
type ExcelDownloadWithHeaderProps = {
data: JSON | JSON[];
fileName: string;
sheetNameArray: string[];
headerRange?: string;
headerMapping: { [key: string]: string };
}
export const downloadExcelWithKoreanHeaders = async ({
data,
fileName = new Date().getTime().toString() + '.xlsx',
sheetNameArray = ["Sheet1"],
headerRange = 'A1:V3',
headerMapping
}: ExcelDownloadWithHeaderProps) => {
const dataArray = Array.isArray(data) ? data : [data];
if (dataArray.length === 0) {
throw new Error('데이터가 없습니다.');
}
// 1. 원본 데이터로 워크시트 생성
const worksheet = XLSX.utils.json_to_sheet(dataArray);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, sheetNameArray[0]);
// 2. 워크북을 ArrayBuffer로 변환
const buffer = XLSX.write(workbook, { bookType: "xlsx", type: "buffer" });
// 3. 헤더만 한글로 교체하는 커스텀 스타일 함수 호출
await excelStyleWithKoreanHeaders(buffer, headerRange, fileName, headerMapping, dataArray[0]);
};
@@ -308,7 +308,6 @@ export const FileUploaderItem = forwardRef<
{children}
</div>
<button
type="button"
className={cn(
"absolute",
"!w-1/5 z-50",
@@ -223,7 +223,6 @@ function Gis({ isOpen , gisMaps, isSearchModalOpen, treeData = [], isSearch = fa
{isSearch && (
<div className="absolute right-8 top-[305px] z-20">
<button
type="button"
onClick={() => setIsSearchModalOpen(true)}
className="overflow-hidden w-[40px] h-[40px] bg-white
border border-[#9aa7b8]
@@ -60,7 +60,6 @@ export default function GisContent({ edit = false, onFeatureSelect, isSearch, se
{isSearch && (
<div className="absolute right-8 top-[254px] z-20">
<button
type="button"
onClick={() => setIsSearchModalOpen(true)}
className="overflow-hidden w-[40px] h-[40px] bg-white
border border-[#9aa7b8]
@@ -20,7 +20,6 @@
// <TabsTrigger value="layers" className="flex-1 h-10">레이어</TabsTrigger>
// {/* {isSearch && (
// <button
// type="button"
// onClick={() => setIsSearchModalOpen(true)}
// className="h-10 w-10 flex items-center justify-center px-0"
// >