하수재이용 실적 등록 엑셀 등록 기능 추가

This commit is contained in:
leedj312
2025-06-03 21:06:52 +09:00
parent c28dd728c5
commit c49b2a8e08
5 changed files with 347 additions and 112 deletions
@@ -3,125 +3,141 @@
import { useWrStore } from "@/app/store";
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { yearOptions } from "@/components/lib/func/commom";
import { ContentsDiv, Title, SearchDiv, SearchFormLeft, SelectBox, SearchInput, SearchFormRight, ScrollArea, UiTable } from "@common/business_components/ui";
import PbnPrfExcelModal from "@/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal";
import {
ContentsDiv,
Title,
SearchDiv,
SearchFormLeft,
SelectBox,
SearchInput,
SearchFormRight,
ScrollArea,
UiTable,
UiModal,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Label } from "@common/components/ui";
import { useState, useEffect } from "react";
import { set } from "react-hook-form";
import { Toaster } from "react-hot-toast";
export default function prfmncPrfmncReg() {
const { code, prfmnc, prfmncHasuInit, searchFclts, } = useWrStore((state) => state);
const { pbnstPrfmncHeadList, monthHeadList,prfmncRes } = prfmnc;
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
const [searchTxt, setSearchTxt] = useState<string>();
const { code, prfmnc, prfmncHasuInit, searchFclts } = useWrStore(
(state) => state
);
const { pbnstPrfmncHeadList, monthHeadList, prfmncRes } = prfmnc;
const [bdstTable, setbdstTable] = useState<pubHasuType[]>();
const [searchTxt, setSearchTxt] = useState<string>();
const [isExcelOpen, setIsExcelOPen] = useState<boolean>(false);
const [searchYear, setSearchYear] = useState<string>(String(new Date().getFullYear()));
useEffect(() => {
if (!prfmnc.isInit) {
prfmncHasuInit("1", "11");
}
}, [prfmnc.isInit, prfmncHasuInit]);
useEffect(() => {
console.log("prfmnc.prfmncRes", prfmncRes)
},[prfmncRes]);
const [searchYear, setSearchYear] = useState<string>(
String(new Date().getFullYear())
);
useEffect(() => {
if (!prfmnc.isInit) {
prfmncHasuInit("1", "11");
}
}, [prfmnc.isInit, prfmncHasuInit]);
useEffect(() => {
console.log("prfmnc.prfmncRes", prfmncRes);
}, [prfmncRes]);
return (
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<Title title={"하수재이용 시설 등록"} />
<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>
<SelectBox
className="w-full h-full text-2xl"
label=""
selectClass={""}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">{'시설명'}</Label>
<SearchInput
className={"w-full text-2xl"}
label=""
textValue={searchTxt || ""}
setText={(e) => {
setSearchTxt(e);
}}
/>
</div>
</SearchFormLeft>
<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
size={"sm"}
onClick={(e) => { }}
>
조회
</Button>
<Button
size={"sm"}
onClick={() => { }}
>
저장
</Button>
<Button
size={"sm"}
onClick={() => { }}
>
파일등록
</Button>
<Button color="green" size={"sm"} onClick={() => { }}>
양식받기
</Button>
</div>
</div>
</SearchFormRight>
</SearchDiv>
</div>
return (
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<Title title={"하수재이용 시설 등록"} />
<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>
<SelectBox
className="w-full h-full text-2xl"
label=""
selectClass={""}
selectArray={yearOptions}
value={searchYear}
onSelectValue={(val: string | number) =>
setSearchYear(String(val))
}
/>
</div>
<div className="grid grid-cols-12 gap-4 h-full">
<div className="col-span-4 h-full min-h-0">
<ListDiv className="min-h-0">
<ScrollArea className="h-[60vh]">
<UiTable
tableData={bdstTable || []}
headlist={pbnstPrfmncHeadList}
pageSize={100}
total={10}
headName={"하수재이용시설 목록"}
cellClick={() => { }}
onPageChange={(page: number) => { }}
children={undefined}
/>
</ScrollArea>
</ListDiv>
</div>
<ListDiv className="col-span-8 pr-6 ">
<ScrollArea className="h-[60vh]">
<UiTable
tableData={[]}
headlist={monthHeadList}
pageSize={100}
total={10}
headName={"하수처리수재이용 실적(m3) 등록결과"}
cellClick={() => { }}
onPageChange={() => { }}
children={undefined}
/>
</ScrollArea>
</ListDiv>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">
{"시설명"}
</Label>
<SearchInput
className={"w-full text-2xl"}
label=""
textValue={searchTxt || ""}
setText={(e) => {
setSearchTxt(e);
}}
/>
</div>
</ContentsDiv>
</>
);
</SearchFormLeft>
<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 size={"sm"} onClick={(e) => {}}>
조회
</Button>
<Button size={"sm"} onClick={() => {}}>
저장
</Button>
<Button size={"sm"} onClick={() => {setIsExcelOPen(true)}}>
파일등록
</Button>
<Button color="green" size={"sm"} onClick={() => {}}>
양식받기
</Button>
</div>
</div>
</SearchFormRight>
</SearchDiv>
</div>
</div>
<div className="grid grid-cols-12 gap-4 h-full">
<div className="col-span-4 h-full min-h-0">
<ListDiv className="min-h-0">
<ScrollArea className="h-[60vh]">
<UiTable
tableData={bdstTable || []}
headlist={pbnstPrfmncHeadList}
pageSize={100}
total={10}
headName={"하수재이용시설 목록"}
cellClick={() => {}}
onPageChange={(page: number) => {}}
children={undefined}
/>
</ScrollArea>
</ListDiv>
</div>
<ListDiv className="col-span-8 pr-6 ">
<ScrollArea className="h-[60vh]">
<UiTable
tableData={[]}
headlist={monthHeadList}
pageSize={100}
total={10}
headName={"하수처리수재이용 실적(m3) 등록결과"}
cellClick={() => {}}
onPageChange={() => {}}
children={undefined}
/>
</ScrollArea>
</ListDiv>
</div>
</ContentsDiv>
<UiModal bodyClass={""} body={<PbnPrfExcelModal></PbnPrfExcelModal>} open={isExcelOpen} onOpenChange={() => {setIsExcelOPen(!isExcelOpen)}}></UiModal>
<Toaster position="top-center" />
</>
);
}
@@ -0,0 +1,43 @@
import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg";
const nameMap = {
"세척수": "wshwtr",
"냉각수": "coolUswtr",
"청소수": "cleanUswtr",
"식수대": "drwtUswtr",
"희석용수": "dltnUswtr",
"중수도": "ithlRswtr",
"기타": "ithlEtcUswtr",
"청소화장실용수": "cleanToilUswtr",
"세척살수용수": "resn",
"조경용수": "lndwtr",
"친수용수": "hydUswtr",
"지하수충전": "ugwtChr",
"농업용수": "farmUswtr",
"하천등유지용수": "rvrKeepUswtr",
"공업용수": "indstUswtr"
};
export const excelToPbnPrfData = (excelData: any[], year: string) => {
// 월별 데이터 하나로 병합
const merged = {} as any;
excelData.forEach((item: any) => {
const key = nameMap[item["용수명"]];
if (!key) return;
for (let i = 1; i <= 12; i++) {
const month = i.toString().padStart(2, "0");
const ym = year + month;
if (!merged[ym]) merged[ym] = { ym };
merged[ym][key] = Number(item[`${i}월`] ?? 0);
}
});
const pbnPrfData = Object.values(merged);
console.log(pbnPrfData);
return pbnPrfData;
};
@@ -1,5 +1,13 @@
import { z } from "zod";
import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg";
export const pbnPrfRegExcelZod = z.object({
ym: z.string().default(""),
bscFctNm: z.string().default(""),
pbnstRuseFcltNm: z.string().default(""),
file: z.instanceof(File).optional(),
});
export const pbnstPrfmncHeadListExport: TableUpperProps[] = [
{ id: "sido", title: "시도" },
{ id: "gugun", title: "시군구" },
@@ -0,0 +1,168 @@
import { useWrStore } from "@/app/store";
import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel";
import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList";
import { yearOptions } from "@/components/lib/func/commom";
import { ToastFormUi } from "@/components/ui/toast/toastFromUi";
import {
FileUpload,
FormField,
FormUi,
SelectBox,
Form,
Title,
type SelectDataType,
filePicked,
} from "@common/business_components/ui";
import { Button } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import type { z } from "zod";
export default function PbnPrfExcelModal() {
const { code, prfmnc, searchFclts } = useWrStore((state) => state);
const [bscFctNmList, setBscFctNmList] = useState<SelectDataType[] | null>(null);
const [files, setFiles] = useState<File[] | null>(null);
const [excelData, setExcelData] = useState<any[]>();
const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({
resolver: zodResolver(pbnPrfRegExcelZod),
defaultValues: {
ym: String(new Date().getFullYear()),
},
});
const onSubmit = (values: z.infer<typeof pbnPrfRegExcelZod>) => {
console.log(values);
};
useEffect(() => {
if(prfmnc.prfmncRes.length > 0){
const basFctNmList = prfmnc.prfmncRes.map((item)=>(
{
val:item.bscFctCd,
text:item.bscFctNm
}
))
setBscFctNmList(basFctNmList)
}
}, [prfmnc.prfmncRes]);
useEffect(()=>{
if(files){
const file = files[0];
if (form.getValues("ym").length < 1) {
ToastFormUi({
body: "파일업로드 이전에 등록년도를 작성해주세요 ",
title: "지도점검 등록",
});
setFiles(null);
return;
}
if(file)
filePicked(file, 0).then((res) => {
if (res !== undefined)
console.log(excelToPbnPrfData(res, form.getValues("ym")))
});
}
},[files])
return (
<>
<div>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div>
<Title title={"하수재이용 실적등록"}></Title>
</div>
<div className="flex justify-between">
<h3 className="text-2xl font-bold text-gray-900 mt-1 ml-7">
{"점검정보 입력"}
</h3>
<Button className="" type="submit">
저장
</Button>
</div>
<div>
<FormField
control={form.control}
name="ym"
render={({ field }) => (
<FormUi label="등록년도">
<SelectBox
className="w-1/4 text-3xl"
selectClass={""}
label=""
selectArray={yearOptions}
value={field.value}
onSelectValue={(val) => field.onChange(val)}
/>
</FormUi>
)}
/>
<FormField
control={form.control}
name="bscFctNm"
render={({ field }) => (
<FormUi label="시설명">
<SelectBox
className="w-1/4 text-3xl"
selectClass={""}
label=""
selectArray={bscFctNmList || [] }
value={field.value}
onSelectValue={(val) => field.onChange(String(val))}
/>
</FormUi>
)}
/>
<FormField
control={form.control}
name="pbnstRuseFcltNm"
render={({ field }) => (
<FormUi label="재이용시설명">
<SelectBox
className="w-1/4 text-3xl"
selectClass={""}
label=""
selectArray={yearOptions}
value={field.value}
onSelectValue={(val) => field.onChange(String(val))}
/>
</FormUi>
)}
/>
<FormField
control={form.control}
name="file"
render={({ field }) => (
<FormUi label="점검결과 파일">
<FileUpload
files={files || []}
setFiles={(files: File[] | null) => {
if (files) setFiles(files);
}}
fileTypes="xlsx"
></FileUpload>
</FormUi>
)}
/>
</div>
</form>
</Form>
</div>
</>
);
}