Merge branch 'iipbs/wr/stats' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/wr/stats

This commit is contained in:
jyha00
2025-06-19 13:38:50 +09:00
16 changed files with 1694 additions and 11645 deletions
File diff suppressed because it is too large Load Diff
+276 -418
View File
@@ -1,434 +1,292 @@
"use client";
import { useWrStore } from "@/app/store";
import { formTableName } from "@/components/lib/class/comClass";
import { getCity } from "@/components/lib/func/commom";
import { CmpttnModal } from "@/components/ui/modal/coMat/cmpttnModal";
import { CoMatModal } from "@/components/ui/modal/coMat/coMatModal";
import {
DmdCoReqSchema,
type DmdCoReqType,
} from "@/app/store/matDmd/coMatRvw/type";
import {
getCity,
getdmdMatFlag,
yearOptions,
} from "@/components/lib/func/commom";
import ConCostForm from "@/components/ui/form/coMat/conCostForm/conCostForm";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui";
import {
ContentsDiv,
SearchDiv,
SearchFormLeft,
SearchFormRight,
SearchInput,
SelectBox,
Title,
UiTable,
type SelectDataType,
} from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, DatePicker, Input, Label } from "@common/components/ui";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@common/components/ui/tooltip";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { useFieldArray, useForm } from "react-hook-form";
import moment from "moment";
import { useCallback, useEffect, useState } from "react";
import { set, useFieldArray, useForm } from "react-hook-form";
import { z } from "zod";
import { tableData } from "@/components/lib/func/commom";
import toast, { Toaster } from "react-hot-toast";
export default function RuseRvwHstry() {
const { code, ruseHstry, } = useWrStore((state) => state);
const { ruseHstryHeadList, } = ruseHstry;
const [fromDate, setFromDate] = useState<Date>(new Date());
const [toDate, setToDate] = useState<Date>(new Date());
const schema = z.object({});
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>()
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
const { code, ruseHist, ruseRvwHistInit, ruseRvwSearch, ruseRvwInqua } =
useWrStore((state) => state);
const { rvwHistRes, ruseHistHeadList } = ruseHist;
const schema = z.object({});
const [pageNation, setPageNatiion] = useState<number>(1);
const getSelCity = (val: string | number) => {
const cityValue = String(val); // Ensure val is treated as a string
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
setObjSearch({ city: cityValue, sgg: '' });
};
const [dmdCoNm, setDmdCoNm] = useState<string>("");
const [ruseUtztnFcltNm, setRuseUtztnFcltNm] = useState<string>("");
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>();
const [objSearch, setObjSearch] = useState<objSearchType>({
sgg: "",
city: "",
});
const getSgg = (val: string | number) => {
console.log(val);
setObjSearch({ ...objSearch, sgg: String(val) })
};
const [fromDate, setFromDate] = useState<string>(
String(new Date().getFullYear())
);
const [toDate, setToDate] = useState<string>(
String(new Date().getFullYear())
);
const [rvwHistData, setRvwHistData] = useState<DmdCoReqType[]>();
const form = useForm<z.infer<typeof schema>>({
resolver: zodResolver(schema),
defaultValues: {
fcltCpct: 0,
}
});
const [isPrcsMo, setIsPrcsMo] = useState<{
isModal: boolean;
}>({ isModal: false });
const [isTrfMo, setIsTrfMo] = useState<{
isModal: boolean;
}>({ isModal: false, });
const [isCmpttnMo, setIsCmpttnMo] = useState<{
isModal: boolean;
}>({ isModal: false, });
const getSelCity = (val: string | number) => {
const cityValue = String(val); // Ensure val is treated as a string
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
setObjSearch({ city: cityValue, sgg: "0" });
};
return (
<ContentsDiv>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<Title title={"재이용검토이력"} />
<SearchDiv>
<SearchFormLeft>
<div className="col-span-8 flex flex-row">
<SelectBox
className="col-span-2 w-1/3 h-full text-2xl"
label="시도"
selectClass={""}
selectArray={code.cityCd || []}
onSelectValue={getSelCity}
>
{""}
</SelectBox>
<SelectBox
className="col-span-2 w-1/3 h-full text-2xl ml-4"
label="시군구"
selectClass={""}
selectArray={selectSgg || []}
onSelectValue={getSgg}
>
{""}
</SelectBox>
<div className="col-span-5 w-full">
<div className="flex flex-row items-center">
<Label className="text-xl text-gray-600 ml-4 mr-4">수요신청년도</Label>
<div className="flex flex-row">
<DatePicker mode={'single'}
className="w-full"
selected={fromDate}
onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }} />
<span className="ml-2 mr-2">~</span>
<DatePicker mode={'single'}
selected={toDate}
onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} />
</div>
</div>
</div>
<SearchInput
className={"text-2xl"}
label="시설명"
textValue={""}
setText={(e) => {
}}
/>
<SearchInput
className={"text-2xl ml-4"}
label="회사명"
textValue={""}
setText={(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={(e) => { }}
>
검토완료
</Button>
</div>
</div>
</SearchFormRight>
</SearchDiv>
const getSgg = (val: string | number) => {
console.log(val);
setObjSearch({ ...objSearch, sgg: String(val) });
};
const getSearch = (
startYear: number,
endYear: number,
sggCd: string,
dmdCoNm: string,
ruseUtztnFcltNm: string
) => {
if (dmdCoNm || ruseUtztnFcltNm) {
ruseRvwSearch(
pageNation,
13,
String(startYear),
String(endYear),
sggCd,
dmdCoNm,
ruseUtztnFcltNm
);
} else {
ruseRvwInqua(pageNation, 13, String(startYear), String(endYear), sggCd);
}
};
const form = useForm<DmdCoReqType>({
resolver: zodResolver(DmdCoReqSchema),
});
const TableCellClick = useCallback(
(index: number | undefined) => {
if (
index !== undefined &&
index >= 0 &&
rvwHistRes &&
rvwHistRes[index]
) {
form.reset(rvwHistRes[index]);
}
},
[rvwHistRes, form]
);
useEffect(() => {
if (!ruseHist.isInit) {
ruseRvwHistInit(
1,
13,
new Date().getFullYear().toString(),
new Date().getFullYear().toString()
);
}
}, [ruseHist.isInit]);
useEffect(() => {
if (rvwHistRes) {
const data = rvwHistRes?.map((item, index) => {
return {
...item,
ctpvCd: item.demandCo.ctpvCd,
sggCd: item.demandCo.sggCd,
dmdCoNm: item.demandCo.dmdCoNm,
daddr: item.demandCo.daddr,
telno: item.demandCo.telno,
regDt: item?.demandCo?.regDt
? moment(item?.demandCo?.regDt).format("YYYY-MM-DD")
: "없음",
rvwCmptnYmd: item?.rvwCmptnYmd
? moment(item?.rvwCmptnYmd).format("YYYY-MM-DD")
: "없음",
mtchnCmptnYmd: item?.mtchnCmptnYmd
? moment(item?.mtchnCmptnYmd).format("YYYY-MM-DD")
: "없음",
splyFcltFk: item.demandMatching?.splyFcltFk,
dmndQty: item.dmndQty,
splyFcltFlg: getdmdMatFlag(item.demandMatching?.splyFcltFlg),
matYn: false,
};
});
setRvwHistData(tableData(data, { code }));
}
}, [rvwHistRes]);
useEffect(() => {
}, [form.formState]);
return (
<ContentsDiv>
<div className="grid grid-cols-4 gap-4">
<div className="col-span-4">
<Title title={"재이용검토이력"} />
<SearchDiv>
<SearchFormLeft>
<div className="col-span-10 flex flex-row">
<SelectBox
className="w-80 h-full text-2xl"
label="시도"
selectClass={""}
selectArray={code.cityCd || []}
onSelectValue={getSelCity}
>
{""}
</SelectBox>
<SelectBox
className="w-80 h-full text-2xl ml-4"
label="시군구"
selectClass={""}
selectArray={selectSgg || []}
onSelectValue={getSgg}
>
{""}
</SelectBox>
<div className="col-span-4 w-full">
<div className="flex flex-row items-center">
<Label className="text-xl text-gray-600 ml-4 mr-4">
수요신청년도
</Label>
<div className="flex flex-row mt-2">
<SelectBox
className="h-full w-32 text-2xl"
label=""
selectClass={""}
selectArray={yearOptions}
value={fromDate}
onSelectValue={(val: string | number) =>
setFromDate(String(val))
}
/>
<span className="mx-6">~</span>
<SelectBox
className="h-full w-32 text-2xl"
label=""
selectClass={""}
selectArray={yearOptions}
value={toDate}
onSelectValue={(val: string | number) =>
setToDate(String(val))
}
/>
<SearchInput
className={"text-2xl w-60 ml-4 "}
label="시설명"
textValue={ruseUtztnFcltNm}
setText={setRuseUtztnFcltNm}
/>
<SearchInput
className={"text-2xl w-60 ml-4 "}
label="회사명"
textValue={dmdCoNm}
setText={setDmdCoNm}
/>
</div>
</div>
</div>
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<ListDiv>
<UiTable
headName={"재이용검토현황"}
tableData={[]}
children={undefined}
headlist={ruseHstryHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
}}
onPageChange={() => { }}
></UiTable>
<hr />
<Form {...form}>
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">수요신청 상세현황</h3>
<h1 className="mt-2 ml-3">표준공사비 산정</h1>
<div className="flex items-center mx-3 mb-3">
<h1 className="">처리시설 표준공사비 산정</h1>
<Button
size={"sm"}
onClick={(e) => { }}
>
재계산
</Button>
<Button
size={"sm"}
onClick={(e) => { }}
>
저장
</Button>
</div>
<div className="grid grid-cols-12 gap-4 ml-4 mr-4">
<div className="col-span-3 mt-4">
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="용도">
<Input
placeholder=""
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? ""}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="요구수량(M3/d)">
<Input
placeholder=""
type="number"
step="0.1"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<Label className="">용도에 따른 처리공정<i className="diveicon di-search" onClick={(e) => setIsPrcsMo({ isModal: true })} /></Label>
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value || ""}
className="mt-2"
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="처리시설 용량(요구수량 * 365일)">
<Input
placeholder=""
type="number"
step="0.001"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<div className="flex items-center justify-between">
<Label>처리시설용량에 따른 공사비(백만원)</Label>
<Button
size={"sm"}
onClick={(e) => setIsCmpttnMo({ isModal: true })}
className="bg-none"
>
공사비 산정표 보기
</Button>
</div>
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="number"
step="0.001"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<div className="flex items-center justify-between">
<Label>시설부대경비 요율(%)</Label>
<Button
size={"sm"}
onClick={(e) => setIsTrfMo({ isModal: true })}
>
요율표 보기
</Button>
</div>
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="number"
step="0.01"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<Label>총사업비 (백만원)
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<i className="diveicon di-search" />
</TooltipTrigger>
<TooltipContent>
<div className="font-bold mb-1 text-xl">총사업비 계산방법</div>
<div className="text-lg">하수처리수 재이용시설 총 사업비 = 공사비+시설부대경비 </div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</Label>
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
className="mt-2"
type="number"
step="0.01"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<div className="flex items-center justify-between">
<Label>공급처 선정</Label>
<Button
size={"sm"}
onClick={(e) => { }}
className="bg-none"
>
후보지 조회
</Button>
</div>
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? ""}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-4 mt-4 mb-3">
<div className="mt-4">
<Label>관로 표준공사비 산정</Label>
</div>
</div>
</div>
</Form>
</ListDiv>
</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) => {
if (fromDate && toDate) {
const fromNum = Number(fromDate);
const toNum = Number(toDate);
if (fromNum > toNum) {
toast.error(
"시작년도가 종료년도 이후로 설정할 수 없습니다."
);
} else {
let con: string | number = "";
if (String(objSearch.city).length > 0) {
con = String(objSearch.city);
}
if (String(objSearch.sgg).length > 0) {
con = String(objSearch.sgg);
}
getSearch(
fromNum,
toNum,
con,
dmdCoNm,
ruseUtztnFcltNm
);
}
}
}}
>
조회
</Button>
<Button size={"sm"} onClick={(e) => {}}>
검토완료
</Button>
</div>
<UiModal
body={
<>
<UiTable
headName={"용도에 따른 처리공정"}
tableData={[
{ usage: "청소", process: "총인처리시설 + 염소소독" },
{ usage: "화장실용수", process: "총인처리시설 + 염소소독" },
{ usage: "세척", process: "총인처리시설 + UV소독" },
{ usage: "살수", process: "총인처리시설 + UV소독" },
{ usage: "조경", process: "총인처리시설 + UV소독" },
{ usage: "농업", process: "총인처리시설 + UV소독" },
{ usage: "하천", process: "총인처리시설 + UV소독" },
{ usage: "지하수", process: "전처리시설 + RO" },
{ usage: "공업용수", process: "전처리시설 + RO" },
</div>
</SearchFormRight>
</SearchDiv>
</div>
</div>
]}
headlist={[
{ id: "usage", title: "용도" },
{ id: "process", title: "단위공정" }
]}
pageSize={0}
total={0}
cellClick={() => { }}
onPageChange={() => { }}
/>
</>
}
bodyClass="w-[25vw] max-w-none h-[60vh]"
open={isPrcsMo.isModal}
onOpenChange={(open) => {
setIsPrcsMo({ isModal: open });
}}
/>
<UiModal
body={
<CoMatModal data={[]}></CoMatModal>
}
bodyClass="w-[40vw] max-w-none h-[70vh]"
open={isTrfMo.isModal}
onOpenChange={(open) => {
setIsTrfMo({ isModal: open });
}}
/>
<UiModal
body={
<CmpttnModal data={[]}></CmpttnModal>
}
bodyClass="w-[70vw] max-w-none h-[50vh]"
open={isCmpttnMo.isModal}
onOpenChange={(open) => {
setIsCmpttnMo({ isModal: open });
}}
/>
</div>
</ContentsDiv >
)
}
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<ListDiv>
<UiTable
headName={"재이용검토현황"}
tableData={rvwHistData || []}
headlist={ruseHistHeadList}
pageSize={20}
total={100000}
cellClick={(index: number | undefined, headId: string) => {
TableCellClick(index);
}}
onPageChange={setPageNatiion}
></UiTable>
<hr />
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">
수요신청 상세현황
</h3>
<ConCostForm form={form} type={"hist"} />
</ListDiv>
</div>
</div>
<Toaster position="top-center" />
</ContentsDiv>
);
}
+35 -52
View File
@@ -1,8 +1,9 @@
"use client";
import Link from "next/link";
import { Button } from "@common/components/ui";
import { useRouter } from "next/navigation";
export default function Home() {
const router = useRouter();
return (
<>
<div className="flex flex-col gap-8 p-6">
@@ -11,27 +12,23 @@ export default function Home() {
<h2 className="text-xl font-semibold mb-4">시설 등록</h2>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltReg/pbnstReg">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltReg/pbnstReg')}}>
하수재이용 시설 등록
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltReg/rainReg">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltReg/rainReg')}}>
빗물재이용 시설 등록
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltReg/rswtReg">중수도시설 등록</Link>
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltReg/rswtReg')}}>
중수도시설 등록
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltReg/htdflReg">온배수 등록</Link>
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltReg/htdflReg')}}>
온배수시설 등록
</Button>
</div>
</div>
@@ -42,29 +39,23 @@ export default function Home() {
<h2 className="text-xl font-semibold mb-4">지도점검 결과</h2>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/prfmncReg/pbnstPrfmncReg">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/prfmncReg/pbnstPrfmncReg')}}>
하수재이용실적 등록
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/prfmncSttn/pbnstPrfmncSttn">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn')}}>
하수재이용실적 현황
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/prfmncReg/chkgdnReg">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/prfmncReg/chkgdnReg')}}>
지도점검 결과 등록
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/prfmncSttn/chkgdnSttn">지도점검 결과 현황</Link>
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/prfmncSttn/chkgdnSttn')}}>
지도점검 결과 현황
</Button>
</div>
</div>
@@ -75,31 +66,23 @@ export default function Home() {
<h2 className="text-xl font-semibold mb-4">시설 현황</h2>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltSttn/pbnstSttn">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltSttn/pbnstSttn')}}>
하수재이용시설현황
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltSttn/rainSttn">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltSttn/rainSttn')}}>
빗물재이용시설현황
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltSttn/rswtSttn">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltSttn/rswtSttn')}}>
중수도이용시설현황
</Link>
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="ruseFcltMng/fcltSttn/htdflSttn">
<Button className="w-full" onClick={() => {router.push('/ruseFcltMng/fcltSttn/htdflSttn')}}>
온배수현황
</Link>
</Button>
</div>
</div>
@@ -111,18 +94,18 @@ export default function Home() {
<div className="grid grid-cols-12 gap-4">
<div className="col-span-2">
<Button className="w-full">
<Link href="matMng/coMng/coSttn">수요처 관리</Link>
<Button className="w-full" onClick={() => {router.push('/matMng/coMng/coSttn')}}>
수요처 관리
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="matMng/coMng/ldrmntCoSttn">잠재수요처 관리</Link>
<Button className="w-full" onClick={() => {router.push('/matMng/coMng/ldrmntCoSttn')}}>
잠재수요처 관리
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="matMng/coMng/drgtSttn">우리동네가뭄</Link>
<Button className="w-full" onClick={() => {router.push('/matMng/coMng/drgtSttn')}}>
우리동네가뭄
</Button>
</div>
</div>
@@ -133,18 +116,18 @@ export default function Home() {
<h2 className="text-xl font-semibold mb-4">수요처 매칭</h2>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-2">
<Button className="w-full">
<Link href="matMng/coMat/coMatRvw">수요처 매칭 검토</Link>
<Button className="w-full" onClick={() => {router.push('/matMng/coMat/coMatRvw')}}>
수요처 매칭 검토
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="matMng/coMat/ruseRvwHstry">재이용검토이력</Link>
<Button className="w-full" onClick={() => {router.push('/matMng/coMat/ruseRvwHstry')}}>
재이용검토이력
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="matMng/coMat/ruseCaseMng">물재이용사례 관리</Link>
<Button className="w-full" onClick={() => {router.push('/matMng/coMat/ruseCaseMng')}}>
물재이용사례 관리
</Button>
</div>
</div>
@@ -154,18 +137,18 @@ export default function Home() {
<h2 className="text-xl font-semibold mb-4">통계 매칭</h2>
<div className="grid grid-cols-12 gap-4">
<div className="col-span-2">
<Button className="w-full">
<Link href="stats/rainStat">빗물재이용시설통계</Link>
<Button className="w-full" onClick={() => {router.push('/stats/rainStat')}}>
빗물재이용시설통계
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="stats/rswtStat">중수도시설통계</Link>
<Button className="w-full" onClick={() => {router.push('/stats/rswtStat')}}>
중수도시설통계
</Button>
</div>
<div className="col-span-2">
<Button className="w-full">
<Link href="stats/matStat">물재이용사례 관리</Link>
<Button className="w-full" onClick={() => {router.push('/stats/matStat')}}>
물재이용사례 관리
</Button>
</div>
</div>
@@ -249,4 +249,16 @@ export const coModalHeadListExport: CommonTableProps[] = [
rowSpan: 1,
colSpan: 1,
},
]
export const usageProcData =[
{ usage: "청소", process: "총인처리시설 + 염소소독" },
{ usage: "화장실용수", process: "총인처리시설 + 염소소독" },
{ usage: "세척", process: "총인처리시설 + UV소독" },
{ usage: "살수", process: "총인처리시설 + UV소독" },
{ usage: "조경", process: "총인처리시설 + UV소독" },
{ usage: "농업", process: "총인처리시설 + UV소독" },
{ usage: "하천", process: "총인처리시설 + UV소독" },
{ usage: "지하수", process: "전처리시설 + RO" },
{ usage: "공업", process: "전처리시설 + RO" },
]
+129 -12
View File
@@ -2,8 +2,9 @@ import type { z } from "zod";
import type { sttnHeadListType } from "../coSttn/headList";
import { coRvwHeadListExport, coRvwNodeListExport } from "./headList";
import type { CommonTableProps } from "../../common/type/header";
import type { DmdCoReqType } from "./type";
import { fetchType, getFetch } from "@/components/lib/api";
import type { DedMatUpdateType, DmdCoReqType } from "./type";
import { fetchType, getFetch, putFectch } from "@/components/lib/api";
import toast from "react-hot-toast/headless";
const coRvwHeadList = coRvwHeadListExport;
const coRvwNodeList = coRvwNodeListExport;
@@ -30,35 +31,151 @@ export type coRvwType = coRvwState & coRvwActions;
type coRvwActions = {
coMatRvwInit: (
pageCnt: number,
pageNo: number,
sggCd: string,
pageCnt: number,
startYear: string,
endYear: string
endYear: string,
) => void;
coMatRvwUpdate: (
splyCd: string,
dmdCd: string,
data: DedMatUpdateType
) => void;
coMatRvwSearch: (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string,
dmdCoNm: string,
) => void;
coMatRvwInqua: (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string
) => void;
};
const coMatInit = async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
) => {
const url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
const coMatRvwRes = await getFetch(fetchType.WR, url);
return coMatRvwRes;
};
export const coRvwActionsExport: (set: any) => coRvwActions = (set: any) => {
return {
coMatRvwInit: async (
pageCnt: number,
pageNo: number,
sggCd: string,
pageCnt: number,
startYear: string,
endYear: string
endYear: string,
) => {
const tempData = `/reuseFc/request/10000000000000`;
const url = `/reuseFc/request/${pageNo}/${pageCnt}/${sggCd}/${startYear}/${endYear}}`;
const coMatRvwRes = await getFetch(fetchType.WR, tempData);
const url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
const coMatRvwRes = await getFetch(fetchType.WR, url);
return set((state: coRvwState) => ({
...state,
coRvw: {
...state.coRvw,
init: false,
coMatRvwRes: [coMatRvwRes],
coMatRvwRes: coMatRvwRes,
},
}));
},
coMatRvwUpdate: async (
splyCd: string,
dmdCd: string,
data: DedMatUpdateType
) => {
try {
const isUpdate = await putFectch(
`/reuseFc/request/cst/${splyCd}/${dmdCd}`,
data
);
const coMatRvwRes = coMatInit(
1,
10,
new Date().getFullYear().toString(),
new Date().getFullYear().toString(),
);
return set((state: coRvwState) => ({
...state,
coRvw: {
...state.coRvw,
init: false,
coMatRvwRes: coMatRvwRes,
},
}));
} catch (e) {
toast.error("매칭 검토 저장 오류입니다.");
}
},
coMatRvwSearch: async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string,
dmdCoNm: string,
) => {
let url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
if (sggCd.length > 0) {
url += `/${sggCd}`;
} else {
url += `/0`;
}
if (dmdCoNm?.length > 0) {
url += `/${dmdCoNm}`;
} else {
url += `/0`;
}
console.log(' url ', url)
const coMatRvwRes = await getFetch(fetchType.WR, url);
return set((state: coRvwState) => ({
...state,
coRvw: {
...state.coRvw,
coMatRvwRes: coMatRvwRes,
},
}));
},
coMatRvwInqua: async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string
) => {
try {
let url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
if (sggCd.length > 0) {
url += `/${sggCd}`;
}else if(sggCd ==='0'){
url += `/0/0`;
}
const coMatRvwRes = await getFetch(fetchType.WR, url);
return set((state: coRvwState) => ({
...state,
coRvw: {
...state.coRvw,
coMatRvwRes: coMatRvwRes,
},
}));
} catch (e) {
console.log(" error ", e);
}
},
};
};
+94 -46
View File
@@ -1,40 +1,43 @@
import { z } from "zod";
const DmdInfoSchema = z.object({
dmdInfoSn: z.number(),
dmdInfoFk: z.string(),
dmndTmng: z.coerce.date(),
dmndQty: z.number(),
wntUntprc: z.number(),
grssClfg: z.number(),
combResdch: z.number(),
trbt: z.number(),
blgcOxygDmndQnt: z.number(),
smll: z.number(),
crmty: z.number(),
tn: z.number(),
tph: z.number(),
ph: z.number(),
clIonQnt: z.number(),
cdtnv: z.number(),
rmrk: z.string(),
useUsgCd: z.string(),
});
const DmdMatSchema = z.object({
dmdInfoFk: z.string(),
splyFcltFk: z.string(),
splyFcltFlg: z.string(),
pbnstRuseFcltBizFk: z.number(),
splyBgngDay: z.coerce.date(),
splyEndDay: z.coerce.date(),
splyCpct: z.number(),
splyFmYn: z.string(),
useUsgCd: z.string(),
});
export const DmdCoReqSchema =
z.object({
cityText:z.string().nullish(),
sggText:z.string().nullish(),
const DemandInfoSchema = z.object({
dmdInfoSn: z.number(),
dmdInfoFk: z.string(),
dmndTmng: z.coerce.date(),
dmndQty: z.number(),
wntUntprc: z.number(),
grssClfg: z.number(),
combResdch: z.number(),
trbt: z.number(),
blgcOxygDmndQnt: z.number(),
smll: z.number(),
crmty: z.number().nullish(),
tn: z.number(),
tph: z.number(),
ph: z.number(),
clIonQnt: z.number(),
cdtnv: z.number(),
rmrk: z.string(),
useUsgCd: z.string(),
mtchnCmptnYmd: z.string().nullish(),
rvwCmptnYmd: z.string().nullish()
});
const DemandMatchingSchema = z.object({
dmdInfoFk: z.string().nullish(),
splyFcltFk: z.string().nullish(),
splyFcltFlg: z.string().nullish(),
pbnstRuseFcltBizFk: z.number().nullish(),
splyBgngDay: z.coerce.date().nullish(),
splyEndDay: z.coerce.date().nullish(),
splyCpct: z.number().nullish(),
splyFmYn: z.string().nullish(),
useUsgCd: z.string().nullish(),
dmdInfoSn: z.number().nullish(),
splyCndtList:z.array(z.string().nullish() ).nullish()
});
const DemandCoSchema = z.object({
dmdInfoPk: z.string(),
dmdCoNm: z.string(),
ctpvCd: z.string(),
@@ -43,19 +46,53 @@ export const DmdCoReqSchema =
splyBgngDay: z.coerce.date(),
splyEndDay: z.coerce.date(),
splyCpct: z.number(),
splyFmYn: z.string(),
splyFmYn: z.string().nullish(),
telno: z.string(),
useUsgCd: z.string(),
regDt: z.coerce.date(),
rgtr: z.string(),
mdfcnDt: z.coerce.date(),
mdfr: z.string(),
useUsgCd: z.string().nullish(),
regDt: z.coerce.date().nullish(),
rgtr: z.string().nullish(),
mdfcnDt: z.coerce.date().nullish(),
mdfr: z.string().nullish(),
dmdAplyPswd: z.string(),
demandInfo: z.array(DmdInfoSchema),
demandMatchings: z.array(DmdMatSchema),
})
demandInfo: z.array(DemandInfoSchema.nullish()).nullish(), // 안쓰는 거임
demandMatchings: z.array(DemandMatchingSchema.nullish()).nullish()// 안쓰는 거임
});
const DemandCstSchema = z.object({
dmdInfoSn: z.number(),
usgPrcsProcs: z.string().nullish(),
cstrnCst: z.number(),
fcltSbsdEpsTrf: z.number(),
prcsFcltCpctCstrnCst: z.number()
});
export const DmdCoReqSchema = z.object({
cityText:z.string().nullish(),
sggText:z.string().nullish(),
dmdInfoSn: z.number(),
dmdInfoFk: z.string(),
dmndTmng: z.coerce.date(),
dmndQty: z.number(),
wntUntprc: z.number(),
grssClfg: z.number(),
combResdch: z.number(),
trbt: z.number(),
blgcOxygDmndQnt: z.number(),
smll: z.number(),
crmty: z.number(),
tn: z.number(),
tph: z.number(),
ph: z.number(),
clIonQnt: z.number(),
cdtnv: z.number(),
rmrk: z.string(),
useUsgCd: z.string().nullish(),
mtchnCmptnYmd: z.string().nullish(),
rvwCmptnYmd: z.string().nullish(),
demandCo: DemandCoSchema.nullish(),
demandMatching: DemandMatchingSchema.nullish(),
demandCst: DemandCstSchema
});
export type DmdCoReqType = z.infer<typeof DmdCoReqSchema>;
@@ -67,4 +104,15 @@ export type DmdMatTableType = {
telno:string,
regDt:string,
state:string
}
export type DedMatUpdateType =
{
dmdInfoSn: number;
usgPrcsProcs: string;
cstrnCst: number;
fcltSbsdEpsTrf: number;
prcsFcltCpctCstrnCst: number;
rgtr: string;
}
@@ -1,37 +1,29 @@
import { z } from "zod";
import type { CommonTableProps } from "../../common/type/header";
import type { TableUpperProps } from "../../common/type/header";
export const sttnHeadListType = z.array(
z.object({
id: z.string(),
title: z.string(),
visible: z.boolean(),
})
);
export const ruseHstryHeadListExport: z.infer<typeof sttnHeadListType> = [
export const ruseHstryHeadListExport:TableUpperProps[]= [
{
id: "ctpv",
id: "cityText",
title: "시도",
visible: true,
},
{
id: "sgg",
id: "sggText",
title: "시군구",
visible: true,
},
{
id: "coNm",
id: "dmdCoNm",
title: "회사명",
visible: true,
},
{
id: "addr",
id: "daddr",
title: "공장주소",
visible: true,
},
{
id: "telNo",
id: "telno",
title: "전화번호",
visible: true,
},
@@ -41,17 +33,17 @@ export const ruseHstryHeadListExport: z.infer<typeof sttnHeadListType> = [
visible: true,
},
{
id: "rvwDt", //바꾸기
id: "rvwCmptnYmd", //바꾸기
title: "검토일자",
visible: true,
},
{
id: "matDt", //바꾸기
id: "mtchnCmptnYmd", //바꾸기
title: "매칭 완료일자",
visible: true,
},
{
id: "gong", //바꾸기
id: "splyFcltFk", //바꾸기
title: "공급처",
visible: true,
},
@@ -66,7 +58,7 @@ export const ruseHstryHeadListExport: z.infer<typeof sttnHeadListType> = [
visible: true,
},
{
id: "state", //바꾸기
id: "splyFcltFlg", //바꾸기
title: "진행상태",
visible: true,
},
@@ -74,112 +66,7 @@ export const ruseHstryHeadListExport: z.infer<typeof sttnHeadListType> = [
id: "matYn", //바꾸기
title: "매칭완료 여부",
visible: true,
type:'check'
},
];
// id는 다확인해야함
export const ruseHstryNodeListExport: CommonTableProps[] = [
{
id: "ctpv",
title: "시도",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "sgg",
title: "시군구",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "coNm",
title: "회사명",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "addr",
title: "공장주소",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},{
id: "telNo",
title: "전화번호",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "regDt", //바꾸기
title: "신청일자",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "rvwDt", //바꾸기
title: "검토일자",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},{
id: "matDt", //바꾸기
title: "매칭 완료일자",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},{
id: "gong", //바꾸기
title: "공급처",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "dmndQty", //바꾸기
title: "요구수량(M3/d)",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "useUsgCd", //바꾸기
title: "사용용도",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "state", //바꾸기
title: "진행상태",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
{
id: "matYn", //바꾸기
title: "매칭완료 여부",
visible: true,
row: 1,
rowSpan: 1,
colSpan: 1,
},
];
+186 -16
View File
@@ -1,34 +1,204 @@
import type { z } from "zod";
import type { sttnHeadListType } from "../coSttn/headList";
import type { CommonTableProps } from "../../common/type/header";
import { ruseHstryHeadListExport, ruseHstryNodeListExport } from "./headList";
import type {
CommonTableProps,
TableUpperProps,
} from "../../common/type/header";
import { ruseHstryHeadListExport } from "./headList";
import { fetchType, getFetch, putFectch } from "@/components/lib/api";
import type { DmdCoReqType } from "../coMatRvw/type";
import toast from "react-hot-toast";
const ruseHstryHeadList = ruseHstryHeadListExport;
const ruseHstryNodeList = ruseHstryNodeListExport;
const ruseHistHeadList = ruseHstryHeadListExport;
export type ruseHstryState = {
ruseHstry: {
ruseHist: {
isInit: boolean;
ruseHstryHeadList: z.infer<typeof sttnHeadListType>;
ruseHstryNodeList: CommonTableProps[];
rvwHistRes: DmdCoReqType[];
ruseHistHeadList: TableUpperProps[];
};
};
export const ruseHstryStateExport: ruseHstryState = {
ruseHstry: {
ruseHist: {
isInit: false,
ruseHstryHeadList: ruseHstryHeadList,
ruseHstryNodeList: ruseHstryNodeList,
}
}
rvwHistRes: [],
ruseHistHeadList: ruseHistHeadList,
},
};
export type ruseHstryType = ruseHstryState & ruseHstryActions;
type ruseHstryActions = {
ruseRvwHistInit: (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd?: string
) => void;
ruseRvwCalUpdate: (data: DmdCoReqType) => void;
ruseRvwSearch: (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string,
dmdCoNm: string,
ruseUtztnFcltNm: string
) => void;
ruseRvwInqua: (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string
) => void;
};
export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (set: any) => {
return {
const irvwHistInit = async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd?: string
) => {
let url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
console.log("sggCd ", sggCd);
if (sggCd) {
url += `/${sggCd}`;
}
}
const rvwHistRes = await getFetch(fetchType.WR, url);
return rvwHistRes;
};
export const ruseHstryActionsExport: (set: any) => ruseHstryActions = (
set: any
) => {
return {
ruseRvwHistInit: async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd?: string
) => {
let url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
if (sggCd) {
url += `/${sggCd}`;
}
const rvwHistRes = await irvwHistInit(
pageNo,
pageCnt,
startYear,
endYear,
sggCd
);
return set((state: ruseHstryState) => ({
...state,
ruseHist: {
...state.ruseHist,
init: false,
rvwHistRes: rvwHistRes,
},
}));
},
ruseRvwCalUpdate: async (data: DmdCoReqType) => {
try {
const update = await putFectch(
`/reuseFc/request/cst`,
JSON.stringify(data)
);
if (update.status === 200) {
toast.success("매칭 계산 저장이 완료입니다.");
const rvwHistRes = await irvwHistInit(
1,
10,
new Date().getFullYear().toString(),
new Date().getFullYear().toString(),
"11"
);
return set((state: ruseHstryState) => ({
...state,
ruseHist: {
...state.ruseHist,
init: false,
rvwHistRes: rvwHistRes,
},
}));
}
} catch (e) {
toast.error("매칭 계산 저장이 오류입니다.");
console.log(e);
}
},
ruseRvwSearch: async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string,
dmdCoNm: string,
ruseUtztnFcltNm: string
) => {
let url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
if (sggCd.length > 0) {
url += `/${sggCd}`;
} else {
url += `/0`;
}
if (dmdCoNm?.length > 0) {
url += `/${dmdCoNm}`;
} else {
url += `/0`;
}
if (ruseUtztnFcltNm?.length > 0) {
url += `/${ruseUtztnFcltNm}`;
} else {
url += `/0`;
}
const rvwHistRes = await getFetch(fetchType.WR, url);
return set((state: ruseHstryState) => ({
...state,
ruseHist: {
...state.ruseHist,
rvwHistRes: rvwHistRes,
},
}));
},
ruseRvwInqua: async (
pageNo: number,
pageCnt: number,
startYear: string,
endYear: string,
sggCd: string
) => {
try {
let url = `/reuseFc/request/infoList/${pageNo}/${pageCnt}/${startYear}/${endYear}`;
if (sggCd.length > 0) {
url += `/${sggCd}`;
}
const rvwHistRes = await getFetch(fetchType.WR, url);
return set((state: ruseHstryState) => ({
...state,
ruseHist: {
...state.ruseHist,
rvwHistRes: rvwHistRes,
},
}));
} catch (e) {
console.log(" error ", e);
}
},
};
};
+21 -5
View File
@@ -14,7 +14,7 @@ export const getCity = (val: string, sggCd: SelectDataType[]) => {
val: item.val,
text: item.text, // 한국어 텍스트
}));
data.unshift({val:'0',text:'전체'})
data.unshift({ val: "0", text: "전체" });
return data;
};
@@ -95,8 +95,6 @@ export const excelArrayDownload = (
});
};
// onchange 텍스트를 숫자로 and ,제거
export const handleCommaNumberChange = (
e: React.ChangeEvent<HTMLInputElement>,
@@ -126,7 +124,6 @@ export const getCityOrSgg = (ref: RefObject<ReturnType>) => {
return con;
};
export const safeDate = (value: any): Date | undefined => {
const date = new Date(value);
return isNaN(date.getTime()) ? undefined : date;
@@ -139,4 +136,23 @@ export const yearOptions: { val: string; text: string }[] = Array.from(
val: String(1970 + i),
text: `${1970 + i}년`,
})
);
);
export const getdmdMatFlag = (flag: string) => {
let flagMat = "";
switch (flag) {
case "Init":
flagMat = "신청";
break;
case "Sub":
flagMat = "검토";
break;
case "Matched":
flagMat = "완료";
break;
default :
flagMat = "";
break;
}
return flagMat;
};
@@ -0,0 +1,377 @@
import { useWrStore } from "@/app/store";
import { usageProcData } from "@/app/store/matDmd/coMatRvw/headList";
import type {
DedMatUpdateType,
DmdCoReqType,
} from "@/app/store/matDmd/coMatRvw/type";
import { TEST_UUID } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { formH1Class } from "@/components/lib/class/comClass";
import { CmpttnModal } from "@/components/ui/modal/coMat/cmpttnModal";
import { CoMatModal } from "@/components/ui/modal/coMat/coMatModal";
import {
Form,
FormField,
FormUi,
UiModal,
UiTable,
} from "@common/business_components/ui";
import PopoverUi from "@common/business_components/ui/popover_ui";
import { Button, Input, Label } from "@common/components/ui";
import { useEffect, useState } from "react";
import { type UseFormReturn } from "react-hook-form";
export default function ConCostForm({
form,
type,
}: {
form: UseFormReturn<DmdCoReqType>;
type: string;
}) {
const { coMatRvwUpdate,ruseRvwCalUpdate } = useWrStore((state) => state);
const [isTrfMo, setIsTrfMo] = useState<{
isModal: boolean;
}>({ isModal: false });
const [isCmpttnMo, setIsCmpttnMo] = useState<{
isModal: boolean;
}>({ isModal: false });
const onSubmit = (value: DmdCoReqType) => {
if (type === "mat") {
const data: DedMatUpdateType = {
dmdInfoSn: form.getValues("dmdInfoSn"),
usgPrcsProcs: form.getValues("demandCst.usgPrcsProcs"),
cstrnCst: form.getValues("demandCst.cstrnCst"),
fcltSbsdEpsTrf: form.getValues("demandCst.fcltSbsdEpsTrf"),
prcsFcltCpctCstrnCst: form.getValues("demandCst.prcsFcltCpctCstrnCst"),
rgtr: TEST_UUID,
};
console.log("mat data ", data);
coMatRvwUpdate("11000SW001R1", form.getValues("dmdInfoFk"), data);
} else if (type === "hist") {
console.log("hist data ", value);
ruseRvwCalUpdate(value)
}
};
useEffect(() => {
console.log(" form ", form.formState.errors);
}, [form.formState]);
return (
<>
<hr className="mt-8" />
<Form {...form}>
<h3 className="mt-4 ml-2 text-2xl font-medium text-label">
표준공사비 산정
</h3>
<div className="flex items-center mx-3 mb-3">
<h1 className="">처리시설 표준공사비 산정</h1>
<Button size={"sm"} onClick={(e) => {}}>
계산
</Button>
<Button size={"sm"} onClick={form.handleSubmit(onSubmit)}>
저장
</Button>
</div>
<div className="col-span-12 w-full">
<h1 className={formH1Class}>기본사항</h1>
</div>
<div className="grid grid-cols-12 gap-4 ml-4 mr-4">
<div className="col-span-3 mt-4">
<FormField
control={form.control}
name="useUsgCd"
render={({ field }) => (
<FormUi label="용도">
<Input
placeholder=""
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? ""}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<FormField
control={form.control}
name="dmndQty"
render={({ field }) => (
<FormUi label="요구수량(M3/d)">
<Input
placeholder=""
type="number"
step="0.1"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<PopoverUi
childrenTriger={
<>
<Label className="underline">
용도에 따른 처리공정
<i className="diveicon di-search" />
</Label>
</>
}
childrenBody={
<>
<UiTable
className=""
headName={"용도에 따른 처리공정"}
tableData={usageProcData}
headlist={[
{ id: "usage", title: "용도" },
{ id: "process", title: "단위공정" },
]}
pageSize={0}
total={0}
cellClick={() => {}}
onPageChange={() => {}}
/>
</>
}
bodyClassName={"w-[25vw] max-w-none h-[54vh]"}
></PopoverUi>
<FormField
control={form.control}
name="demandCst.usgPrcsProcs"
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="text"
onChange={field.onChange}
value={form.getValues("demandCst.usgPrcsProcs") ?? ""}
className="mt-2"
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<FormField
control={form.control}
name="dmndQty"
render={({ field }) => (
<FormUi label="처리시설 용량(요구수량 * 365일)">
<Input
placeholder=""
type="number"
step="0.001"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={(Number(field.value) * 365)|| 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-12 w-full">
<h1 className={formH1Class}>공사비 입력사항</h1>
</div>
<div className="col-span-3 mt-4">
<div className="flex items-center justify-between">
<Label>처리시설용량에 따른 공사비(백만원)</Label>
<Button
size={"sm"}
onClick={(e) => setIsCmpttnMo({ isModal: true })}
className="bg-none"
>
공사비 산정표 보기
</Button>
</div>
<FormField
control={form.control}
name="demandCst.prcsFcltCpctCstrnCst"
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="number"
step="0.001"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<div className="flex items-center justify-between">
<Label>시설부대경비 요율(%)</Label>
<Button
size={"sm"}
onClick={(e) => setIsTrfMo({ isModal: true })}
>
요율표 보기
</Button>
</div>
<FormField
control={form.control}
name="demandCst.fcltSbsdEpsTrf"
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="number"
step="0.01"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-3 mt-4">
<PopoverUi
childrenTriger={
<>
<Label className="underline">
총사업비 (백만원) <i className="diveicon di-search" />
</Label>
</>
}
childrenBody={
<>
<div className="!w-full ">
<div className=" items-center font-bold mb-1 !text-3xl">
총사업비 계산방법
</div>
<div className=" items-center !text-2xl">
하수처리수 재이용시설 총 사업비 =
공사비+시설부대경비{" "}
</div>
</div>
</>
}
bodyClassName={"w-[22vw]"}
></PopoverUi>
<Input
placeholder=""
className="mt-2"
type="number"
step="0.01"
onChange={(e) => {}}
value={
form.getValues("demandCst.prcsFcltCpctCstrnCst") +
form.getValues("demandCst.fcltSbsdEpsTrf") || 0
}
/>
</div>
<div className="col-span-3 mt-4">
<div className="flex items-center justify-between">
<Label>공급처 선정</Label>
<Button size={"sm"} onClick={(e) => {}} className="bg-none">
후보지 조회
</Button>
</div>
<FormField
control={form.control}
name=""
render={({ field }) => (
<FormUi label="">
<Input
placeholder=""
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? ""}
/>
</FormUi>
)}
/>
</div>
<div className="col-span-4 mt-4">
<div>
<FormField
control={form.control}
name="demandCst.cstrnCst"
render={({ field }) => (
<FormUi label="공급관로 표준공사비(백만원)">
<Input
placeholder=""
type="text"
step="0.001"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
/>
</FormUi>
)}
/>
</div>
<div className="mt-4">
<Label>관로 표준공사비 산정 프로그램</Label>
<Button size={"sm"} onClick={(e) => {}} className="bg-none">
다운로드
</Button>
</div>
<div className="col-span-4 mt-4 mb-3">
<FormField
control={form.control}
name=""
render={({ field }) => (
<Label className="text-xl">
처리시설 + 공급관로 총사업비(백만원)
<FormUi label="">
<Input
placeholder=""
type="number"
step="0.001"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
readOnly={true}
value={field.value ?? 0}
/>
</FormUi>
</Label>
)}
/>
</div>
</div>
</div>
<UiModal
body={<CoMatModal data={[]}></CoMatModal>}
bodyClass="w-[40vw] max-w-none h-[70vh]"
open={isTrfMo.isModal}
onOpenChange={(open) => {
setIsTrfMo({ isModal: open });
}}
/>
<UiModal
body={<CmpttnModal data={[]}></CmpttnModal>}
bodyClass="w-[70vw] max-w-none h-[50vh]"
open={isCmpttnMo.isModal}
onOpenChange={(open) => {
setIsCmpttnMo({ isModal: open });
}}
/>
</Form>
</>
);
}
+26 -34
View File
@@ -1,40 +1,32 @@
import type { NextConfig } from "next";
import webpack from "webpack";
const subDomain =
process.env.NEXT_PUBLIC_SUB_DOMAIN || "http://localhost:13001";
const nextConfig: NextConfig = {
eslint: {
ignoreDuringBuilds: true,
},
webpack: (config) => {
config.plugins.push(
new webpack.DefinePlugin({
"import.meta.env.VITE_PORT": JSON.stringify(
process.env.NEXT_PUBLIC_PORT
),
"import.meta.env.VITE_PROXY_HOST": JSON.stringify(
process.env.NEXT_PUBLIC_PROXY_HOST
),
"import.meta.env.VITE_SERVER_API_URL": JSON.stringify(
process.env.NEXT_PUBLIC_SERVER_API_URL
),
"import.meta.env.VITE_SITE_ID": JSON.stringify(process.env.SITE_ID),
"import.meta.env.VITE_CLAIM_NAME": JSON.stringify(
process.env.NEXT_PUBLIC_CLAIM_NAME
),
"import.meta.env.VITE_ACCESS_TOKEN": JSON.stringify(
process.env.NEXT_PUBLIC_ACCESS_TOKEN
),
"import.meta.env.VITE_REFRESH_TOKEN": JSON.stringify(
process.env.NEXT_PUBLIC_REFRESH_TOKEN
),
"import.meta.env.VITE_AUTH_USER_ID": JSON.stringify(
process.env.NEXT_PUBLIC_AUTH_USER_ID
),
"process.env.SITE_ID": JSON.stringify(process.env.NEXT_PUBLIC_SITE_ID),
})
);
return config;
async rewrites() {
return {
beforeFiles: [
{
source: "/_next/static/:path*",
destination: `${subDomain}/_next/static/:path*`,
has: [
{
type: "header",
key: "referer",
value: "(.*)/pst(.*)",
},
],
},
],
afterFiles: [
{
source: "/pst/:path*",
destination: `${subDomain}/pst/:path*`,
},
],
fallback: [],
};
},
};
@@ -1,7 +1,7 @@
"use client"
import { Pie, PieChart } from "recharts";
import type { CSSProperties } from "react";
import { Pie, PieChart } from "recharts";
import {
Card,
CardContent
@@ -99,7 +99,7 @@ const CustomLegend = (props: LegendProps) => {
};
export default function DoughnutChart(props: {
chartConfig: ChartConfig;
chartConfig: any;
chartData: ChartDataItem[] | undefined;
chartTitle: string
}) {
@@ -19,4 +19,5 @@ export * from "./tab";
export * from "./table";
export * from "./table_div";
export * from "./title";
export * from "./sdmInsertForm";
export * from "./sdmInsertForm";
export * from "./popover_ui"
@@ -1,20 +1,19 @@
import './lib/css/gis.common.css';
import React, { createContext, useContext, useEffect, useMemo, useRef, useState, useCallback } from 'react';
import { Search } from 'lucide-react';
import OlMap from 'ol/Map';
import View from 'ol/View';
import { defaults as defaultControls, OverviewMap } from 'ol/control';
import { defaults } from 'ol/interaction';
import * as olProj from 'ol/proj';
import proj4 from 'proj4';
import { register } from 'ol/proj/proj4';
import GisApp from './lib/gis.core';
import GisContent from './GisContent';
import GisTree from './GisTree';
import proj4 from 'proj4';
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import GisLonLat from './GisLonLat';
import GisMapToggle from './GisMapToggle';
import GisSelect from './GisSelect';
import GisToolBar from './GisToolBar';
import GisMapToggle from './GisMapToggle';
import { Search } from 'lucide-react';
import GisTree from './GisTree';
import './lib/css/gis.common.css';
import GisApp from './lib/gis.core';
export const GisContext = createContext({ gisCore: null, gisMap: null, treeData: null, checkedLayerIds: null });
export const useGisContext = () => useContext(GisContext);
@@ -243,4 +242,4 @@ function Gis({ isOpen , gisMaps, isSearchModalOpen, treeData = [], isSearch = fa
);
}
export default React.memo(Gis);
export default React.memo(Gis);
@@ -0,0 +1,23 @@
import { Popover, PopoverContent, PopoverTrigger } from "@common/components/ui";
export default function PopoverUi({
childrenTriger,
childrenBody,
bodyClassName
}: {
childrenTriger: React.ReactNode;
childrenBody: React.ReactNode;
bodyClassName:string
}) {
return (
<>
<Popover>
<PopoverTrigger>{childrenTriger}</PopoverTrigger>
<PopoverContent className={bodyClassName}>
{childrenBody}
</PopoverContent>
</Popover>
</>
);
}
-10178
View File
File diff suppressed because it is too large Load Diff