diff --git a/apps/sn/app/layout.js b/apps/sn/app/layout.js new file mode 100644 index 000000000..8525f5f8c --- /dev/null +++ b/apps/sn/app/layout.js @@ -0,0 +1,12 @@ +export const metadata = { + title: 'Next.js', + description: 'Generated by Next.js', +} + +export default function RootLayout({ children }) { + return ( + + {children} + + ) +} diff --git a/apps/sn/app/map/page.tsx b/apps/sn/app/map/page.tsx index b547fb7e4..7185c9660 100644 --- a/apps/sn/app/map/page.tsx +++ b/apps/sn/app/map/page.tsx @@ -1,18 +1,20 @@ -'use client' +"use client"; -import Gis from '@common/business_components/ui/map/Gis'; -import { SearchDiv, SelectBox, UiTable, MainDiv, Title, ContentsDiv, SearchFormLeft, SearchFormRight } from '@common/business_components'; -import ListDiv from '@common/business_components/ui/list_div'; -import { Button, Input } from '@common/components'; -import { useEffect, useState } from "react"; +import Gis, { useGisContext } from "@common/business_components/ui/map/Gis"; import { mapService } from "@service"; +import { useCallback, useEffect, useRef, useState } from "react"; +import GisApp from "@common/business_components/ui/map/lib/gis.core"; +import SearchModal from "./SearchModal"; +import FeatureClickEventPopup from "./featureClickEventPopup"; const Map = () => { - const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정 - const [selectedFeature,setSelectedFeature] = useState(null); // 선택된 피처 상태 - - const fetchData = async () => { + const [selectedFeature, setSelectedFeature] = useState(null); // 선택된 피처 상태 + const gisMaps = useRef(null); + const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 + const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태 + const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터 + const fetchData = async () => { try { const response = await mapService.getLyrStngs(); setTreeData(response.data); // API 응답 저장 @@ -26,10 +28,86 @@ const Map = () => { fetchData(); }, []); + // SearchModal, GisContent 등에서 호출 + const onFeatureSelect = (data: any) => { + let map = gisMaps.current; + if (!map) { + console.warn("지도가 초기화되지 않았습니다."); + return; + } + + // 항상 같은 select 객체 사용 + const select = GisApp.Module.select as any; + if (!select) return; + + // 1. 기존 선택 초기화 + select.resetSelectedFeature(); + + // 2. data가 OpenLayers Feature 인스턴스인지 확인 + let foundFeature = null; + if ( + data && + typeof data.getGeometry === "function" && + typeof data.setStyle === "function" + ) { + // 이미 Feature 인스턴스라면 그대로 사용 + foundFeature = data; + } else { + // 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용 + const featureId = data.fid || data.ftrIdn || data.id; + map + .getLayers() + .getArray() + .forEach((layer: any) => { + const source = layer.getSource?.(); + if (source?.getFeatureById) { + const feature = source.getFeatureById(String(featureId).trim()); + if (feature) foundFeature = feature; + } + }); + } + + // 3. 피처 선택 + if (foundFeature) { + let geometry = foundFeature.getGeometry(); + if (geometry) { + let extent = geometry.getExtent(); + + map.getView().fit(extent, { + duration: 300, + padding: [50, 50, 50, 50], + maxZoom: 16, + constrainResolution: true, + nearest: true, + }); + } + select.selectFeature(foundFeature, true); + } else { + console.warn("OpenLayers Feature를 찾을 수 없습니다:", data); + } + + setFeatureData(data); + setIsOpen(true); + setIsSearchModalOpen(false); + }; return (
- -
+ + ); }; diff --git a/apps/wr/app/matMng/coMat/coMatRvw/page.tsx b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx new file mode 100644 index 000000000..248a45484 --- /dev/null +++ b/apps/wr/app/matMng/coMat/coMatRvw/page.tsx @@ -0,0 +1,847 @@ +"use client"; + +import { useWrStore } from "@/app/store"; +import { formH1Class, 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 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 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 { z } from "zod"; + + +export default function CoMatRvw() { + const { code, coRvw, } = useWrStore((state) => state); + const { coRvwHeadList, } = coRvw; + const [fromDate, setFromDate] = useState(new Date()); + const [toDate, setToDate] = useState(new Date()); + const [selectSgg, setSelectSgg] = useState() + const [objSearch, setObjSearch] = useState({ sgg: "", city: "" }); + 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 schema = z.object({ + fcltCpct: z.number().optional(), + }); + + const form = useForm>({ + resolver: zodResolver(schema), + defaultValues: { + fcltCpct: 0, + } + }); + + 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 getSgg = (val: string | number) => { + console.log(val); + setObjSearch({ ...objSearch, sgg: String(val) }) + }; + + useEffect(() => { + if (fromDate > toDate) { + const newFromDate = new Date(toDate); + newFromDate.setDate(toDate.getDate() - 1); + setFromDate(newFromDate); + } + }, [toDate]); + + return ( + <> + +
+
+ + <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 + className="col-span-2 w-1/3 h-full text-2xl ml-4" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <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'} + 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) => { + }} + /> + </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> + </div> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> + + <div className="grid grid-cols-6 gap-4"> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={"수요매칭검토현황"} + tableData={[]} + children={undefined} + headlist={coRvwHeadList} + pageSize={20} + total={100000} + cellClick={(index: number | undefined, headId: string) => { + }} + onPageChange={() => { }} + ></UiTable> + <hr /> + <ScrollArea className="h-[49vh]"> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label">수요신청 상세현황</h3> + <Form {...form}> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="사용용도"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="희망단가(원/m3)"> + <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-12 w-full"> + <h1 className={formH1Class}>요구수질</h1> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="총대장균군수 (개/100ml)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="결합잔류염소(mg/L)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="탁도(NTU)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="생물학적 산소요구량(BOD)(mg/L)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="냄새"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="색도(도)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="총질소 (T-N)(mg/L)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="총인(T-P)(mg/L)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="수소이온농도(pH)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="염화물(mgCL/L)"> + <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"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="전기전도도(㎲/cm)"> + <Input + placeholder="" + type="number" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + value={field.value ?? 0} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-3 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="비고"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-12 w-full"> + <h1 className={formH1Class}>공급처 후보지</h1> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="후보지1"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(String(e.target.value)); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="후보지2"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + <div className="col-span-4 mt-4"> + <FormField + control={form.control} + name="" + render={({ field }) => ( + <FormUi label="후보지3"> + <Input + placeholder="" + type="text" + onChange={(e) => { + field.onChange(e.target.value); + }} + value={field.value ?? ""} + /> + </FormUi> + )} + /> + </div> + </div> + </Form> + <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={(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"> + <div> + <FormField + control={form.control} + name="" + 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="text" + step="0.001" + onChange={(e) => { + field.onChange(Number(e.target.value)); + }} + readOnly={true} + value={field.value ?? 0} + /> + </FormUi> + </Label> + )} + /> + </div> + </div> + </div> + </Form> + </ScrollArea> + </ListDiv> + </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" }, + + ]} + 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 > + </> + ) +} \ No newline at end of file diff --git a/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx new file mode 100644 index 000000000..4950ab0da --- /dev/null +++ b/apps/wr/app/matMng/coMat/ruseCaseMng/page.tsx @@ -0,0 +1,126 @@ +"use client"; +import { useWrStore } from "@/app/store"; +import { ruseUtzType } from "@/app/store/matDmd/ruseCaseMng/headList"; +import { getCity } from "@/components/lib/func/commom"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +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 } from "@common/components/ui"; +import { useState } from "react"; + +export default function RuseCaseMng() { + const { code,ruseCase} = useWrStore((state) => state); + const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() + const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); + const [selectUtz, setSelectUtz] = useState<string[] | []>() + const [searchTxt, setSearchTxt] = useState<string>() + + const getSelCity = (val: string | number) => { + const cityValue = String(val); + const data = getCity(cityValue, code.sggCd); + setSelectSgg(data); + setObjSearch({ city: cityValue, sgg: '' }); + }; + + const getSgg = (val: string | number) => { + setObjSearch({ ...objSearch, sgg: String(val) }) + }; + 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 + className="col-span-2 w-1/3 h-full text-2xl" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <SelectBox + className="col-span-2 w-1/3 h-full text-2xl" + label="용도" + selectClass={""} + selectArray={ruseUtzType} + onSelectValue={(val) => { + if(val) + setSelectUtz([String(val)])}} + /> + + <SearchInput + className={"text-2xl"} + label="수요처명" + textValue={""} + 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={(e) => { }} + > + 엑셀등록 + </Button> + <Button + size={"sm"} + onClick={(e) => { }} + > + 다운로드 + </Button> + <Button + size={"sm"} + onClick={(e) => { }} + > + 양식받기 + </Button> + </div> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={"물재이용사례 현황"} + tableData={[]} + children={undefined} + headlist={ruseCase.ruseHeadList} + pageSize={20} + total={100000} + cellClick={(index: number | undefined, headId: string) => { + }} + onPageChange={() => { }} + ></UiTable> + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx similarity index 78% rename from apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx rename to apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx index 9b3d2262f..70d57d0b9 100644 --- a/apps/wr/app/matMng/matDmd/ruseRvwHstry/page.tsx +++ b/apps/wr/app/matMng/coMat/ruseRvwHstry/page.tsx @@ -3,17 +3,20 @@ 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 type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; +import { ContentsDiv, Form, FormField, FormUi, ScrollArea, SearchDiv, SearchFormLeft, SearchFormRight, SearchInput, SelectBox, Title, UiModal, 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 { z } from "zod"; -export default function ruseRvwHstry() { +export default function RuseRvwHstry() { const { code, ruseHstry, } = useWrStore((state) => state); const { ruseHstryHeadList, } = ruseHstry; const [fromDate, setFromDate] = useState<Date>(new Date()); @@ -40,18 +43,17 @@ export default function ruseRvwHstry() { 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 { - fields: [], - append, - remove, - } = useFieldArray({ - control: form.control, - name: "", - }); - -return ( - <> + return ( <ContentsDiv> <div className="grid grid-cols-4 gap-4"> <div className="col-span-4"> @@ -69,7 +71,7 @@ return ( {""} </SelectBox> <SelectBox - className="col-span-2 w-1/3 h-full text-2xl" + className="col-span-2 w-1/3 h-full text-2xl ml-4" label="시군구" selectClass={""} selectArray={selectSgg || []} @@ -79,13 +81,13 @@ return ( </SelectBox> <div className="col-span-5 w-full"> <div className="flex flex-row items-center"> - <Label className="text-xl text-gray-600">수요신청년도</Label> + <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>~</span> + <span className="ml-2 mr-2">~</span> <DatePicker mode={'single'} selected={toDate} onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} /> @@ -100,7 +102,7 @@ return ( }} /> <SearchInput - className={"text-2xl"} + className={"text-2xl ml-4"} label="회사명" textValue={""} setText={(e) => { @@ -148,7 +150,7 @@ return ( <hr /> <Form {...form}> <h3 className="mt-4 ml-2 text-2xl font-medium text-label">수요신청 상세현황</h3> - <h1 className="mt-1 ml-3">표준공사비 산정</h1> + <h1 className="mt-2 ml-3">표준공사비 산정</h1> <div className="flex items-center mx-3 mb-3"> <h1 className="">처리시설 표준공사비 산정</h1> <Button @@ -204,7 +206,7 @@ return ( /> </div> <div className="col-span-3 mt-4"> - <Label className="">용도에 따른 처리공정<i className="diveicon di-search" /></Label> + <Label className="">용도에 따른 처리공정<i className="diveicon di-search" onClick={(e) => setIsPrcsMo({ isModal: true })} /></Label> <FormField control={form.control} @@ -248,7 +250,7 @@ return ( <Label>처리시설용량에 따른 공사비(백만원)</Label> <Button size={"sm"} - onClick={(e) => { }} + onClick={(e) => setIsCmpttnMo({ isModal: true })} className="bg-none" > 공사비 산정표 보기 @@ -277,7 +279,7 @@ return ( <Label>시설부대경비 요율(%)</Label> <Button size={"sm"} - onClick={(e) => { }} + onClick={(e) => setIsTrfMo({ isModal: true })} > 요율표 보기 </Button> @@ -302,7 +304,19 @@ return ( </div> <div className="col-span-3 mt-4"> - <Label>총사업비 (백만원)<i className="diveicon di-search" /></Label> + <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="" @@ -330,7 +344,7 @@ return ( onClick={(e) => { }} className="bg-none" > - 후보지 선택 + 후보지 조회 </Button> </div> <FormField @@ -351,7 +365,7 @@ return ( /> </div> - <div className="col-span-4 mt-4"> + <div className="col-span-4 mt-4 mb-3"> <div className="mt-4"> <Label>관로 표준공사비 산정</Label> </div> @@ -360,8 +374,61 @@ return ( </Form> </ListDiv> </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" }, + + ]} + 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 > - </> -) + ) } \ No newline at end of file diff --git a/apps/wr/app/matMng/coMng/coSttn/page.tsx b/apps/wr/app/matMng/coMng/coSttn/page.tsx new file mode 100644 index 000000000..b664147f5 --- /dev/null +++ b/apps/wr/app/matMng/coMng/coSttn/page.tsx @@ -0,0 +1,262 @@ +"use client"; + +import { useWrStore } from "@/app/store"; +import { btnClass } from "@/app/store/common/code"; +import { + excelDownload, + getCity, + getCityOrSgg, + tableData, +} from "@/components/lib/func/commom"; +import { + ContentsDiv, + SearchDiv, + SearchFormLeft, + SearchFormRight, + SearchInput, + SelectBox, + Title, + UiModal, + UiTable, + type SelectDataType, +} from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button } from "@common/components/ui"; +import { useCallback, useEffect, useState } from "react"; +import SdmInsertForm, { +} from "@common/business_components/ui/sdmInsertForm"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import toast, { Toaster } from "react-hot-toast"; +import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; +import { fetchType, getFetch } from "@/components/lib/api"; +import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form"; + +export default function CoSttn() { + const { + code, + coSttn, + coSttnInit, + coSttnSearch, + getDemandCompList, + regDemandCompany, + updateDemandCompany, + coSttnTxtSearch, + checkDemand, + demandCompList, + dmdIsSucees + } = useWrStore((state) => state); + + const [bdstTable, setBdstTable] = useState<DemandCompType[]>(); + const [pageNation, setPageNation] = useState(1); + const { coSttnRes } = coSttn; + const [isDmdModal, setIsDmdModal] = useState<{ + isMoal: boolean; + data: DemandCompType; + }>({ isMoal: false, data: {} as DemandCompType }); + const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(); + const [objSearch, setObjSearch] = useState<objSearchType>({ + sgg: "", + city: "", + }); + + const [seartchTxt, setSearchTxt] = useState<string>(); + const [upadateData, setUpdateData] = useState<DemandCompType>(); + + + 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 getSgg = (val: string | number) => { + setObjSearch({ ...objSearch, sgg: String(val) }); + }; + + useEffect(() => { + if (!coSttn.isInit) { + + console.log('coSttn.isInit ', coSttn.isInit) + coSttnInit("1", "13", "0"); + } + }, [coSttn.isInit, coSttnInit, objSearch]); + + useEffect(() => { + if (coSttnRes?.length > 0 && code.cityCd.length > 0) { + const data = tableData(coSttnRes, { code }); + const chData = data.map((item: any) => ({ + ...item, + })); + // .filter((item: any) => item !== undefined); + setBdstTable(chData); + } else if (coSttnRes.length == 0) { + setBdstTable([]); + } + }, [coSttnRes]); + + useEffect(() => { + if (coSttn.excelList.length > 0) { + if (coSttn.excelList.length === 0) return; + excelDownload( + coSttn.excelList, + "수요처 관리", + "sample_coSttn.xlsx", + "A1:F1", + 2 + ); + } + }, [coSttn.excelList]); + + const excelClick = useCallback(() => { + const con = objSearch.sgg ? objSearch.sgg : objSearch.city; + if (con) coSttnSearch("1", "10000", String(con)); + }, [coSttnSearch, objSearch.city, objSearch.sgg]); + + const searchClick = () => { + const con = objSearch.sgg ? objSearch.sgg : objSearch.city; + if (con) { + if (seartchTxt && seartchTxt?.length > 0) { + coSttnTxtSearch("1", "13", String(con), seartchTxt ?? ""); + } else { + coSttnSearch("1", "13", String(con)); + } + } + }; + 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="col-span-2 w-1/6 h-full text-2xl" + label="시도" + selectClass={""} + selectArray={code.cityCd || []} + onSelectValue={getSelCity} + /> + <SelectBox + className="col-span-2 w-1/6 h-full text-2xl" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <SearchInput + className={"!text-3xl"} + label="회사명" + textValue={seartchTxt ?? ""} + 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="flex flex-row space-x-2"> + <Button size={"sm"} onClick={searchClick}> + 조회 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { + + setUpdateData(undefined); + setIsDmdModal({ ...isDmdModal, isMoal: true }); + }} + > + 등록 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { + /* 저장 로직 */ + if (!upadateData) { + <ToastFormUi body={"수요처 변경을 원하는 행을 선택해주세요"} title={"수요처관리"}></ToastFormUi>; + }else{ + setIsDmdModal({ + ...isDmdModal, + isMoal: true}) + } + }} + > + 저장 + </Button> + <Button + size={"sm"} + className={`${btnClass} green`} + onClick={excelClick} + > + 다운로드 + </Button> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={[]} + tableData={bdstTable || []} + headlist={coSttn.coSttHeadList} + pageSize={20} + total={10000} + cellClick={(index: number | undefined, headId: string) => { + setUpdateData(coSttnRes[index as number]); + }} + onPageChange={setPageNation} + ></UiTable> + </ListDiv> + </div> + </div> + <UiModal + bodyClass={"w-[40vw] max-w-none h-[90vh]"} + open={isDmdModal.isMoal} + onOpenChange={() => { + setIsDmdModal({ isMoal: false, data: {} as DemandCompType }); + }} + body={ + <SdmInsertForm + selectSidoData={code.cityCd} + selectSigunData={code.sggCd} + dataList={demandCompList} + rtnValue={(searchText: string, pageCnt: number) => { + getDemandCompList(searchText, pageCnt); + }} + rtnInputData={ async(data) => { + if(upadateData?.dmdInfoPk){ + updateDemandCompany(data as DemandCompType) + }else{ + const dmd= await getFetch(fetchType.WR,`/reuseFc/request/${data.dmdInfoPk}`) + if(dmd) { + toast.error(`사업자번호 ${dmd.dmdInfoPk}는 이미 등록되었습니다. 다시등록해주세요`) + return + } + regDemandCompany(data as DemandCompType); + } + if(dmdIsSucees ==='success'){ + toast.success(`수요처 등록 및 수정 완료되었습니다..`) + setIsDmdModal({ isMoal: false, data: data as DemandCompType }); + }else{ + toast.error(`수요처 등록 및 수정 에러입니다.`) + } + + }} + bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"} + updateList={upadateData} + ></SdmInsertForm> + } + ></UiModal> + </ContentsDiv> + <Toaster position="top-center" /> + </> + ); +} diff --git a/apps/wr/app/matMng/coMng/drgtSttn/page.tsx b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx new file mode 100644 index 000000000..77bbe4a5a --- /dev/null +++ b/apps/wr/app/matMng/coMng/drgtSttn/page.tsx @@ -0,0 +1,132 @@ +"use client"; +import { useWrStore } from "@/app/store"; +import { btnClass } from "@/app/store/common/code"; +import type { customCoSttnBdst } from "@/app/store/matDmd/coSttn"; +import { drgtHeadListExport } from "@/app/store/matDmd/drgtSttn/headList"; +import { excelDownload, getCity } from "@/components/lib/func/commom"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import { ContentsDiv, SearchDiv, SearchFormLeft, SearchFormRight, SelectBox, Title, UiTable, type SelectDataType } from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button, DatePicker, Label } from "@common/components/ui"; +import { useCallback, useState } from "react"; + +export default function DrgtSttn() { + const { code, } = useWrStore((state) => state); + const [fromDate, setFromDate] = useState<Date>(new Date()); + const [toDate, setToDate] = useState<Date>(new Date()); + const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(); + const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); + + 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 getSgg = (val: string | number) => { + console.log(val); + setObjSearch({ ...objSearch, sgg: String(val) }) + }; + + const excelClick = useCallback(() => { + excelDownload( + [[]], + "우리동네가뭄", + "sample_drgtSttn.xlsx", + "A1:H1" + ); + }, []); + 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="col-span-2 w-1/6 h-full text-2xl" + label="시도" + selectClass={""} + selectArray={code.cityCd || []} + onSelectValue={getSelCity} + /> + <SelectBox + className="col-span-2 w-1/6 h-full text-2xl" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <div className="col-span-5 w-auto"> + <div className="flex flex-row items-center"> + <Label className="text-xl text-gray-600">조회기간</Label> + <div className="flex flex-row w-1/4"> + <DatePicker mode={'single'} + selected={fromDate} + onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }} /> + <span>~</span> + <DatePicker mode={'single'} + selected={toDate} + onSelect={(date: Date | undefined) => { if (date) setToDate(date) }} /> + </div> + </div> + </div> + </div> + </SearchFormLeft> + <SearchFormRight + className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> + <div className="flex flex-row space-x-2"> + <Button + size={"sm"} + onClick={(e) => { }} + > + 조회 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { }} + > + 상세보기 + </Button> + <Button + size={"sm"} + className={`${btnClass} green`} + onClick={excelClick} + > + 다운로드 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { }} + > + 지도보기 + </Button> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={[]} + tableData={[]} + headlist={drgtHeadListExport} + pageSize={20} + total={10000} + cellClick={(index: number | undefined, headId: string) => { }} + onPageChange={() => { }} + ></UiTable> + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx new file mode 100644 index 000000000..d4039eb9d --- /dev/null +++ b/apps/wr/app/matMng/coMng/ldrmntCoSttn/page.tsx @@ -0,0 +1,196 @@ +"use client"; + +import { useWrStore } from "@/app/store"; +import { btnClass } from "@/app/store/common/code"; +import type { customLdrmntBdst } from "@/app/store/matDmd/ldrmntCoSttn"; +import { ldrmntNodeListExport } from "@/app/store/matDmd/ldrmntCoSttn/headList"; +import { + excelDownload, + getCity +} from "@/components/lib/func/commom"; +import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcel"; +import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; +import LdrmntExcelModal from "@/components/ui/modal/ldrmntSttn/ldrmntExcelModal"; +import CoDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/coDatailModal"; +import { + ContentsDiv, + SearchDiv, + SearchFormLeft, + SearchFormRight, + SearchInput, + SelectBox, + Title, + UiModal, + UiTable, + type ReturnType, + type SelectDataType +} from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button } from "@common/components/ui"; +import { useCallback, useRef, useState } from "react"; + +export default function LdrmntCoSttn() { + const { code, ldrmnt } = useWrStore( + (state) => state + ); + const { ldrmntCoList } = ldrmnt; + const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customLdrmntBdst | undefined }>({ data: undefined, isOpen: false }) + const [pageNation, setPageNation] = useState(1); + const [isRegExcel, setIsRegExcel] = useState(false); + const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() + const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); + const [bdstTable, setBdstTable] = useState<customLdrmntBdst[]>(); + const ref = useRef<ReturnType>({} as ReturnType); + + const excelClick = useCallback(() => { + excelDownload( + [[]], + "잠재수요처 관리", + "sample_ldrmnt.xlsx", + "A1:AL1", + 2 + ); + }, []); + + const [isExcelOpen, setIsExcelOPen] = useState<{ + isModal: boolean; + }>({ isModal: false}); + + const cellClick = (index: number | undefined, headId: string) => { + if (index !== undefined) { + setDetailModal({ isOpen: true, data: ldrmntCoList[index] }); + } + console.log("detailModal", detailModal); + + } + + 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 getSgg = (val: string | number) => { + console.log(val); + setObjSearch({ ...objSearch, sgg: String(val) }) + }; + + 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="col-span-2 w-1/6 h-full text-2xl" + label="시도" + selectClass={""} + selectArray={code.cityCd || []} + onSelectValue={getSelCity} + /> + <SelectBox + className="col-span-2 w-1/6 h-full text-2xl ml-4" + label="시군구" + selectClass={""} + selectArray={selectSgg || []} + onSelectValue={getSgg} + /> + <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="flex flex-row space-x-2"> + <Button + size={"sm"} + onClick={(e) => { }} + > + 조회 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { + setIsExcelOPen({ ...isExcelOpen, isModal: true }); + }} + > + 엑셀등록 + </Button> + <Button + size={"sm"} + className={btnClass} + onClick={() => { + /* 저장 로직 */ + }} + > + 다운로드 + </Button> + <Button + size={"sm"} + className={`${btnClass} green`} + onClick={excelClick} + > + 양식받기 + </Button> + </div> + </SearchFormRight> + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <div className="overflow-x-auto"> + <ListDiv className="min-w-max"> + <UiTable + headName={[]} + tableData={ldrmntCoList || []} + headlist={ldrmntNodeListExport} + pageSize={20} + total={10000} + cellClick={(index: number | undefined, headId: string) => { cellClick(index ?? undefined, headId) }} + onPageChange={setPageNation} + /> + </ListDiv> + </div> + </div> + <UiModal + open={detailModal.isOpen} + onOpenChange={() => { + setDetailModal({ ...detailModal, isOpen: !detailModal.isOpen }) + }} + bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"} + body={<CoDetailModal formObj={detailModal.data} />} + /> + + <UiModal + bodyClass={"w-[40vw] max-w-none"} + open={isRegExcel} + body={<CoRegExcel></CoRegExcel>} + onOpenChange={setIsRegExcel} + /> + <UiModal + bodyClass={""} + body={<LdrmntExcelModal data={isExcelOpen.data}></LdrmntExcelModal>} + open={isExcelOpen.isModal} + onOpenChange={() => { + setIsExcelOPen({ isModal: false, }); + }} + ></UiModal> + </div> + + </ContentsDiv> + </> + + ) + +} \ No newline at end of file diff --git a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx b/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx deleted file mode 100644 index b7bafc693..000000000 --- a/apps/wr/app/matMng/matDmd/coMatRvw/page.tsx +++ /dev/null @@ -1,409 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { formTableName } from "@/components/lib/class/comClass"; -import { getCity } from "@/components/lib/func/commom"; -import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; -import { ContentsDiv, Form, FormField, FormUi, ScrollArea, 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 { zodResolver } from "@hookform/resolvers/zod"; -import { useEffect, useState } from "react"; -import { useFieldArray, useForm } from "react-hook-form"; -import { z } from "zod"; - - -export default function coMatRvw() { - const { code, coRvw, } = useWrStore((state) => state); - const { coRvwHeadList, } = coRvw; - const [fromDate, setFromDate] = useState<Date>(new Date()); - const [toDate, setToDate] = useState<Date>(new Date()); - const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>() - const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" }); - - - const schema = z.object({ - fcltCpct: z.number().optional(), - }); - - const form = useForm<z.infer<typeof schema>>({ - resolver: zodResolver(schema), - defaultValues: { - fcltCpct: 0, - } - }); - - 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 getSgg = (val: string | number) => { - console.log(val); - setObjSearch({ ...objSearch, sgg: String(val) }) - }; - - const { - fields: [], - append, - remove, - } = useFieldArray({ - control: form.control, - name: "", - }); - - useEffect(() => { - if (fromDate > toDate) { - const newFromDate = new Date(toDate); - newFromDate.setDate(toDate.getDate() - 1); - setFromDate(newFromDate); - } - }, [toDate]); - - 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 - className="col-span-2 w-1/3 h-full text-2xl" - label="시군구" - selectClass={""} - selectArray={selectSgg || []} - onSelectValue={getSgg} - /> - <div className="col-span-5 w-full"> - <div className="flex flex-row items-center"> - <Label className="text-xl text-gray-600">수요신청년도</Label> - <div className="flex flex-row"> - <DatePicker mode={'single'} - selected={fromDate} - onSelect={(date: Date | undefined) => { if (date) setFromDate(date) }} /> - <span>~</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) => { - }} - /> - </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> - </div> - </div> - </SearchFormRight> - </SearchDiv> - </div> - </div> - - <div className="grid grid-cols-6 gap-4 "> - <div className="col-span-6"> - <ListDiv> - <UiTable - headName={"수요매칭검토현황"} - tableData={[]} - children={undefined} - headlist={coRvwHeadList} - 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> - <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" /></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) => { }} - 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) => { }} - > - 요율표 보기 - </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>총사업비 (백만원)<i className="diveicon di-search" /></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"> - <div> - <FormField - control={form.control} - name="" - 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"> - <FormField - control={form.control} - name="" - render={({ field }) => ( - <Label className="text-xl">처리시설 + 공급관로 총사업비(백만원) - <FormUi label=""> - <Input - placeholder="" - type="text" - step="0.001" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - readOnly={true} - value={field.value ?? 0} - /> - </FormUi> - </Label> - )} - /> - </div> - </div> - </div> - </Form> - </ListDiv> - </div> - </div> - </ContentsDiv > - </> - ) -} \ No newline at end of file diff --git a/apps/wr/app/matMng/matDmd/coReg/page.tsx b/apps/wr/app/matMng/matDmd/coReg/page.tsx deleted file mode 100644 index b0f911449..000000000 --- a/apps/wr/app/matMng/matDmd/coReg/page.tsx +++ /dev/null @@ -1,84 +0,0 @@ -"use client"; -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import * as z from "zod"; -import { - Form, - FormField, - FormUi, - ScrollArea, - SelectBox, -} from "@common/business_components/ui"; -import { Button } from "@common/components/ui"; -import { CoRegForm } from "@/components/ui/form/matDmd/coRegForm/component"; -import toast, { Toaster } from "react-hot-toast"; -import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; - -const formSchema = z.object({ - ctpv: z.string(), - sgg: z.string(), - coNm: z.string().min(1).max(20), - bznmNo: z.string().min(1).min(9).max(12), - addr: z.string().min(1).min(6).max(20), - telNo: z.string().min(8).max(12), - -}); - -export default function MyForm() { - - - - const form = useForm<z.infer<typeof formSchema>>({ - resolver: zodResolver(formSchema), - defaultValues: { - coNm:'', - bznmNo:'', - addr:'', - telNo:'', - }, - }); - - function onSubmit(values: z.infer<typeof formSchema>) { - try { - toast.dismiss(); - //ToastFormUi("수요신청 화면으로 이동하시겠습니까?", "수요처 등록 완료", "./dmdReg", "이동") - - } catch (error) { - console.error("Form submission error", error); - toast.error("수요처 등록이 실패하였습니다."); - } - } - - return ( - <> - <div className="grid h-40 grid-cols-3 place-content-center"> - <h1 className=" col-start-2 col-span-1 text-4xl underline"> - 수요처 정보입력 - </h1> - </div> - - <div className="grid grid-cols-5 gap-4 overflow-hidden"> - <div className="col-span-1 "/> - <div className="col-span-3 "> - <div> - <Form {...form}> - <form - onSubmit={form.handleSubmit(onSubmit)} - className="space-y-8 max-w-3xl mx-auto" - > - <CoRegForm>{form}</CoRegForm> - - - <Button type="submit">수요처등록</Button> - </form> - </Form> - </div> - </div> - <div className="col-span-1 " > - <Toaster position="top-center" /> - </div> - </div> - </> - ); -} - diff --git a/apps/wr/app/matMng/matDmd/coSttn/page.tsx b/apps/wr/app/matMng/matDmd/coSttn/page.tsx deleted file mode 100644 index 06f624a65..000000000 --- a/apps/wr/app/matMng/matDmd/coSttn/page.tsx +++ /dev/null @@ -1,107 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { Button } from "@common/components/ui"; -import { btnClass } from "@/app/store/common/code"; -import ListDiv from "@common/business_components/ui/list_div"; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import type { customCoBdst } from "@/app/store/matDmd/coReg"; -import { - ContentsDiv, - SearchBaseForm, - Title, - UiModal, - UiTable, - type ReturnType, -} from "@common/business_components/ui"; -import { useCallback, useEffect, useRef, useState } from "react"; - - -export default function coSttn() { - const [bdstTable, setBdstTable] = useState<customCoBdst[]>(); - const [pageNation, setPageNation] = useState(1); - const { code, coSttn } = useWrStore( - (state) => state - ); - - const ref = useRef<ReturnType>({} as ReturnType); - - const excelClick = useCallback(() => { - }, []); - - return( - <> - <ContentsDiv> - <div className="grid grid-cols-4 gap-4 "> - <div className="col-span-4"> - <Title title={"수요처 관리"} /> - <SearchBaseForm - selectSidoData={code.cityCd} - selectSigunData={code.sggCd} - selectRegionData={code.rvbsnCd} - selectUnitWaterShedData={code.lgbsnCd} - selectMiddleRegionData={code.mdmbsnCd} - selectEnvPartData={code.lclgvrnmntCd} - rightChildren={ - <div> - <Button - className={btnClass} - onClick={() => { - /* 등록 로직 */ - }} - > - 등록 - </Button> - <Button - className={btnClass} - onClick={() => { - /* 저장 로직 */ - }} - > - 저장 - </Button> - </div> - } - leftChildren={undefined} - 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; - } - // coSttnSearch(1, "20", con); - }} - excelClick={excelClick} - initClick={function (): void {}} - btnClass={btnClass} - ref={ref} - /> - </div> - </div> - <div className="grid grid-cols-6 gap-4 "> - <div className="col-span-6"> - <ListDiv> - <UiTable - headName={[]} - tableData={bdstTable || []} - children={ - <HeadMakeColSpan upHeadList={coSttn.coSttNodeList} /> - } - headlist={coSttn.coSttHeadList} - pageSize={20} - total={10000} - cellClick={(index: number | undefined,headId:string)=>{} } - onPageChange={setPageNation} - ></UiTable> - </ListDiv> - </div> - </div> - - </ContentsDiv> - </> - - ) - -} \ No newline at end of file diff --git a/apps/wr/app/matMng/matDmd/dmdReg/page.tsx b/apps/wr/app/matMng/matDmd/dmdReg/page.tsx deleted file mode 100644 index 75918d021..000000000 --- a/apps/wr/app/matMng/matDmd/dmdReg/page.tsx +++ /dev/null @@ -1,106 +0,0 @@ -"use client"; -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import * as z from "zod"; -import { Form } from "@common/business_components/ui"; -import { Button } from "@common/components/ui"; -import { DmdRegForm } from "@/components/ui/form/matDmd/dmdRegform/component"; -import toast, { Toaster } from "react-hot-toast"; -import { useRouter } from "next/navigation"; - -const formSchema = z.object({ - dmdSel: z.string().min(1), - dmdTmng: z.coerce.date(), - dmdWq: z.string().min(1).optional(), - useUsgCd: z.string(), - wntUntprc: z.string().min(1), - grssClfg: z.string().min(1), - tn: z.string().min(1).optional(), - combResdch: z.string().min(1).optional(), - tp: z.string().min(1).optional(), - trbt: z.string().min(1).optional(), - ph: z.string().min(1).optional(), - bod: z.string().min(1).optional(), - clIonQnt: z.string().min(1).optional(), - smll: z.string().min(1).optional(), - cdtnv: z.string().min(1).optional(), - crmty: z.string().min(1).optional(), - rmrk: z.string().min(1).optional(), - sply1: z.string().min(1).optional(), - sply2: z.string().min(1).optional(), - sply3: z.string().min(1).optional(), - password: z.string().min(1), -}); - -export default function MyForm() { - const form = useForm<z.infer<typeof formSchema>>({ - resolver: zodResolver(formSchema), - defaultValues: { - dmdSel:'', - dmdTmng: new Date(), - dmdWq: "", - useUsgCd: "", - wntUntprc: "", - grssClfg: "", - tn: "", - combResdch: "", - tp: "", - trbt: "", - ph: "", - bod: "", - clIonQnt: "", - smll: "", - cdtnv: "", - crmty: "", - rmrk: "", - sply1: "", - sply2: "", - sply3: "", - password: "", - }, - }); - - const router = useRouter(); - - async function onSubmit(values: z.infer<typeof formSchema>) { - try { - - toast.success("✅ 수요신청이 완료되었습니다."); - await new Promise((resolve) => setTimeout(resolve, 3000)); - router.push("../../") - } catch (error) { - toast.error("수요신청을 다시입력해주시길 바랍니다."); - } - } - - return ( - <> - <div className="grid h-40 grid-cols-3 place-content-center"> - <h1 className=" col-start-2 col-span-1 text-4xl underline"> - 수요 신청정보입력 - </h1> - </div> - - <div className="grid grid-cols-5 gap-4 overflow-hidden"> - <div className="col-span-1 " /> - <div className="col-span-3 max-h-[78vh] overflow-y-scroll "> - <div> - <Form {...form}> - <form - onSubmit={form.handleSubmit(onSubmit)} - className="space-y-8 max-w-3xl mx-auto" - > - <DmdRegForm> {form}</DmdRegForm> - - <Button type="submit"> 수요신청</Button> - </form> - </Form> - </div> - </div> - <div className="col-span-1 "> - <Toaster position="top-center" /> - </div> - </div> - </> - ); -} diff --git a/apps/wr/app/matMng/matDmd/ldrmntCoSttn/page.tsx b/apps/wr/app/matMng/matDmd/ldrmntCoSttn/page.tsx deleted file mode 100644 index b6e5ccb7e..000000000 --- a/apps/wr/app/matMng/matDmd/ldrmntCoSttn/page.tsx +++ /dev/null @@ -1,147 +0,0 @@ -"use client"; - -import { useWrStore } from "@/app/store"; -import { Button } from "@common/components/ui"; -import { btnClass } from "@/app/store/common/code"; -import ListDiv from "@common/business_components/ui/list_div"; -import { - tableData, -} from "@/components/lib/func/commom"; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; -import type { customCoBdst } from "@/app/store/matDmd/coReg"; -import { - ContentsDiv, - SearchBaseForm, - Title, - UiModal, - UiTable, - type ReturnType, -} from "@common/business_components/ui"; -import CoDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/coDatailModal"; -import CoRegExcel from "@/components/ui/modal/coReg/coRegExcel/coRegExcel"; -import { useCallback, useEffect, useRef, useState } from "react"; - -export default function ldrmntCoSttn() { - const { code, ldrmntCoSttn } = useWrStore( - (state) => state - ); - const { ldrmntCoSttnRes } = ldrmntCoSttn; - const [bdstTable, setBdstTable] = useState<customCoBdst[]>(); - const [detailModal, setDetailModal] = useState<{isOpen:boolean,data:customCoBdst|undefined}>({data:undefined,isOpen:false }) - const [pageNation, setPageNation] = useState(1); - const [isRegExcel, setIsRegExcel] = useState(false); - - const ref = useRef<ReturnType>({} as ReturnType); - - const excelClick = useCallback(() => { - }, []); - - const cellClick=(index:number|undefined, headId: string)=>{ - if(index!==undefined && bdstTable!==undefined){ - setDetailModal({isOpen:true ,data:bdstTable[index] }) - } - } - - useEffect(() => { - if (ldrmntCoSttnRes.length > 0 && code.cityCd.length > 0) { - const data = tableData(ldrmntCoSttnRes, { code }); - console.log("data", data); - const chData = data - .map((item: any) => ({ - ...item - - })) - .filter((item: any) => item !== undefined); - - setBdstTable(chData); - } - }, [code, ldrmntCoSttnRes, ldrmntCoSttn.ldrmntCoSttHeadList]); - - return( - <> - <ContentsDiv> - <div className="grid grid-cols-4 gap-4 "> - <div className="col-span-4"> - <Title title={"잠재수요처 관리"} /> - <SearchBaseForm - selectSidoData={code.cityCd} - selectSigunData={code.sggCd} - selectRegionData={code.rvbsnCd} - selectUnitWaterShedData={code.lgbsnCd} - selectMiddleRegionData={code.mdmbsnCd} - selectEnvPartData={code.lclgvrnmntCd} - rightChildren={ - <div> - <Button - className={btnClass} - onClick={() => setIsRegExcel(!isRegExcel)} - > - 엑셀등록 - </Button> - <Button - className={btnClass} - onClick={() => { - // 저장 로직 - }} - > - 양식받기 - </Button> - </div> - } - leftChildren={undefined} - 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; - } - // ldrmntCoSttnSearch(1, "20", con); - }} - excelClick={excelClick} - initClick={function (): void {}} - btnClass={btnClass} - ref={ref} - /> - </div> - </div> - <div className="grid grid-cols-6 gap-4 "> - <div className="col-span-6"> - <ListDiv> - <UiTable - headName={[]} - tableData={bdstTable || []} - children={ - <HeadMakeColSpan upHeadList={ldrmntCoSttn.ldrmntCoSttNodeList} /> - } - headlist={ldrmntCoSttn.ldrmntCoSttHeadList} - pageSize={20} - total={10000} - cellClick={(index: number | undefined,headId:string)=>{cellClick(index ?? undefined,headId)} } - onPageChange={setPageNation} - ></UiTable> - </ListDiv> - </div> - <UiModal - open={detailModal.isOpen} - onOpenChange={()=>{ - setDetailModal({...detailModal, isOpen:!detailModal.isOpen}) - }} - bodyClass={"w-[40vw] max-w-none max-h-[calc(100%-70px)]"} - body={<CoDetailModal formObj={detailModal.data}/>}/> - - <UiModal - bodyClass={"w-[40vw] max-w-none"} - open={isRegExcel} - body={<CoRegExcel></CoRegExcel>} - onOpenChange={setIsRegExcel} - /> - </div> - - </ContentsDiv> - </> - - ) - -} \ No newline at end of file diff --git a/apps/wr/app/page.tsx b/apps/wr/app/page.tsx index ff6ef558d..5e1cd2333 100644 --- a/apps/wr/app/page.tsx +++ b/apps/wr/app/page.tsx @@ -48,6 +48,13 @@ export default function Home() { </Link> </Button> </div> + <div className="col-span-2"> + <Button className="w-full"> + <Link href="ruseFcltMng/prfmncSttn/pbnstPrfmncSttn"> + 하수재이용실적 현황 + </Link> + </Button> + </div> <div className="col-span-2"> <Button className="w-full"> <Link href="ruseFcltMng/prfmncReg/chkgdnReg"> @@ -102,19 +109,20 @@ export default function Home() { <div> <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/matDmd/coReg">수요처 등록</Link> + <Link href="matMng/coMng/coSttn">수요처 관리</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/coSttn">수요처 관리</Link> + <Link href="matMng/coMng/ldrmntCoSttn">잠재수요처 관리</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/ldrmntCoSttn">잠재수요처 관리</Link> + <Link href="matMng/coMng/drgtSttn">우리동네가뭄</Link> </Button> </div> </div> @@ -126,12 +134,38 @@ export default function Home() { <div className="grid grid-cols-12 gap-4"> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/coMatRvw">수요처 매칭 검토</Link> + <Link href="matMng/coMat/coMatRvw">수요처 매칭 검토</Link> </Button> </div> <div className="col-span-2"> <Button className="w-full"> - <Link href="matMng/matDmd/ruseRvwHstry">재이용검토이력</Link> + <Link href="matMng/coMat/ruseRvwHstry">재이용검토이력</Link> + </Button> + </div> + <div className="col-span-2"> + <Button className="w-full"> + <Link href="matMng/coMat/ruseCaseMng">물재이용사례 관리</Link> + </Button> + </div> + </div> + </div> + {/* 통계*/} + <div> + <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> + </div> + <div className="col-span-2"> + <Button className="w-full"> + <Link href="stats/rswtStat">중수도시설통계</Link> + </Button> + </div> + <div className="col-span-2"> + <Button className="w-full"> + <Link href="stats/matStat">물재이용사례 관리</Link> </Button> </div> </div> diff --git a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx index c0d6d4377..8cb85e9fb 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/htdflReg/page.tsx @@ -20,7 +20,6 @@ import HtdflRegForm from "@/components/ui/form/fcltReg/htdflReg/htdflRegForm"; import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; -import { headMakeColSpan } from "../rainReg/TableHead"; import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; export default function Home() { diff --git a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx index 86dce20d6..c5b1629e6 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/pbnstReg/page.tsx @@ -9,7 +9,7 @@ import { UiModal, UiTable, } from "@common/business_components"; -import { Button, Input } from "@common/components"; +import { Button } from "@common/components"; import { useWrStore } from "../../../store"; import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; import { useEffect, useState } from "react"; @@ -17,14 +17,11 @@ import ListDiv from "@common/business_components/ui/list_div"; import { tableData } from "@/components/lib/func/commom"; import type { customPbnst, - fcBizSchema, fcBizType, pubHasuType, - ruseFcltType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; -import { z } from "zod"; import { PbnstRegModal } from "@/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal"; import { Toaster } from "react-hot-toast"; import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; @@ -52,7 +49,6 @@ export default function PublicReuseFaciltyInsert() { const [searchTxt, setSearchTxt] = useState<string>(); const [bdstTable, setbdstTable] = useState<pubHasuType[]>(); - const [selectBdst, setSelectBdst] = useState<customPbnst | null>(null); useEffect(() => { @@ -75,11 +71,9 @@ export default function PublicReuseFaciltyInsert() { await pbnstRuseFcltUpdate(data) - console.log('bizs ', bizs) await pbnstRuseBizUpdate(bizs) - console.log(' data ', data) } @@ -99,6 +93,7 @@ export default function PublicReuseFaciltyInsert() { if (selectRow) { setIsRuseReg({ ...isRuseReg, data: selectRow }); pbnstRegClick(selectRow); + } }; diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/TableHead.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/TableHead.tsx index 39137d364..9dd67dc44 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rainReg/TableHead.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rainReg/TableHead.tsx @@ -1,7 +1,7 @@ -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import { TableRow, TableHead } from "@common/components/ui"; -export const headMakeColSpan = (upHeadList: TableUpperProps[]) => { +export const makeFcltRegHead = (upHeadList: TableUpperProps[]) => { return ( <> <TableRow> diff --git a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx index ea51326ef..534d3e340 100644 --- a/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltReg/rswtReg/page.tsx @@ -19,7 +19,7 @@ import { tableData } from "@/components/lib/func/commom"; import RswtrRegForm from "@/components/ui/form/fcltReg/rswtrReg/rswtrRegForm"; import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; import type { chgBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { headMakeColSpan } from "../rainReg/TableHead"; +import { makeFcltRegHead } from "../rainReg/TableHead"; import { BdstReg } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal"; export default function Home() { diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx index f2ab7c06d..e8362edbe 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/htdflSttn/page.tsx @@ -21,7 +21,7 @@ import { type ReturnType, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; +import { makeFcltRegHead } from "@common/business_components/ui/table/makeFcltRegHead"; import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal"; import BdstChgModal from "@/components/ui/modal/fcltReg/bdstChgModal/bdstChgModal"; import { Button } from "@common/components/ui"; @@ -155,7 +155,7 @@ export default function HtdflSttn() { headName={[]} tableData={bdstTable || []} children={ - <HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} /> + <makeFcltRegHead upHeadList={htdflSttn.htdflSttNodeList} /> } headlist={htdflSttn.htdflSttHeadList} pageSize={20} diff --git a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx index 837cf23f1..3f6ad7566 100644 --- a/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx +++ b/apps/wr/app/ruseFcltMng/fcltSttn/pbnstSttn/page.tsx @@ -4,39 +4,114 @@ import { btnClass } from "@/app/store/common/code"; import { ContentsDiv, SearchBaseForm, + SearchInput, + SelectBox, Title, UiModal, UiTable, type ReturnType, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button } from "@common/components/ui"; +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 } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import { excelDownload, getCityOrSgg } from "@/components/lib/func/commom"; +import type { + customPbnst, + pubHasuType, +} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { + excelDownload, + getCityOrSgg, + 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"; export default function PbnstSttn() { - const { code, pbnstSttn, pbnstSttnSearch } = useWrStore((state) => state); + const { + code, + pbnstSttn, + pbnstSttnSearch, + pbnSttnInit, + getPbnStnDetail, + pbnNmSearch, + } = useWrStore((state) => state); const ref = useRef<ReturnType>({} as ReturnType); const codeData = getCityOrSgg(ref); + const [searchYear, setSearchYear] = useState<string>( + String(new Date().getFullYear()) + ); const [pageNation, setPageNation] = useState(1); const [isChHead, setIsChHead] = useState(false); - const [bdstTable, setBdstTable] = useState<customPbnst[]>(); + const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>(); + const [pbnDetaileData, setPbnDetaileData] = useState<{ + isModal: boolean; + data: customPbnst; + }>({ isModal: false, data: {} as customPbnst }); + + const [clickPk , setClickPk] = useState<string>("") + const [pbnRuseNm, setPbnRuseNm] = useState<string>(""); + const excelClick = useCallback(() => { - // if (codeData) pbnstSttnSearch(1, "10000", codeData); - excelDownload( - [[]], - "하수재이용시설 현황", - "sample_pbnstSttn.xlsx", - "A1:U2" - ); - }, [pbnstSttnSearch, codeData]); + pbnstSttnSearch("1", "10000", ref.current, "", searchYear); + }, [pbnstSttnSearch, searchYear, ref.current]); + const cellCLick = useCallback( + (index: number | undefined) => { + if ( + index !== undefined && + pbnstSttn.pbnstSttnRes && + pbnstSttn.pbnstSttnRes[index] + ) { + const pbnstRuseFcltPk = pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltPk; + // setClickPk(pbnstRuseFcltPk) + getPbnStnDetail(pbnstRuseFcltPk); + } + }, + [getPbnStnDetail, pbnstSttn.pbnstSttnRes] + ); + + useEffect(() => { + if (pbnstSttn.excelList.length >= 0) { + excelDownload( + pbnstSttn.excelList, + "하수재이용시설 현황", + "sample_pbnstSttn.xlsx", + "A1:U2" + ); + } + }, [pbnstSttn.excelList]); + useEffect(() => { + if (!pbnstSttn.isInit) { + pbnSttnInit("1", "13", ref.current, searchYear); + } + }, [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(() => { + if (pbnstSttn.pbnstDetail.pbnstRuseFcltPk) + setPbnDetaileData({ + isModal: true, + data: pbnstSttn.pbnstDetail, + }); + }, [pbnstSttn.pbnstDetail]); + + + useEffect(() => { + console.log('pbnDetaileData.isModal ', pbnDetaileData.isModal) +},[pbnDetaileData.isModal]) return ( <> <ContentsDiv> @@ -60,7 +135,33 @@ export default function PbnstSttn() { 조회항목설정 </Button> } - leftChildren={undefined} + 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> + </> + } queryClick={function (returnType: ReturnType): void { // '{partValue: 'A', sidoValue: '0', sigunValue: '0', regionValue: '0', unitWaterShedValue: '0', …}' let con; @@ -72,9 +173,10 @@ export default function PbnstSttn() { // pbnstSttnSearch(1, "20", con); }} excelClick={excelClick} - initClick={function (): void { }} + initClick={function (): void {}} btnClass={btnClass} ref={ref} + isAdmin={false} /> </div> </div> @@ -90,7 +192,9 @@ export default function PbnstSttn() { headlist={pbnstSttn.pbnstSttHeadList} pageSize={20} total={100000} - cellClick={(index: number | undefined, headId: string) => { }} + cellClick={(index: number | undefined, headId: string) => { + cellCLick(index); + }} onPageChange={setPageNation} ></UiTable> </ListDiv> @@ -112,6 +216,18 @@ export default function PbnstSttn() { /> } /> + <UiModal + body={ + <PbnstSttnModal + data={pbnDetaileData.data || ({} as customPbnst)} + ></PbnstSttnModal> + } + bodyClass="w-[68vw] max-w-none h-[90vh]" + open={pbnDetaileData.isModal} + onOpenChange={(open) => { + setPbnDetaileData({ data: {} as customPbnst, isModal: false }); + }} + /> </ContentsDiv> </> ); diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx index 130578654..10a0bf85f 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead.tsx @@ -1,5 +1,5 @@ +import type { TableUpperProps } from "@/app/store/common/type/header"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { TableHead, TableRow } from "@common/components/ui"; export const headMakeprfmnc = ( diff --git a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx index c5dce841b..fed0338f0 100644 --- a/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx +++ b/apps/wr/app/ruseFcltMng/prfmncReg/pbnstPrfmncReg/page.tsx @@ -16,44 +16,141 @@ import { UiModal, } from "@common/business_components/ui"; import ListDiv from "@common/business_components/ui/list_div"; -import { Button, Label } from "@common/components/ui"; +import { + Button, + Label, + Table, + TableBody, + TableHeader, +} from "@common/components/ui"; import { useState, useEffect, useCallback } from "react"; import { set } from "react-hook-form"; import { Toaster } from "react-hot-toast"; +import { headMakeprfmnc } from "../chkgdnReg/TableHead"; +import { InputTableBody } from "@/components/lib/func/TableData"; +import { + initValInUsage, + initValOutUsage, + subTotalObj, + totalObj, + type FcPrfType, + type PrfType, +} from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; export default function prfmncPrfmncReg() { - const { code, prfmnc, prfmncHasuInit, } = useWrStore( + const { code, prfmnc, prfmncHasuInit, prfmnRegData } = useWrStore( (state) => state ); const { pbnstPrfmncHeadList, monthHeadList, prfmncRes } = prfmnc; - const [bdstTable, setbdstTable] = useState<pubHasuType[]>(); + const [bdstTable, setbdstTable] = useState<FcPrfType[]>(); const [searchTxt, setSearchTxt] = useState<string>(); - const [isExcelOpen, setIsExcelOPen] = useState<boolean>(false); + const [isExcelOpen, setIsExcelOPen] = useState<{ + isModal: boolean; + data: FcPrfType; + }>({ isModal: false, data: {} as FcPrfType }); + const [inputData, setInputData] = useState<any[]>(); + const [pbnstRuseFcltPk, setPbnstRuseFcltPk] = useState<string>(); const [searchYear, setSearchYear] = useState<string>( String(new Date().getFullYear()) ); + const excelClick = useCallback(() => { + excelDownload( + [[]], + "하수재이용실적", + "sample_pbnstPrfmncReg.xlsx", + "A1:O1" + ); + }, [prfmnc.excelList]); + const onSave = useCallback(() => { + if (pbnstRuseFcltPk) { + prfmnRegData( + excelToPbnPrfData( + inputData as unknown as JSON[], + searchYear, + pbnstRuseFcltPk + ) as unknown as PrfType + ); + prfmncHasuInit("1", "11"); + } + }, [inputData, searchYear, pbnstRuseFcltPk,prfmncHasuInit]); - const excelClick = useCallback(() => { - console.log("dd") - excelDownload( - [[]], - "하수재이용실적", - "sample_pbnstPrfmncReg.xlsx", - "A1:O1" - ); - }, [prfmnc.excelList]) + const cellClick = useCallback( + (index: number | undefined, headId: string) => { + if (index !== undefined) { + setIsExcelOPen({ + isModal: false, + data: prfmncRes[index] || ({} as FcPrfType), + }); + const inUsageData = [...initValInUsage]; + const outUsageData = [...initValOutUsage]; + const inSubtotal = subTotalObj; + const outSubtotal = subTotalObj; + if (prfmncRes[index]?.prfList) { + prfmncRes[index].prfList?.forEach((prfItem) => { + const month = Number(prfItem?.ym?.slice(4)); // "MM" + const monthKey = `${month}월`; - useEffect(() => { - if (!prfmnc.isInit) { - prfmncHasuInit("1", "11"); + inUsageData.forEach((inData: any) => { + const usageKey = inData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + inData[monthKey] = value; + inData.total += value; + + if (inSubtotal && usageKey !== "subtotal") { + (inSubtotal as any)[monthKey] = + ((inSubtotal as any)[monthKey] ?? 0) + value; + inSubtotal.total += value; + } + }); + + outUsageData.forEach((outData: any) => { + const usageKey = outData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + outData[monthKey] = value; + outData.total += value; + + if (usageKey !== "subtotal") { + (outSubtotal as any)[monthKey] = + ((outSubtotal as any)[monthKey] ?? 0) + value; + outSubtotal.total += value; + } + }); + }); + inUsageData.push(inSubtotal); + outUsageData.push(outSubtotal); + const usageTotalObj: { [key: string]: any } = totalObj; + for (const key in usageTotalObj) { + if (["usage", "gubun", "edit"].includes(key)) continue; + const val = + (Number((inSubtotal as any)[key]) || 0) + + (Number((outSubtotal as any)[key]) || 0); + + (usageTotalObj as any)[key] = val; + } + const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; + setPbnstRuseFcltPk(prfmncRes[index].pbnstRuseFcltPk); + setInputData(tableData); + } else { + setInputData([]); } - }, [prfmnc.isInit, prfmncHasuInit]); - useEffect(() => { - setbdstTable(prfmncRes) - console.log("prfmnc.prfmncRes", prfmncRes) - }, [prfmncRes]); + } + }, + [prfmncRes] + ); + + useEffect(() => { + if (!prfmnc.isInit) { + prfmncHasuInit("1", "11"); + } + }, [prfmnc.isInit, prfmncHasuInit]); + useEffect(() => { + setbdstTable(prfmncRes); + }, [prfmncRes]); return ( <> @@ -98,10 +195,20 @@ export default function prfmncPrfmncReg() { <Button size={"sm"} onClick={(e) => {}}> 조회 </Button> - <Button size={"sm"} onClick={() => {}}> + <Button + size={"sm"} + onClick={() => { + onSave(); + }} + > 저장 </Button> - <Button size={"sm"} onClick={() => {setIsExcelOPen(true)}}> + <Button + size={"sm"} + onClick={() => { + setIsExcelOPen({ ...isExcelOpen, isModal: true }); + }} + > 파일등록 </Button> <Button color="green" size={"sm"} onClick={excelClick}> @@ -124,7 +231,9 @@ export default function prfmncPrfmncReg() { pageSize={100} total={10} headName={"하수재이용시설 목록"} - cellClick={() => {}} + cellClick={(index: number | undefined, headId: string) => { + cellClick(index, headId); + }} onPageChange={(page: number) => {}} children={undefined} /> @@ -133,23 +242,33 @@ export default function prfmncPrfmncReg() { </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} - /> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label"> + {"하수처리수재이용 실적(m3) 등록결과"} + </h3> + </div> + + <Table variant="secondary"> + <TableHeader className="font-bold"> + {headMakeprfmnc(monthHeadList, [])} + </TableHeader> + <TableBody> + {InputTableBody(inputData ?? [], monthHeadList, setInputData)} + </TableBody> + </Table> </ScrollArea> </ListDiv> </div> </ContentsDiv> - <UiModal bodyClass={""} body={<PbnPrfExcelModal></PbnPrfExcelModal>} open={isExcelOpen} onOpenChange={() => {setIsExcelOPen(!isExcelOpen)}}></UiModal> + <UiModal + bodyClass={""} + body={<PbnPrfExcelModal data={isExcelOpen.data}></PbnPrfExcelModal>} + open={isExcelOpen.isModal} + onOpenChange={() => { + setIsExcelOPen({ isModal: false, data: {} as FcPrfType }); + }} + ></UiModal> <Toaster position="top-center" /> - </> ); -} \ No newline at end of file +} diff --git a/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx new file mode 100644 index 000000000..cfeddb170 --- /dev/null +++ b/apps/wr/app/ruseFcltMng/prfmncSttn/pbnstPrfmncSttn/page.tsx @@ -0,0 +1,683 @@ +"use client"; + +import { useWrStore } from "@/app/store"; +import { btnClass } from "@/app/store/common/code"; +import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type FcPrfType, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import { yearOptions } from "@/components/lib/func/commom"; +import { InputTableBody } from "@/components/lib/func/TableData"; +import { ContentsDiv, Title, SearchBaseForm, SelectBox, SearchInput, UiTable, type ReturnType, MainChart, type ChartConfig, CHART_FORM, ScrollArea } from "@common/business_components"; +import DoughnutChart from "@common/business_components/ui/chart/DoughnutChart"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button, Label, Table, TableBody, TableHeader } from "@common/components/ui"; +import { useEffect, useRef, useState } from "react"; +import { headMakeprfmnc } from "../../prfmncReg/chkgdnReg/TableHead"; + + + +export default function PbnstPrfmncSttn() { + const { code, tableHeadMaker, pbnstPrfmncSttn, pbnstPrfmncInit, pbnstPrfmncSearch, prfmnc } = useWrStore((state) => state); + const { monthHeadList } = prfmnc + const { pbnstPrfHeadList, pbnstPrfmncRes, prfmncRes, rawData, selectYearList } = pbnstPrfmncSttn; + const [isChHead, setIsChHead] = useState(false); + const [fromDate, setFromDate] = useState<string>(String(new Date().getFullYear())); + const [toDate, setToDate] = useState<string>(String(new Date().getFullYear())); + const [year, setYear] = useState<string>(String(new Date().getFullYear())); + const [bdstTable, setbdstTable] = useState<FcPrfType[]>(); + const ref = useRef<ReturnType>({} as ReturnType); + const [swtrmtFcltNm, setSwtrmtFcltNm] = useState<string>(); + const [chartConfig, setChartConfig] = useState<ChartConfig>({}); + const [chartData, setChartData] = useState<dnChartForm[]>([]); + const [dnInUsage, setDnInUsage] = useState<dnChartForm[]>([]); + const [dnInChartConfig, setDnInChartConfig] = useState<ChartConfig>({}); + const [dnOutUsage, setDnOutUsage] = useState<dnChartForm[]>([]); + const [dnOutChartConfig, setDnOutChartConfig] = useState<ChartConfig>({}); + const [barData, setBarData] = useState<barChartForm[]>([]); + const [barChartConfig, setBarChartConfig] = useState<ChartConfig>({}); + const [prfData, setPrfData] = useState<any[]>(); + const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({}); + const [lnOutChartConfig, setLnOutChartConfig] = useState<ChartConfig>({}); + const [inLineData, setInLineData] = useState<{ + chartData1: lineChartDataProps[]; + chartData2: lineChartDataProps[]; + chartData3: lineChartDataProps[]; + chartData4: lineChartDataProps[]; + chartData5: lineChartDataProps[]; + chartData6: lineChartDataProps[]; + chartData7: lineChartDataProps[]; + chartData8: lineChartDataProps[]; + chartData9: lineChartDataProps[]; + }>(); + // const [lnInChartConfig, setLnInChartConfig] = useState<ChartConfig>({}); + const [outLineData, setOutLineData] = useState<{ + chartData1: lineChartDataProps[]; + chartData2: lineChartDataProps[]; + chartData3: lineChartDataProps[]; + chartData4: lineChartDataProps[]; + chartData5: lineChartDataProps[]; + chartData6: lineChartDataProps[]; + }>(); + + + + type dnChartForm = { label: string, val: number, fill?: string }; + type barChartForm = { label: string, "장내용수": number, "장외용수": number }; + type lineChartDataProps = { label: string, val: number, color: string }; + + const prfTableData = (prfList: PrfType[], year:string) => { + const inUsageData = initValInUsage; + const outUsageData = initValOutUsage; + + const inSubtotal = subTotalObj; + const outSubtotal = subTotalObj; + + + const prfFilter = prfList?.filter((e) => e.ym.slice(0, 4) === year) + if (prfList && prfFilter.length > 0) { + prfList?.forEach((prfItem) => { + const month = Number(prfItem?.ym?.slice(4)); // "MM" + const monthKey = `${month}월`; + + inUsageData.forEach((inData: any) => { + const usageKey = inData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + inData[monthKey] = value; + inData.total += value; + + if (inSubtotal && usageKey !== "subtotal") { + (inSubtotal as any)[monthKey] = + ((inSubtotal as any)[monthKey] ?? 0) + value; + inSubtotal.total += value; + } + }); + + outUsageData.forEach((outData: any) => { + const usageKey = outData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + outData[monthKey] = value; + outData.total += value; + + if (usageKey !== "subtotal") { + (outSubtotal as any)[monthKey] = + ((outSubtotal as any)[monthKey] ?? 0) + value; + outSubtotal.total += value; + } + }); + }); + inUsageData.push(inSubtotal); + outUsageData.push(outSubtotal); + const usageTotalObj: { [key: string]: any } = totalObj; + for (const key in usageTotalObj) { + if (["usage", "gubun", "edit"].includes(key)) continue; + const val = + (Number((inSubtotal as any)[key]) || 0) + + (Number((outSubtotal as any)[key]) || 0); + + (usageTotalObj as any)[key] = val; + } + const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; + setPrfData(tableData); + + } else { + setPrfData([]); + } + } + useEffect(() => { + let wshwtr = 0; + let coolUswtr = 0; + let cleanUswtr = 0; + let drwtUswtr = 0; + let dltnUswtr = 0; + let ithlRswtr = 0; + let ithlEtcUswtr = 0; + let cleanToilUswtr = 0; + let resn = 0; + let lndwtr = 0; + let hydUswtr = 0; + let ugwtChr = 0; + let farmUswtr = 0; + let rvrKeepUswtr = 0; + let indstUswtr = 0; + if (rawData) { + rawData.forEach((item) => { + prfTableData(item.prfList, year); + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + + wshwtr += element.wshwtr; //세척수 + coolUswtr += element.coolUswtr; //냉각수 + cleanUswtr += element.cleanUswtr; //청소수 + drwtUswtr += element.drwtUswtr; //식수대 + dltnUswtr += element.dltnUswtr //희석용수 + ithlRswtr += element.ithlRswtr //중수도 + ithlEtcUswtr += element.ithlEtcUswtr //기타 + cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 + resn += element.resn //세척살수용수 + + lndwtr += element.lndwtr; //조경용수 + hydUswtr += element.hydUswtr; //친수용수 + ugwtChr += element.ugwtChr; //지하수충전 + farmUswtr += element.farmUswtr //농업용수 + rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 + indstUswtr += element.indstUswtr //공업용수 + + }); + }) + const data: dnChartForm[] = [] + data?.push({ label: "세척수", val: wshwtr, fill: "red" }) + data?.push({ label: "냉각수", val: coolUswtr, fill: "orange" }) + data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) + data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) + data?.push({ label: "희석용수", val: dltnUswtr, fill: "skyblue" }) + data?.push({ label: "중수도", val: ithlRswtr, fill: "blue" }) + data?.push({ label: "기타", val: ithlEtcUswtr, fill: "purple" }) + data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "red" }) + data?.push({ label: "세척살수용수", val: resn, fill: "orange" }) + data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) + data?.push({ label: "친수용수", val: hydUswtr, fill: "green" }) + data?.push({ label: "지하수충전", val: ugwtChr, fill: "skyblue" }) + data?.push({ label: "농업용수", val: farmUswtr, fill: "blue" }) + data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "purple" }) + data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) + setChartData(data); + } + }, [rawData, year]) + + + useEffect(() => { + const newChartConfig = chartData.reduce((config, element) => { + config[element.label] = { + label: element.label, + fill: element.fill + }; + return config; + }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; + setChartConfig(newChartConfig); + }, [chartData]); + + // 장내용수 도넛차트 + useEffect(() => { + let wshwtr = 0; + let coolUswtr = 0; + let cleanUswtr = 0; + let drwtUswtr = 0; + let dltnUswtr = 0; + let ithlRswtr = 0; + let ithlEtcUswtr = 0; + let cleanToilUswtr = 0; + let resn = 0; + if (rawData) { + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + wshwtr += element.wshwtr; //세척수 + coolUswtr += element.coolUswtr; //냉각수 + cleanUswtr += element.cleanUswtr; //청소수 + drwtUswtr += element.drwtUswtr; //식수대 + dltnUswtr += element.dltnUswtr //희석용수 + ithlRswtr += element.ithlRswtr //중수도 + ithlEtcUswtr += element.ithlEtcUswtr //기타 + cleanToilUswtr += element.cleanToilUswtr //청소화장실용수 + resn += element.resn //세척살수용수 + }); + }) + const data: dnChartForm[] = [] + data?.push({ label: "세척수", val: wshwtr, fill: "yellow" }) + data?.push({ label: "냉각수", val: coolUswtr, fill: "green" }) + data?.push({ label: "청소수", val: cleanUswtr, fill: "yellow" }) + data?.push({ label: "식수대", val: drwtUswtr, fill: "green" }) + data?.push({ label: "희석용수", val: dltnUswtr, fill: "yellow" }) + data?.push({ label: "중수도", val: ithlRswtr, fill: "green" }) + data?.push({ label: "기타", val: ithlEtcUswtr, fill: "yellow" }) + data?.push({ label: "청소화장실용수", val: cleanToilUswtr, fill: "green" }) + data?.push({ label: "세척살수용수", val: resn, fill: "yellow" }) + setDnInUsage(data); + } + }, [rawData, year]) + + useEffect(() => { + const newChartConfig = dnInUsage.reduce((config, element) => { + config[element.label] = { + label: element.label, + fill: element.fill + }; + return config; + }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; + setDnInChartConfig(newChartConfig); + }, [dnInUsage]); + + // 장외용수 도넛차트 + useEffect(() => { + let lndwtr = 0; + let hydUswtr = 0; + let ugwtChr = 0; + let farmUswtr = 0; + let rvrKeepUswtr = 0; + let indstUswtr = 0; + if (rawData) { + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + lndwtr += element.lndwtr; //조경용수 + hydUswtr += element.hydUswtr; //친수용수 + ugwtChr += element.ugwtChr; //지하수충전 + farmUswtr += element.farmUswtr //농업용수 + rvrKeepUswtr += element.rvrKeepUswtr //하천등유지용수 + indstUswtr += element.indstUswtr //공업용수 + + }); + }) + const data: dnChartForm[] = [] + data?.push({ label: "조경용수", val: lndwtr, fill: "yellow" }) + data?.push({ label: "친수용수", val: hydUswtr, fill: "black" }) + data?.push({ label: "지하수충전", val: ugwtChr, fill: "yellow" }) + data?.push({ label: "농업용수", val: farmUswtr, fill: "black" }) + data?.push({ label: "하천등유지용수", val: rvrKeepUswtr, fill: "yellow" }) + data?.push({ label: "공업용수", val: indstUswtr, fill: "black" }) + setDnOutUsage(data); + } + }, [rawData, year]) + + useEffect(() => { + const newChartConfig = dnOutUsage.reduce((config, element) => { + config[element.label] = { + label: element.label, + fill: element.fill + }; + return config; + }, {} as Record<string, { label: string; color: string; }>) satisfies ChartConfig; + setDnOutChartConfig(newChartConfig); + }, [dnOutUsage]); + + //월별 장내외 용수 총 실적 막대차트 + useEffect(() => { + let wshwtr = 0; + let coolUswtr = 0; + let cleanUswtr = 0; + let drwtUswtr = 0; + let dltnUswtr = 0; + let ithlRswtr = 0; + let ithlEtcUswtr = 0; + let cleanToilUswtr = 0; + let resn = 0; + let lndwtr = 0; + let hydUswtr = 0; + let ugwtChr = 0; + let farmUswtr = 0; + let rvrKeepUswtr = 0; + let indstUswtr = 0; + let inUsageSum = 0; + let outUsageSum = 0; + let inUsageArr = []; + let outUsageArr = []; + + + if (rawData) { + const data: barChartForm[] = [] + rawData.forEach((item) => { + item.prfList + .filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + + wshwtr = element.wshwtr; //세척수 + coolUswtr = element.coolUswtr; //냉각수 + cleanUswtr = element.cleanUswtr; //청소수 + drwtUswtr = element.drwtUswtr; //식수대 + dltnUswtr = element.dltnUswtr //희석용수 + ithlRswtr = element.ithlRswtr //중수도 + ithlEtcUswtr = element.ithlEtcUswtr //기타 + cleanToilUswtr = element.cleanToilUswtr //청소화장실용수 + resn = element.resn //세척살수용수 + + lndwtr = element.lndwtr; //조경용수 + hydUswtr = element.hydUswtr; //친수용수 + ugwtChr = element.ugwtChr; //지하수충전 + farmUswtr = element.farmUswtr //농업용수 + rvrKeepUswtr = element.rvrKeepUswtr //하천등유지용수 + indstUswtr = element.indstUswtr //공업용수 + + inUsageSum = wshwtr + coolUswtr + cleanUswtr + drwtUswtr + dltnUswtr + ithlRswtr + ithlEtcUswtr + cleanToilUswtr + resn; + inUsageArr.push(inUsageSum) + outUsageSum = lndwtr + hydUswtr + ugwtChr + farmUswtr + rvrKeepUswtr + indstUswtr; + outUsageArr.push(outUsageSum) + + const month = Number(element.ym.slice(4, 6)) + data.push({ label: `${month}월`, "장내용수": inUsageSum, "장외용수": outUsageSum }) + + }, + ); + + }) + + setBarData(data); + } + }, [rawData, year]) + + useEffect(() => { + const newChartConfig = barData.reduce((config, element) => { + config[element.label] = { + label: element.label, + }; + return config; + + }, {} as Record<string, { label: string }>) satisfies ChartConfig; + setBarChartConfig(newChartConfig); + }, [barData]); + + //월별 장내 용수 실적 라인차트 + useEffect(() => { + + if (rawData) { + const wshwtrData: lineChartDataProps[] = [] + const coolUswtrData: lineChartDataProps[] = [] + const cleanUswtrData: lineChartDataProps[] = [] + const drwtUswtrData: lineChartDataProps[] = [] + const dltnUswtrData: lineChartDataProps[] = [] + const ithlRswtrData: lineChartDataProps[] = [] + const ithlEtcUswtrData: lineChartDataProps[] = [] + const cleanToilUswtrData: lineChartDataProps[] = [] + const resnData: lineChartDataProps[] = [] + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + const month = Number(element.ym.slice(4, 6)) + wshwtrData.push({ label: `${month}월`, val: element.wshwtr, color: "red" }) + coolUswtrData.push({ label: `${month}월`, val: element.coolUswtr, color: "red" }) + cleanUswtrData.push({ label: `${month}월`, val: element.cleanUswtr, color: "red" }) + drwtUswtrData.push({ label: `${month}월`, val: element.drwtUswtr, color: "red" }) + dltnUswtrData.push({ label: `${month}월`, val: element.dltnUswtr, color: "red" }) + ithlRswtrData.push({ label: `${month}월`, val: element.ithlRswtr, color: "red" }) + ithlEtcUswtrData.push({ label: `${month}월`, val: element.ithlEtcUswtr, color: "red" }) + cleanToilUswtrData.push({ label: `${month}월`, val: element.cleanToilUswtr, color: "red" }) + resnData.push({ label: `${month}월`, val: element.resn, color: "red" }) + + }, + ); + }) + const rtndata = { + chartData1: wshwtrData, + chartData2: coolUswtrData, + chartData3: cleanUswtrData, + chartData4: drwtUswtrData, + chartData5: dltnUswtrData, + chartData6: ithlRswtrData, + chartData7: ithlEtcUswtrData, + chartData8: cleanToilUswtrData, + chartData9: resnData + } + + setInLineData(rtndata) + } + }, [rawData, year]) + + useEffect(() => { + if (inLineData?.chartData1) { + const newChartConfig = { + chartData1: { + label: '세척수', + color: "red", + }, + chartData2: { + label: '냉각수', + color: "orange", + }, + chartData3: { + label: '청소수', + color: "yellow", + }, + chartData4: { + label: '식수대', + color: "pink", + }, + chartData5: { + label: '희석용수', + color: "purple", + }, + chartData6: { + label: '중수도', + color: "green", + }, + chartData7: { + label: '기타', + color: "blue", + }, + chartData8: { + label: '청소화장실용수', + color: "magenta", + }, + chartData9: { + label: '세척살수용수', + color: "skyblue", + }, + } satisfies ChartConfig; + setLnInChartConfig(newChartConfig); + } + }, [inLineData]); + + //월별 장외 용수 실적 라인차트 + useEffect(() => { + if (rawData) { + const lndwtrData: lineChartDataProps[] = [] + const hydUswtrData: lineChartDataProps[] = [] + const ugwtChrData: lineChartDataProps[] = [] + const farmUswtrData: lineChartDataProps[] = [] + const rvrKeepUswtrData: lineChartDataProps[] = [] + const indstUswtrData: lineChartDataProps[] = [] + rawData.forEach((item) => { + item.prfList.filter((e) => e.ym.slice(0, 4) === year) .forEach((element) => { + const month = Number(element.ym.slice(4, 6)) + lndwtrData.push({ label: `${month}월`, val: element.lndwtr, color: "red" }) + hydUswtrData.push({ label: `${month}월`, val: element.hydUswtr, color: "red" }) + ugwtChrData.push({ label: `${month}월`, val: element.ugwtChr, color: "red" }) + farmUswtrData.push({ label: `${month}월`, val: element.farmUswtr, color: "red" }) + rvrKeepUswtrData.push({ label: `${month}월`, val: element.rvrKeepUswtr, color: "red" }) + indstUswtrData.push({ label: `${month}월`, val: element.indstUswtr, color: "red" }) + }, + ); + }) + setOutLineData({ + chartData1: lndwtrData, + chartData2: hydUswtrData, + chartData3: ugwtChrData, + chartData4: farmUswtrData, + chartData5: rvrKeepUswtrData, + chartData6: indstUswtrData, + }) + } + }, [rawData, year]) + + useEffect(() => { + if (outLineData?.chartData1) { + const newChartConfig = { + chartData1: { + label: '조경용수', + color: "red", + }, + chartData2: { + label: '친수용수', + color: "orange", + }, + chartData3: { + label: '지하수충전', + color: "yellow", + }, + chartData4: { + label: '농업용수', + color: "green", + }, + chartData5: { + label: '하천등유지용수', + color: "blue", + }, + chartData6: { + label: '공업용수', + color: "purple", + }, + } satisfies ChartConfig; + setLnOutChartConfig(newChartConfig); + } + }, [outLineData]); + + useEffect(() => { + if (!pbnstPrfmncSttn.isInit) { + pbnstPrfmncInit("1", "11"); + } + }, [pbnstPrfmncSttn.isInit, pbnstPrfmncInit]); + + useEffect(() => { + setbdstTable(prfmncRes); + }, [prfmncRes]); + + return ( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4 "> + <div className="col-span-4"> + <Title title={"하수재이용실적 현황"} /> + <SearchBaseForm + selectSidoData={code.cityCd} + selectSigunData={code.sggCd} + selectRegionData={code.rvbsnCd} + selectUnitWaterShedData={code.lgbsnCd} + selectMiddleRegionData={code.mdmbsnCd} + selectEnvPartData={code.lclgvrnmntCd} + rightChildren={<Button + className={btnClass} + onClick={() => { + setIsChHead(true); + }} + > + 조회항목설정 + </Button>} + leftChildren={<div className="col-span-5"> + <div className="flex flex-row"> + <div className="flex flex-row items-center"> + <Label className="text-xl text-gray-600">하수 재이용년도</Label> + <SelectBox + className="h-full text-2xl" + label="" + selectClass={""} + selectArray={yearOptions} + value={fromDate} + onSelectValue={(val: string | number) => setFromDate(String(val))} /> + <SelectBox + className="h-full text-2xl" + label="" + selectClass={""} + selectArray={yearOptions} + value={toDate} + onSelectValue={(val: string | number) => setToDate(String(val))} /> + </div> + <SearchInput + className={"text-2xl"} + label="시설명" + textValue={swtrmtFcltNm} + setText={(e) => { + setSwtrmtFcltNm(e); + }} /> + <SelectBox + className="h-full text-2xl" + label="재이용시설명" + selectClass={""} + selectArray={[]} + value={""} + onSelectValue={() => { }} /> + </div> + </div>} + queryClick={function (returnType: ReturnType): void { + pbnstPrfmncSearch(returnType, swtrmtFcltNm ?? "", fromDate, toDate); + if (fromDate && toDate) { + const fromNum = Number(fromDate); + const toNum = Number(toDate); + if (fromNum > toNum) { + alert("시작년도가 종료년도 이후로 설정할 수 없습니다."); + } else { + if (toNum - fromNum > 5) { + alert("최대 5년까지 선택 가능합니다."); + } else { + tableHeadMaker(fromNum, toNum); + + } + } + } + }} + excelClick={() => { }} + initClick={function (): void { }} + btnClass={btnClass} + ref={ref} isAdmin={false} /> + </div> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={[]} + tableData={bdstTable || []} + headlist={pbnstPrfHeadList} + pageSize={20} + total={10000} + cellClick={() => { }} + onPageChange={() => { }} + /> + + <hr /> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label">하수재이용실적 상세현황</h3> + + <SelectBox + className="h-full w-1/12 text-2xl" + label="" + selectClass={""} + selectArray={selectYearList} + value={year} + onSelectValue={(val: string | number) => setYear(String(val))} /> + <h1 className="">장내·외 용도별 하수재이용실적 현황(계)</h1> + + <div className="flex"> + <div className="w-1/3"> + <MainChart chartConfig={chartConfig} chartData={chartData} chartTitle={"장내·외 용수 총 실적"} chartForm={"daughnut"} /> + </div> + <div className="w-1/3"> + <MainChart chartConfig={dnInChartConfig} chartData={dnInUsage} chartTitle={"장내용수 실적"} chartForm={"daughnut"} /> + </div> + <div className="w-1/3"> + <MainChart chartConfig={dnOutChartConfig} chartData={dnOutUsage} chartTitle={"장외용수 실적"} chartForm={"daughnut"} /> + </div> + </div> + <h1 className="">장내·외 월별 하수재이용실적 현황</h1> + <div className="flex"> + <div className="w-1/3"> + <MainChart chartConfig={barChartConfig} chartData={barData} chartTitle={"월별 장내·외 용수 총 실적"} chartForm={CHART_FORM.DOUBLEBAR} /> + </div> + <div className="w-1/3"> + <MainChart chartConfig={lnInChartConfig} chartData={inLineData} chartTitle={"월별 장내 용수 실적"} chartForm={CHART_FORM.LINE} /> + </div> + <div className="w-1/3"> + <MainChart chartConfig={lnOutChartConfig} chartData={outLineData} chartTitle={"월별 장외 용수 총 실적"} chartForm={CHART_FORM.LINE} /> + </div> + </div> + <h1 className="">하수재이용실적 현황</h1> + <ListDiv className="col-span-8 pr-6 "> + <ScrollArea className="h-[60vh]"> + <div className="card-header"> + <h3 className="text-2xl font-medium text-label"> + {"하수처리수재이용 실적(m3) 등록결과"} + </h3> + </div> + + <UiTable + headName={undefined} + tableData={prfData || []} + headlist={monthHeadList} + pageSize={0} + total={0} + cellClick={undefined} + onPageChange={function (page: number): void { + throw new Error("Function not implemented."); + }}> + </UiTable> + </ScrollArea> + </ListDiv> + + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ) +} diff --git a/apps/wr/app/stats/matStat/page.tsx b/apps/wr/app/stats/matStat/page.tsx new file mode 100644 index 000000000..a147ff597 --- /dev/null +++ b/apps/wr/app/stats/matStat/page.tsx @@ -0,0 +1,74 @@ +'use client' +import { useWrStore } from "@/app/store"; +import { yearOptions } from "@/components/lib/func/commom"; +import { ContentsDiv, Title, SearchDiv, SearchFormLeft, SelectBox, UiTable } from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button } from "@common/components/ui"; +import { useState } from "react"; + +export default function MatStat(){ +const { code, matStat } = useWrStore((state) => { + return state; + }); + const [pageNation, setPageNation] = useState(1); + const [searchYear, setSearchYear] = useState<string>( + String(new Date().getFullYear()) + ); + + return( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4"> + <div className="col-span-4"> + <Title title={"재이용 통계"} /> + <SearchDiv> + <SearchFormLeft> + <SelectBox + className="w-full h-full text-2xl" + label="통계년도" + selectClass={""} + selectArray={yearOptions} + value={searchYear} + onSelectValue={(val: string | number) => + setSearchYear(String(val)) + } + /> + <div className="flex flex-row space-x-2 items-center"> + <Button className="" size={"sm"} onClick={(e) => {}}> + 조회 + </Button> + <Button className="" size={"sm"} onClick={(e) => {}}> + 다운로드 + </Button> + <Button className="" size={"sm"} onClick={(e) => {}}> + 전체통계다운로드 + </Button> + </div> + </SearchFormLeft> + {/* <SearchFormRight> + + </SearchFormRight> */} + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4"> + <div className="col-span-6 h-full min-h-0"> + <ListDiv className="min-h-0"> + {/* <ScrollArea className="h-[60vh]"> */} + <UiTable + tableData={[]} + headlist={matStat.matStatHeadList} + pageSize={20} + total={10000} + headName={"건축물 목록"} + cellClick={(val, headId) => {}} + onPageChange={setPageNation} + ></UiTable> + {/* </ScrollArea> */} + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/app/stats/rainStat/page.tsx b/apps/wr/app/stats/rainStat/page.tsx new file mode 100644 index 000000000..f4d42e033 --- /dev/null +++ b/apps/wr/app/stats/rainStat/page.tsx @@ -0,0 +1,81 @@ +"use client"; +import { useWrStore } from "@/app/store"; +import { yearOptions } from "@/components/lib/func/commom"; +import { + ContentsDiv, + SearchDiv, + SearchFormLeft, + SelectBox, + Title, + UiTable, +} from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button } from "@common/components/ui"; +import { useState } from "react"; + +export default function rainStat() { + const { code, rainStat } = useWrStore((state) => { + return state; + }); + const [pageNation, setPageNation] = useState(1); + const [searchYear, setSearchYear] = useState<string>( + String(new Date().getFullYear()) + ); + + return ( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4"> + <div className="col-span-4"> + <Title title={"재이용 통계"} /> + <SearchDiv> + <SearchFormLeft> + <SelectBox + className="w-full h-full text-2xl" + label="통계년도" + selectClass={""} + selectArray={yearOptions} + value={searchYear} + onSelectValue={(val: string | number) => + setSearchYear(String(val)) + } + /> + <div className="flex flex-row space-x-2 items-center"> + <Button className="" size={"sm"} onClick={(e) => {}}> + 조회 + </Button> + <Button className="" size={"sm"} onClick={(e) => {}}> + 다운로드 + </Button> + <Button className="" size={"sm"} onClick={(e) => {}}> + 전체통계다운로드 + </Button> + </div> + </SearchFormLeft> + {/* <SearchFormRight> + + </SearchFormRight> */} + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4"> + <div className="col-span-6 h-full min-h-0"> + <ListDiv className="min-h-0"> + {/* <ScrollArea className="h-[60vh]"> */} + <UiTable + tableData={[]} + headlist={rainStat.rainStatHeadList} + pageSize={20} + total={10000} + headName={"건축물 목록"} + cellClick={(val, headId) => {}} + onPageChange={setPageNation} + ></UiTable> + {/* </ScrollArea> */} + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ); +} diff --git a/apps/wr/app/stats/rswtStat/page.tsx b/apps/wr/app/stats/rswtStat/page.tsx new file mode 100644 index 000000000..7514f98b1 --- /dev/null +++ b/apps/wr/app/stats/rswtStat/page.tsx @@ -0,0 +1,75 @@ +'use client' +import { useWrStore } from "@/app/store"; +import { yearOptions } from "@/components/lib/func/commom"; +import { ContentsDiv, SearchDiv, SearchFormLeft, SelectBox, Title, UiTable } from "@common/business_components/ui"; +import ListDiv from "@common/business_components/ui/list_div"; +import { Button } from "@common/components/ui"; +import { useState } from "react"; + +export default function RswtStat() { + const { code, rswtStat } = useWrStore((state) => { + return state; + }); + const [pageNation, setPageNation] = useState(1); + const [searchYear, setSearchYear] = useState<string>( + String(new Date().getFullYear()) + ); + + return( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4"> + <div className="col-span-4"> + <Title title={"재이용 통계"} /> + <SearchDiv> + <SearchFormLeft> + <SelectBox + className="w-full h-full text-2xl" + label="통계년도" + selectClass={""} + selectArray={yearOptions} + value={searchYear} + onSelectValue={(val: string | number) => + setSearchYear(String(val)) + } + /> + <div className="flex flex-row space-x-2 items-center"> + <Button className="" size={"sm"} onClick={(e) => {}}> + 조회 + </Button> + <Button className="" size={"sm"} onClick={(e) => {}}> + 다운로드 + </Button> + <Button className="" size={"sm"} onClick={(e) => {}}> + 전체통계다운로드 + </Button> + </div> + </SearchFormLeft> + {/* <SearchFormRight> + + </SearchFormRight> */} + </SearchDiv> + </div> + </div> + <div className="grid grid-cols-6 gap-4"> + <div className="col-span-6 h-full min-h-0"> + <ListDiv className="min-h-0"> + {/* <ScrollArea className="h-[60vh]"> */} + <UiTable + tableData={[]} + headlist={rswtStat.rswtStatHeadList} + pageSize={20} + total={10000} + headName={"건축물 목록"} + cellClick={(val, headId) => {}} + onPageChange={setPageNation} + ></UiTable> + {/* </ScrollArea> */} + </ListDiv> + </div> + </div> + </ContentsDiv> + </> + ) + +} \ No newline at end of file diff --git a/apps/wr/app/store/common/code/index.ts b/apps/wr/app/store/common/code/index.ts index 3f6da6dec..6caabcb5c 100644 --- a/apps/wr/app/store/common/code/index.ts +++ b/apps/wr/app/store/common/code/index.ts @@ -102,6 +102,12 @@ const dmdUszCd = [ ] +const ruseMngMtd = [ + { val: "자체운영", text: "자체운영" }, + { val: "공기업", text: "공기업" }, + { val: "민간(대행)", text: "민간(대행)" }, +] + const pplQulity = [ { val: "도복장강관", text: "도복장강관" }, @@ -154,6 +160,7 @@ export type comCodeState = { RNB:string, HTB:string } + ruseMngMtd:SelectDataType[] }; }; @@ -292,6 +299,7 @@ export const comCodeStateExport: comCodeState = { yn: yn, dmdUszCd:dmdUszCd, buildingType:buildingType, + ruseMngMtd:ruseMngMtd, }, }; diff --git a/apps/wr/app/store/common/searchCode/index.ts b/apps/wr/app/store/common/searchCode/index.ts index c1b46a901..83234c2e1 100644 --- a/apps/wr/app/store/common/searchCode/index.ts +++ b/apps/wr/app/store/common/searchCode/index.ts @@ -1,14 +1,22 @@ -import { fetchType, getFetch, postFectch } from "@/components/lib/api"; +import { + fetchType, + getFetch, + postFectch, + putFectch, +} from "@/components/lib/api"; import type { pubHasuType } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; import type { DemandCompType } from "@common/business_components/ui"; export type comFcltState = { searchFclts: pubHasuType; demandCompList: DemandCompType[]; + dmdIsSucees: string; + checkDemand: DemandCompType; }; export type comFcltActions = { getSwtrmtFcltNm: (searchNm: string) => void; - getDemandCompList :(searchNm: string,cnt:number) => void - regDemandCompany:(data:DemandCompType ) => void + getDemandCompList: (searchNm: string, cnt: number) => void; + regDemandCompany: (data: DemandCompType) => void; + updateDemandCompany: (data: DemandCompType) => void; }; export const searchActions: (set: any) => comFcltActions = (set: any) => { @@ -26,27 +34,64 @@ export const searchActions: (set: any) => comFcltActions = (set: any) => { addr: item.addr, fctCpc: item.fctCpc, })); - return set((state: comFcltState) => ({ + set((state: comFcltState) => ({ ...state, searchFclts: fcltNmCd, })); }, - getDemandCompList: async (searchNm: string ,cnt:number) => { + getDemandCompList: async (searchNm: string, cnt: number) => { const coList = await getFetch( fetchType.WR, - `/reuseFc/request/${searchNm}/${cnt}` + `/reuseFc/request/${searchNm}/${cnt}` ); - return set((state: comFcltState) => ({ - ...state, - demandCompList: coList, - })); - },regDemandCompany: async (data:DemandCompType)=>{ - - try{ - const response = await postFectch('/reuseFc/request',data,fetchType.WR ) - }catch(err){ - console.log(err) - } + set((state: comFcltState) => { + state.demandCompList = coList; + return state; + }); + }, + regDemandCompany: async (data: DemandCompType) => { + try { + const response = await postFectch( + "/reuseFc/request", + data, + fetchType.WR + ); + let message = ""; + if (response.status === 200) { + message = "success"; + } else { + message = "fail"; + } + set((state: comFcltState) => { + state.dmdIsSucees = message; + return state; + + }); + } catch (err) { + console.log(err); + } + }, + updateDemandCompany: async (data: DemandCompType) => { + try { + const response = await putFectch("/reuseFc/request", data); + + let message = ""; + if (response.status === 200) { + message = "success"; + } else { + message = "fail"; + } + + set((state: comFcltState) => { + state.dmdIsSucees = message; + return state; + + }); + + + } catch (err) { + console.log(err); + } } - }; + } }; diff --git a/apps/wr/app/store/common/type/headder.tsx b/apps/wr/app/store/common/type/header.tsx similarity index 61% rename from apps/wr/app/store/common/type/headder.tsx rename to apps/wr/app/store/common/type/header.tsx index e11fae01c..45ef9e291 100644 --- a/apps/wr/app/store/common/type/headder.tsx +++ b/apps/wr/app/store/common/type/header.tsx @@ -15,9 +15,12 @@ export type TableUpperProps = { upName?: string; upSequnce?: number; edit?:boolean; - visible?:boolean; - rowSpan?: true; + visible?:boolean; + rowSpan?: number; + colSpan?: number; type?: string; + selectData ?:string; // type 이 seelct 일경우 selectarray 정하기 위해 + row?:number; + mergeCell?:boolean // 셀을 합칠경우 }; - \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/coMatRvw/headList.tsx b/apps/wr/app/store/matDmd/coMatRvw/headList.tsx index 906c97047..8caf7e1b2 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/headList.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/headList.tsx @@ -1,5 +1,5 @@ import { z } from "zod"; -import type { CommonTableProps } from "../../common/type/headder"; +import type { CommonTableProps } from "../../common/type/header"; export const sttnHeadListType = z.array( z.object({ @@ -106,4 +106,147 @@ export const coRvwNodeListExport: CommonTableProps[] = [ colSpan: 1, }, -]; \ No newline at end of file +]; + +export const cmpttnHeadListExport: CommonTableProps[] = [ + { + id: "ctpv", + title: "구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sgg", + title: "처리시설 용량(m³)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "500", + title: "500", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "1000", + title: "1,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + },{ + id: "2000", + title: "2,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "3000", //바꾸기 + title: "3,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "5000", //바꾸기 + title: "5,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "10000", //바꾸기 + title: "10,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "20000", //바꾸기 + title: "20,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "30000", //바꾸기 + title: "30,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "50000", //바꾸기 + title: "50,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "100000", //바꾸기 + title: "100,000", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + +]; + + +export const coModalHeadListExport: CommonTableProps[] = [ + { + id: "gubun", + title: "공사비/구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "a", + title: "기본조사설계비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aa", + title: "실시설계비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaa", + title: "공사감리비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaa", + title: "시설부대비", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +] \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/coMatRvw/index.tsx b/apps/wr/app/store/matDmd/coMatRvw/index.tsx index 6e62da829..906a7bedd 100644 --- a/apps/wr/app/store/matDmd/coMatRvw/index.tsx +++ b/apps/wr/app/store/matDmd/coMatRvw/index.tsx @@ -1,7 +1,7 @@ import type { z } from "zod"; import type { sttnHeadListType } from "../coSttn/headList"; import { coRvwHeadListExport, coRvwNodeListExport } from "./headList"; -import type { CommonTableProps } from "../../common/type/headder"; +import type { CommonTableProps } from "../../common/type/header"; const coRvwHeadList = coRvwHeadListExport; const coRvwNodeList = coRvwNodeListExport; diff --git a/apps/wr/app/store/matDmd/coReg/index.tsx b/apps/wr/app/store/matDmd/coReg/index.tsx deleted file mode 100644 index c4e64614c..000000000 --- a/apps/wr/app/store/matDmd/coReg/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { z } from "zod"; - -export const coZod = z.object({ - ctpv: z.string(), - sgg: z.string(), - coNm: z.string().min(1).max(20), - bznmNo: z.string().min(1).min(9).max(12), - addr: z.string().min(1).min(6).max(20), - telNo: z.string().min(8).max(12) - -}); - -export type customCoBdst = z.infer<typeof coZod>; diff --git a/apps/wr/app/store/matDmd/coSttn/excel.tsx b/apps/wr/app/store/matDmd/coSttn/excel.tsx new file mode 100644 index 000000000..39d669664 --- /dev/null +++ b/apps/wr/app/store/matDmd/coSttn/excel.tsx @@ -0,0 +1,17 @@ +import type { customCoSttnBdst } from "."; + +export const excelCoSttnParsing = (data: customCoSttnBdst[]): string[][] => { + const excelExportData: string[][] = []; + + data.forEach((item) => { + excelExportData.push([ + String(item.ctpvCd), + String(item.sggCd), + item.dmdCoNm ?? "", + item.daddr ?? "", + String(item.dmdInfoPk ?? ""), + item.telno ?? "" + ]); + }); + return excelExportData; +}; diff --git a/apps/wr/app/store/matDmd/coSttn/headList.tsx b/apps/wr/app/store/matDmd/coSttn/headList.tsx index 79e5b6a3a..b0010778b 100644 --- a/apps/wr/app/store/matDmd/coSttn/headList.tsx +++ b/apps/wr/app/store/matDmd/coSttn/headList.tsx @@ -1,4 +1,4 @@ -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; import { z } from "zod"; export const sttnHeadListType = z.array( @@ -15,41 +15,40 @@ export const coRegExcel = z.object({ export const coSttHeadListExport: z.infer<typeof sttnHeadListType> = [ { - id: "ctpv", + id: "cityText", title: "시도", visible: true, }, { - id: "sgg", + id: "sggText", title: "시군구", visible: true, }, { - id: "coNm", + id: "dmdCoNm", title: "회사명", visible: true, }, { - id: "addr", - title: "공장주소", + id: "daddr", + title: "주소", visible: true, }, { - id: "bznmNo", - title: "공장관리번호", + id: "dmdInfoPk", + title: "사업자번호", visible: true, }, { - id: "telNo", + id: "telno", title: "전화번호", visible: true, }, ]; -// id는 다확인해야함 export const coSttNodeListExport: CommonTableProps[] = [ { - id: "ctpv", + id: "cityText", title: "시도", visible: true, row: 1, @@ -57,7 +56,7 @@ export const coSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "sgg", + id: "sggText", title: "시군구", visible: true, row: 1, @@ -65,7 +64,7 @@ export const coSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "coNm", + id: "dmdCoNm", title: "회사명", visible: true, row: 1, @@ -73,23 +72,23 @@ export const coSttNodeListExport: CommonTableProps[] = [ colSpan: 1, }, { - id: "addr", - title: "공장주소", + id: "daddr", + title: "주소", visible: true, row: 1, rowSpan: 1, colSpan: 1, }, { - id: "bznmNo", - title: "공장관리번호", + id: "dmdInfoPk", + title: "사업자번호", visible: true, row: 1, rowSpan: 1, colSpan: 1, }, { - id: "telNo", + id: "telno", title: "전화번호", visible: true, row: 1, diff --git a/apps/wr/app/store/matDmd/coSttn/index.tsx b/apps/wr/app/store/matDmd/coSttn/index.tsx index 00157ec6e..4b8c60436 100644 --- a/apps/wr/app/store/matDmd/coSttn/index.tsx +++ b/apps/wr/app/store/matDmd/coSttn/index.tsx @@ -1,16 +1,18 @@ -import type { z } from "zod"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; -import { coSttNodeListExport, coSttHeadListExport } from "./headList"; -import type { customCoBdst } from "../../matDmd/coReg"; -import type { sttnHeadListType } from "../coSttn/headList"; +import type { CommonTableProps } from "@/app/store/common/type/header"; +import { fetchType, getFetch } from "@/components/lib/api"; +import { coSttHeadListExport, coSttNodeListExport } from "./headList"; +import { excelCoSttnParsing } from "./excel"; +import type { DemandCompType } from "@common/business_components/ui"; // 테이블 헤드 리스트 const coSttNodeList = coSttNodeListExport; const coSttHeadList = coSttHeadListExport; +const coSttnRes: DemandCompType[] = []; + export type coSttnState = { coSttn: { - coSttnRes: customCoBdst[]; + coSttnRes: DemandCompType[]; coSttHeadList: CommonTableProps[]; coSttNodeList: CommonTableProps[]; excelList: []; @@ -19,7 +21,9 @@ export type coSttnState = { }; type coSttnActions = { - + coSttnInit:(pageNo:string, pageCnt:string, con: string) => void; + coSttnSearch: (pageNo:string, pageCnt:string, con: string) => void; + coSttnTxtSearch:(pageNo:string, pageCnt:string, con: string,txt:string) => void; }; export type coSttnType = coSttnState & coSttnActions; @@ -28,16 +32,89 @@ export const coSttnStateExport: coSttnState = { coSttn: { coSttHeadList: coSttHeadList, coSttNodeList: coSttNodeList, - coSttnRes: [], + coSttnRes: coSttnRes, excelList: [], isInit: false, }, }; + export const coSttnActionsExport: (set: any) => coSttnActions = ( set: any ) => { return { - + coSttnInit: async (pageNo:string, pageCnt:string, con: string) => { + try { + + const coSttnRes = await getFetch( + fetchType.WR, + `/reuseFc/request/${pageNo}/${pageCnt}/${con}` + ); + + + set((state: coSttnState) => { + return { + ...state, + coSttn: { + ...state.coSttn, + coSttnRes: coSttnRes, + isInit: false, + }, + }; + }); + } catch (e) { + console.log(e) + } + }, + coSttnSearch: async (pageNo:string, pageCnt:string, con: string) => { + try { + const coSttnRes = await getFetch( + fetchType.WR, + `/reuseFc/request/${pageNo}/${pageCnt}/${con}` + ); + if (Number(pageCnt) >= 10000) { + const coExcel = excelCoSttnParsing(coSttnRes); + set((state: coSttnState) => { + return { + ...state, + coSttn: { + ...state.coSttn, + excelList: coExcel, + isInit: false, + }, + }; + }); + } else + set((state: coSttnState) => { + return { + ...state, + coSttn: { + ...state.coSttn, + coSttnRes: coSttnRes, + isInit: false, + }, + }; + }); + } catch (erTxt) { + console.log("error", erTxt); + } + }, + coSttnTxtSearch: async (pageNo:string, pageCnt:string, con: string, txt: string) => { + try { + const coSttnRes = await getFetch( + fetchType.WR, + `/reuseFc/request/${pageNo}/${pageCnt}/${con}/${txt}`) + set((state: coSttnState) => { + return { + ...state, + coSttn: { + ...state.coSttn, + coSttnRes: coSttnRes, + isInit: false, + }}}) + } catch (erTxt) { + console.log("error", erTxt); + } + } } } \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/drgtSttn/headList.tsx b/apps/wr/app/store/matDmd/drgtSttn/headList.tsx new file mode 100644 index 000000000..40eae47e3 --- /dev/null +++ b/apps/wr/app/store/matDmd/drgtSttn/headList.tsx @@ -0,0 +1,102 @@ +import type { CommonTableProps } from "../../common/type/header"; + +export const drgtHeadListExport: CommonTableProps[] = [ + { + id: "ctpvCd", + title: "시도", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sggCd", + title: "시군구", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "haengjung", + title: "행정동", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "normal", + title: "정상(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "attention", + title: "관심(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "caution", + title: "주의(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "warning", + title: "관심+주의(횟수)", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "ranking", + title: "가뭄순위", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +]; + +export const drgtDetailHeadListExport: CommonTableProps[] = [ + { + id: "year", + title: "년", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "month", + title: "월", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + },{ + id: "day", + title: "일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "state", + title: "가뭄상태", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +] \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/drgtSttn/index.tsx b/apps/wr/app/store/matDmd/drgtSttn/index.tsx new file mode 100644 index 000000000..edbbc2f28 --- /dev/null +++ b/apps/wr/app/store/matDmd/drgtSttn/index.tsx @@ -0,0 +1,27 @@ +import type { CommonTableProps } from "../../common/type/header"; +import { drgtHeadListExport } from "./headList"; + +const drgtHeadList = drgtHeadListExport; + +export type drgtState = { + drgt:{ + drgtHeadList: CommonTableProps[]; + } +} + +type drgtActions = { +}; + +export type drgtType = drgtState & drgtActions; + +export const drgtStateExport: drgtState = { + drgt: { + drgtHeadList: drgtHeadList, + } +} + +export const drgtActionsExport: (set: any) => drgtActions = ( + set: any +) => { + return {}; +}; \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx new file mode 100644 index 000000000..d8641d40a --- /dev/null +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/headList.tsx @@ -0,0 +1,359 @@ +import type { CommonTableProps } from "../../common/type/header"; + +export const ldrmntHeadListExport: CommonTableProps[] = [ + { + id: "ctpvCd", + title: "시도", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sggCd", + title: "시군구", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa1", + title: "회사명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa33", + title: "공장주소", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa35", + title: "공장관리번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa11", + title: "전화번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +] + +export const ldrmntNodeListExport: CommonTableProps[] = [ + { + id: "ctpvCd", + title: "시도", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "sggCd", + title: "시군구", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa", + title: "관리기관", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa1", + title: "회사명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa2", + title: "공장구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa3", + title: "단지명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa4", + title: "설립구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa5", + title: "입주형태", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa6", + title: "보유구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa7", + title: "최초승인일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa8", + title: "최초등록일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa9", + title: "등록구분", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa10", + title: "등록일", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa11", + title: "전화번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa12", + title: "남자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa13", + title: "여자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa14", + title: "외국인남자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa15", + title: "외국인여자종업원", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa16", + title: "종업원합계", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa17", + title: "생산품", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa18", + title: "원자재", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa19", + title: "공장규모", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa20", + title: "용도지역", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa21", + title: "지목", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa22", + title: "용지면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa23", + title: "제조시설면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa24", + title: "부대시설면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa25", + title: "건축면적", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa26", + title: "지식산업센터명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa27", + title: "대표업종", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa28", + title: "업종명", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa29", + title: "업종코드", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa30", + title: "차수", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa31", + title: "법인주소", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa32", + title: "필지수", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa33", + title: "공장주소", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa34", + title: "공장주소_지번", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, + { + id: "aaaaaa35", + title: "공장관리번호", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 1, + }, +]; \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx index 35d127904..4aec34e2f 100644 --- a/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx +++ b/apps/wr/app/store/matDmd/ldrmntCoSttn/index.tsx @@ -1,66 +1,201 @@ -import type { z } from "zod"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; -import { coSttNodeListExport, coSttHeadListExport } from "../coSttn/headList"; -import type { customCoBdst } from "../../matDmd/coReg"; -import type { sttnHeadListType } from "../coSttn/headList"; +import type { CommonTableProps } from "@/app/store/common/type/header"; +import { z } from "zod"; +import { ldrmntHeadListExport, ldrmntNodeListExport } from "./headList"; +import { deleteFectch, fetchType, getFetch, postFectch } from "@/components/lib/api"; + +export const ldrmntZod = z.object({ + ctpvCd: z.number().default(0), + sggCd: z.number().default(0), + aaaaaa: z.string().default(''), + aaaaaa1: z.string().default(''), + aaaaaa2: z.string().default(''), + aaaaaa3: z.string().default(''), + aaaaaa4: z.string().default(''), + aaaaaa5: z.string().default(''), + aaaaaa6: z.string().default(''), + aaaaaa7: z.date().default(() => new Date()), + aaaaaa8: z.date().default(() => new Date()), + aaaaaa9: z.string().default(''), + aaaaaa10: z.date().default(() => new Date()), + aaaaaa11: z.string().default(''), + aaaaaa12: z.string().default(''), + aaaaaa13: z.string().default(''), + aaaaaa14: z.string().default(''), + aaaaaa15: z.string().default(''), + aaaaaa16: z.string().default(''), + aaaaaa17: z.string().default(''), + aaaaaa18: z.string().default(''), + aaaaaa19: z.string().default(''), + aaaaaa20: z.string().default(''), + aaaaaa21: z.string().default(''), + aaaaaa22: z.string().default(''), + aaaaaa23: z.string().default(''), + aaaaaa24: z.string().default(''), + aaaaaa25: z.string().default(''), + aaaaaa26: z.string().default(''), + aaaaaa27: z.string().default(''), + aaaaaa28: z.string().default(''), + aaaaaa29: z.string().default(''), + aaaaaa30: z.string().default(''), + aaaaaa31: z.string().default(''), + aaaaaa32: z.string().default(''), + aaaaaa33: z.string().default(''), + aaaaaa34: z.string().default(''), + aaaaaa35: z.string().default(''), +}) // 테이블 헤드 리스트 -const coSttNodeList = coSttNodeListExport; -const coSttHeadList = coSttHeadListExport; +const ldrmntHeadList = ldrmntHeadListExport; +const ldrmntNodeList = ldrmntNodeListExport; -const ldrmntCoSttnRes: customCoBdst[] = []; +const ldrmntCoList = [{ + ctpvCd: "서울특별시", + sggCd: "종로구", + aaaaaa: "서울특별시 종로구", + aaaaaa1: "남일문화 (주)", + aaaaaa2: "개별입지", + aaaaaa3: "", + aaaaaa4: "일반", + aaaaaa5: "해당없음", + aaaaaa6: "임대", + aaaaaa7: "19980101", + aaaaaa8: "20050202", + aaaaaa9: "등록변경", + aaaaaa10: "20221207", + aaaaaa11: "02-720-1511", + aaaaaa12: "0", + aaaaaa13: "2", + aaaaaa14: "0", + aaaaaa15: "0", + aaaaaa16: "2", + aaaaaa17: "인쇄물", + aaaaaa18: "문구, 차드", + aaaaaa19: "소기업", + aaaaaa20: "도시지역 / 주거지역 / 제2종일반주거지역", + aaaaaa21: "대", + aaaaaa22: "238", + aaaaaa23: "57.12", + aaaaaa24: "69.44", + aaaaaa25: "126.56", + aaaaaa26: "", + aaaaaa27: "18111", + aaaaaa28: "경 인쇄업 외 2 종", + aaaaaa29: "18111, 18113, 18119", + aaaaaa30: "10", + aaaaaa31: "", + aaaaaa32: "1", + aaaaaa33: "서울특별시 종로구 자하문로16길 8 (창성동)", + aaaaaa34: "서울특별시 종로구 창성동 87-1번지", + aaaaaa35: "111102005091210", +}] -const ldrmntCoList = {ctpv: "이거머임", - sgg: "01", - coNm: "회사요", - bznmNo: "abc123", - addr: "서울 강남구", - telNo: "010-1234-5678"} -export type ldrmntCoSttnState = { - ldrmntCoSttn: { - ldrmntCoSttnRes: customCoBdst[]; - ldrmntCoSttHeadList: CommonTableProps[]; - ldrmntCoSttNodeList: CommonTableProps[]; +export type customLdrmntBdst = z.infer<typeof ldrmntZod>; + +const ldrmntRes: customLdrmntBdst[] = []; + +export type ldrmntState = { + ldrmnt: { + ldrmntHeadList: CommonTableProps[]; + ldrmntNodeList: CommonTableProps[]; excelList: []; isInit: boolean; + ldrmntCoList: typeof ldrmntCoList; + ldrmntRes: customLdrmntBdst[]; }; }; -type ldrmntCoSttnActions = { +type ldrmntActions = { }; -export type ldrmntCoSttnType = ldrmntCoSttnState & ldrmntCoSttnActions; +export type ldrmntType = ldrmntState & ldrmntActions; -export const ldrmntCoSttnStateExport: ldrmntCoSttnState = { - ldrmntCoSttn: { - ldrmntCoSttHeadList: coSttHeadList, - ldrmntCoSttNodeList: coSttNodeList, - ldrmntCoSttnRes: [ldrmntCoList], +export const ldrmntStateExport: ldrmntState = { + ldrmnt: { + ldrmntHeadList: ldrmntHeadList, + ldrmntNodeList: ldrmntNodeList, excelList: [], isInit: false, + ldrmntCoList: ldrmntCoList, + ldrmntRes: ldrmntRes, }, }; -export const ldrmntCoSttnActionsExport: (set: any) => ldrmntCoSttnActions = ( +export const ldrmntActionsExport: (set: any) => ldrmntActions = ( set: any ) => { return { - ldrmntCoSttnInit: async (code: string | number) => { - try{ - - set((state: ldrmntCoSttnState) => { - return { - ...state, - ldrmntCoSttn: { - ...state.ldrmntCoSttn, - ldrmntCoSttnRes: ldrmntCoSttnRes, - isInit: false, - }, - }; - }); - }catch(e){ - console.log(e) - } - }, + ldrmntInit: async (code: string | number) => { + try { + + set((state: ldrmntState) => { + return { + ...state, + ldrmnt: { + ...state.ldrmnt, + isInit: false, + ldrmntCoList: ldrmntCoList, + }, + }; + }); + } catch (e) { + console.log(e) + } + }, + ldrmntInsert: async (ldrmntRes: []) => { + try { + + const response = await postFectch( + `/reuseFc/request`, + [] + // JSON.stringify(writeRgtrAndMdfr([ldrmntRes])) + ); + + return set((state: ldrmntState) => ({ + ...state, + ldrmnt: { + ...state.ldrmnt, + ldrmntRes: response.data, + isInit: false, + }, + })); + } catch (error) { + console.error("Error updating ldrmnt:", error); + } + }, + fileDelete: async (atflCd: string) => { + try { + const response = await deleteFectch( + `/attach-service/api/v1/atfl/attachments/atflCd//${atflCd}`, + undefined, + fetchType.CS + ); + + console.log("File deleted successfully:", response); + return set((state: ldrmntState) => ({ + ...state, + ldrmnt: { + ...state.ldrmnt, + isInit: false, + }, + })); + } catch (error) { + console.error("Error deleting file:", error); + } + }, + fileDownLoad: async (atflCd: string) => { + try { + const response = await getFetch( + fetchType.CS, + `/attach-service/api/v1/atflcd/download/${atflCd}` + ); + + if (!response.ok) { + throw new Error(`Error downloading file: ${response.statusText}`); + } + } catch (error) { + console.error("Error downloading file:", error); + } + }, + } } \ No newline at end of file diff --git a/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx new file mode 100644 index 000000000..125866601 --- /dev/null +++ b/apps/wr/app/store/matDmd/ruseCaseMng/headList.tsx @@ -0,0 +1,355 @@ +import type { SelectDataType } from "@common/business_components/ui"; +import type { TableUpperProps } from "../../common/type/header"; + +//★☆★☆ 여기서부터 수정하기 ★☆★☆ +export const ruseCaseHeadListExport: TableUpperProps[] = [ + { + id: "a", + title: "사업명", + visible: true, + row: 0, + rowSpan: 2, + }, + { + id: "b", + title: "사업기간", + visible: true, + row: 0, + rowSpan: 2, + }, + { + id: "c", + title: "공급처", + visible: true, + row: 0, + colSpan: 3, + }, + { + id: "d", + title: "시설종류", + visible: true, + row: 1, + }, + { + id: "e", + title: "공급처명", + visible: true, + row: 1, + }, + { + id: "f", + title: "시설용량(m³/일)", + visible: true, + row: 1, + }, + { + id: "g", + title: "수요처", + visible: true, + row: 0, + colSpan: 2, + }, + { + id: "h", + title: "수요처명", + visible: true, + row: 1, + }, + { + id: "i", + title: "주소", + visible: true, + row: 1, + }, + { + id: "q", + title: "재이용시설", + visible: true, + row: 0, + colSpan: 5, + }, + { + id: "q2", + title: "시설용량(m³/일)", + visible: true, + row: 1, + }, + { + id: "q3", + title: "관로(km)", + visible: true, + row: 1, + }, + { + id: "q4", + title: "용도", + visible: true, + row: 1, + }, + { + id: "q5", + title: "공급량(m³/일)", + visible: true, + row: 1, + }, + { + id: "q6", + title: "처리공법", + visible: true, + row: 1, + }, + { + id: "k", + title: "보증수질", + visible: true, + row: 0, + colSpan: 13, + }, + { + id: "k1", + title: "용도별", + visible: true, + row: 1, + }, + { + id: "k2", + title: "총대장균군수​(개/100ml)", + visible: true, + row: 1, + }, + { + id: "k3", + title: "결합잔류염소(mg/L)", + visible: true, + row: 1, + }, + { + id: "k4", + title: "탁도(NTU)", + visible: true, + row: 1, + }, + { + id: "k5", + title: "생물학적​산소요구량(BOD)(mg/L)​", + visible: true, + row: 1, + }, + { + id: "k6", + title: "냄새​", + visible: true, + row: 1, + }, + { + id: "k7", + title: "색도​", + visible: true, + row: 1, + }, + { + id: "k8", + title: "총질소(T-N)(mg/L)​", + visible: true, + row: 1, + }, + { + id: "k9", + title: "총인(T-P)(mg/L)", + visible: true, + row: 1, + }, + { + id: "k10", + title: "수소이온농도(PH)​", + visible: true, + row: 1, + }, + { + id: "k11", + title: "수소이온농도(PH)​", + visible: true, + row: 1, + }, + { + id: "k12", + title: "전기전도도​(㎲/cm", + visible: true, + row: 1, + }, + { + id: "k13", + title: "비고​", + visible: true, + row: 1, + }, + { + id: "h", + title: "소요사업비(백만원)", + visible: true, + row: 0, + colSpan: 14, + }, + { + id: "h1", + title: "총", + visible: true, + row: 1, + }, + { + id: "h2", + title: "토목재이용시설", + visible: true, + row: 1, + }, + { + id: "h3", + title: "토목관로", + visible: true, + row: 1, + }, + { + id: "h4", + title: "건축", + visible: true, + row: 1, + }, + { + id: "h5", + title: "기계", + visible: true, + row: 1, + }, + { + id: "h6", + title: "전기・계측", + visible: true, + row: 1, + }, + { + id: "h7", + title: "GIS・DB", + visible: true, + row: 1, + }, + { + id: "h8", + title: "CCTV", + visible: true, + row: 1, + }, + { + id: "h9", + title: "시공및준공", + visible: true, + row: 1, + }, + { + id: "h10", + title: "페기물", + visible: true, + row: 1, + }, + { + id: "h11", + title: "설계비", + visible: true, + row: 1, + }, + { + id: "h12", + title: "감리비", + visible: true, + row: 1, + }, + { + id: "h13", + title: "시설부대비", + visible: true, + row: 1, + }, + { + id: "h14", + title: "기타", + visible: true, + row: 1, + }, + { + id: "i", + title: "자원조달계획(백만원)", + visible: true, + row: 0, + colSpan: 4, + }, + { + id: "i1", + title: "총", + visible: true, + row: 1, + }, + { + id: "i2", + title: "국비", + visible: true, + row: 1, + }, + { + id: "i3", + title: "지방비", + visible: true, + row: 1, + }, + { + id: "i4", + title: "원인자부담", + visible: true, + row: 1, + }, + { + id: "j", + title: "사업비정산(백만원)", + visible: true, + row: 0, + colSpan: 5, + }, + { + id: "j1", + title: "총", + visible: true, + row: 1, + }, + { + id: "j2", + title: "국비", + visible: true, + row: 1, + }, + { + id: "j3", + title: "지방비", + visible: true, + row: 1, + }, + { + id: "j4", + title: "원인자부담", + visible: true, + row: 1, + }, + { + id: "j5", + title: "국고비율", + visible: true, + row: 1, + }, +]; + +export const ruseUtzType: SelectDataType[] = [ + { text: "조경용수", val: "조경용수" }, + { text: "청소화장실용수", val: "청소화장실용수" }, + { text: "세척살수용수", val: "세척살수용수" }, + { text: "농업용수", val: "농업용수" }, + { text: "공업용수", val: "공업용수" }, + { text: "친수용수", val: "친수용수" }, + { text: "기타", val: "기타" }, +]; diff --git a/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx b/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx new file mode 100644 index 000000000..c54b0db1a --- /dev/null +++ b/apps/wr/app/store/matDmd/ruseCaseMng/index.tsx @@ -0,0 +1,24 @@ +import type { TableUpperProps } from "../../common/type/header"; +import { ruseCaseHeadListExport } from "./headList"; + +export type ruseCaseState = { + ruseCase: { + ruseHeadList:TableUpperProps[]; + }; + }; +type ruseCaseActions = { +}; +export type ruseCaseType = ruseCaseState & ruseCaseActions; + +export const ruseCaseStateExport: ruseCaseState = { + ruseCase: { + ruseHeadList:ruseCaseHeadListExport, + }, +}; +export const ruseCaseActionsExport: (set: any) => ruseCaseActions = ( + set: any +) => { + return { + + }; +}; diff --git a/apps/wr/app/store/matDmd/ruseRvwHstry/headList.tsx b/apps/wr/app/store/matDmd/ruseRvwHstry/headList.tsx index f394229cf..8bbaa8e89 100644 --- a/apps/wr/app/store/matDmd/ruseRvwHstry/headList.tsx +++ b/apps/wr/app/store/matDmd/ruseRvwHstry/headList.tsx @@ -1,5 +1,5 @@ import { z } from "zod"; -import type { CommonTableProps } from "../../common/type/headder"; +import type { CommonTableProps } from "../../common/type/header"; export const sttnHeadListType = z.array( z.object({ diff --git a/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx b/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx index e41f792b6..8bb70deae 100644 --- a/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx +++ b/apps/wr/app/store/matDmd/ruseRvwHstry/index.tsx @@ -1,6 +1,6 @@ import type { z } from "zod"; import type { sttnHeadListType } from "../coSttn/headList"; -import type { CommonTableProps } from "../../common/type/headder"; +import type { CommonTableProps } from "../../common/type/header"; import { ruseHstryHeadListExport, ruseHstryNodeListExport } from "./headList"; const ruseHstryHeadList = ruseHstryHeadListExport; diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx index 3729ab987..3cc75d70c 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList.tsx @@ -1,4 +1,4 @@ -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import { z } from "zod"; export const chkgdRegExcel = z.object({ @@ -123,16 +123,16 @@ export const rainHeadNmExport: chHeadType[] = [ ]; export const rainChkgdnHeadListExport: TableUpperProps[] = [ - { id: "order", title: "순번", rowSpan: true }, - { id: "checkBox", title: "선택", rowSpan: true }, - { id: "cityText", title: "시도", rowSpan: true }, - { id: "sggText", title: "시군구", rowSpan: true }, - { id: "bdstNm", title: "시설명", rowSpan: true }, - { id: "operMngCd", title: "운영관리형태", rowSpan: true }, - { id: "oilqMeasMthd", title: "유량측정방법", rowSpan: true }, - { id: "anlOperCst", title: "연간운영비(원/년)", rowSpan: true }, - { id: "dtfcltCpct", title: "빗물저류조용량(m³)", rowSpan: true }, - { id: "chckYmd", title: "점검일", rowSpan: true }, + { id: "order", title: "순번", mergeCell: true }, + { id: "checkBox", title: "선택", mergeCell: true }, + { id: "cityText", title: "시도", mergeCell: true }, + { id: "sggText", title: "시군구", mergeCell: true }, + { id: "bdstNm", title: "시설명", mergeCell: true }, + { id: "operMngCd", title: "운영관리형태", mergeCell: true }, + { id: "oilqMeasMthd", title: "유량측정방법", mergeCell: true }, + { id: "anlOperCst", title: "연간운영비(원/년)", mergeCell: true }, + { id: "dtfcltCpct", title: "빗물저류조용량(m³)", mergeCell: true }, + { id: "chckYmd", title: "점검일", mergeCell: true }, { id: "utztnUsgCd", title: "이용용도" }, { id: "totalSplyUswtrUtztnQnt", title: "연간보급수이용량(m³)" }, { id: "totalRuseFcltUtztnQnt", title: "연간빗물이용량(m³)" }, diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx index 0cdc4a9b8..ff612a0fb 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rainChkgdn/index.tsx @@ -1,7 +1,6 @@ import { buildingType } from "@/app/store/common/code"; import { TEST_UUID, - type TableUpperProps, } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { deleteFectch, @@ -22,6 +21,7 @@ import { splHeadListExport, type chHeadType, } from "./headList"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export type rainChkZodType = z.infer<typeof rainChkZod>; const fcltDiv = [ @@ -217,7 +217,7 @@ export const rainChkgdnActionsExport: (set: any) => rainChkgdnActions = ( try { const res = await deleteFectch(`/reuseChk/rainy`, chkgdnPks); - if (res.ok) { + if (res) { ToastFormUi({ body: "삭제가 완료되었습니다. ", title: "지도점검 삭제", diff --git a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx index fe40fb441..0e690dbb9 100644 --- a/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx +++ b/apps/wr/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList.tsx @@ -1,6 +1,6 @@ -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { z } from "zod"; import { guideDetail, type chHeadType } from "../rainChkgdn/headList"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export type polutionType = { chkgdnDtlFk: number; @@ -115,16 +115,16 @@ export const rswtHeadNmExport: chHeadType[] = [ ]; export const rswtChkHeadListExport: TableUpperProps[] = [ - { id: "order", title: "순번", rowSpan: true }, - { id: "checkBox", title: "선택", rowSpan: true }, - { id: "cityText", title: "시도" ,rowSpan: true }, - { id: "sggText", title: "시군구",rowSpan: true }, - { id: "bdstNm", title: "시설명" ,rowSpan: true}, - { id: "operMngCd", title: "운영관리형태" ,rowSpan: true}, - { id: "anlOperCst", title: "연간운영비(원/년)" ,rowSpan: true}, - { id: "prcsCpct", title: "처리용량(m³)" ,rowSpan: true}, - { id: "spwtPositn", title: "채수지점" ,rowSpan: true}, - { id: "chckYmd", title: "점검일" ,rowSpan: true}, + { id: "order", title: "순번", mergeCell: true }, + { id: "checkBox", title: "선택", mergeCell: true }, + { id: "cityText", title: "시도" ,mergeCell: true }, + { id: "sggText", title: "시군구",mergeCell: true }, + { id: "bdstNm", title: "시설명" ,mergeCell: true}, + { id: "operMngCd", title: "운영관리형태" ,mergeCell: true}, + { id: "anlOperCst", title: "연간운영비(원/년)" ,mergeCell: true}, + { id: "prcsCpct", title: "처리용량(m³)" ,mergeCell: true}, + { id: "spwtPositn", title: "채수지점" ,mergeCell: true}, + { id: "chckYmd", title: "점검일" ,mergeCell: true}, { id: "utztnUsgCd", title: "이용용도" }, { id: "splyUswtrUtztnQnt", title: "연간보급수이용량(m³)" ,type: "number"}, { id: "ruseFcltUtztnQnt", title: "연간중수도이용량(m³)",type: "number"}, diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/excel.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/excel.tsx index b0cbb7724..d8160cab9 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/excel.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/excel.tsx @@ -1,7 +1,10 @@ import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg"; +type NameMap = { + [key: string]: string; +}; - const nameMap = { + const nameMap:NameMap = { "세척수": "wshwtr", "냉각수": "coolUswtr", "청소수": "cleanUswtr", @@ -20,24 +23,33 @@ import { TEST_UUID } from "../../ruseFcltMng/fcltReg/rainReg"; }; -export const excelToPbnPrfData = (excelData: any[], year: string) => { +export const excelToPbnPrfData = (excelData: JSON[], year: string,pbnstRuseFcltFk:string) => { // 월별 데이터 하나로 병합 const merged = {} as any; excelData.forEach((item: any) => { - const key = nameMap[item["용수명"]]; + const usageNm = item["용수명"] + const key = nameMap[usageNm as any]; 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); + const data = pbnPrfData.map((item) => { - return pbnPrfData; + return({ + ...(item as object), + pbnstRuseFcltFk:pbnstRuseFcltFk, + rgtr: TEST_UUID, + mdfr: TEST_UUID, + }) + }) + return data; }; \ No newline at end of file diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/headList.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/headList.tsx index a41eeba52..544f07516 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/headList.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/headList.tsx @@ -1,9 +1,10 @@ import { z } from "zod"; -import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "../../common/type/header"; export const pbnPrfRegExcelZod = z.object({ ym: z.string().default(""), bscFctNm: z.string().default(""), + pbnstRuseFcltFk:z.string(), pbnstRuseFcltNm: z.string().default(""), file: z.instanceof(File).optional(), }); @@ -12,23 +13,26 @@ export const pbnstPrfmncHeadListExport: TableUpperProps[] = [ { id: "sido", title: "시도" }, { id: "gugun", title: "시군구" }, { id: "bscFctNm", title: "시설명" }, - { id: "sisul", title: "재이용시설명" }, - { id: "sisulCd", title: "재이용시설코드" }, + { id: "ruseUtztnFcltNm", title: "재이용시설명" }, + { id: "pbnstRuseFcltPk", title: "재이용시설코드" }, ]; export const monthHeadListExport: TableUpperProps[] = [ - { id: "gubun", title: "구분" }, + { id: "용수명", title: "용수명" }, { id: "total", title: "계" }, - { id: "mon1", title: "1월" }, - { id: "mon2", title: "2월" }, - { id: "mon3", title: "3월" }, - { id: "mon4", title: "4월" }, - { id: "mon5", title: "5월" }, - { id: "mon6", title: "6월" }, - { id: "mon7", title: "7월" }, - { id: "mon8", title: "8월" }, - { id: "mon9", title: "9월" }, - { id: "mon10", title: "10월" }, - { id: "mon11", title: "11월" }, - { id: "mon12", title: "12월" }, + { id: "1월", title: "1월" ,edit: true }, + { id: "2월", title: "2월" ,edit: true }, + { id: "3월", title: "3월" ,edit: true }, + { id: "4월", title: "4월" ,edit: true }, + { id: "5월", title: "5월" ,edit: true }, + { id: "6월", title: "6월" ,edit: true }, + { id: "7월", title: "7월" ,edit: true }, + { id: "8월", title: "8월" ,edit: true }, + { id: "9월", title: "9월" ,edit: true }, + { id: "10월", title: "10월" ,edit: true }, + { id: "11월", title: "11월" ,edit: true }, + { id: "12월", title: "12월" ,edit: true }, ]; + + + diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx index 282c277ec..e72d6def6 100644 --- a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/index.tsx @@ -1,79 +1,113 @@ import { fetchType, getFetch, postFectch } from "@/components/lib/api"; -import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg"; -import { - pbnstPrfmncHeadListExport, - monthHeadListExport, -} from "./headList"; +import { pbnstPrfmncHeadListExport, monthHeadListExport } from "./headList"; 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"; const pbnstPrfmncHeadList = pbnstPrfmncHeadListExport; const monthHeadList = monthHeadListExport; export type pbnstPrfmncState = { - prfmnc: { - isInit: boolean; - pbnstPrfmncHeadList: TableUpperProps[]; - monthHeadList: TableUpperProps[]; - prfmncRes: pubHasuType[]; - excelList: Number[]; - } -} + prfmnc: { + isInit: boolean; + pbnstPrfmncHeadList: TableUpperProps[]; + monthHeadList: TableUpperProps[]; + prfmncRes: FcPrfType[]; + excelList: Number[]; + }; +}; export const pbnstPrfmncStateExport: pbnstPrfmncState = { - prfmnc: { - isInit: false, - pbnstPrfmncHeadList: pbnstPrfmncHeadList, - monthHeadList: monthHeadList, - prfmncRes: [], - excelList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], - } -} + prfmnc: { + isInit: false, + pbnstPrfmncHeadList: pbnstPrfmncHeadList, + monthHeadList: monthHeadList, + prfmncRes: [], + excelList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, +}; export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions; type pbnstPrfmncActions = { - prfmncHasuInit: (page: string, sggOrCity: string) => void; -} + prfmncHasuInit: (page: string, sggOrCity: string) => void; + prfmnRegData: (data:PrfType) =>void +}; const checkWrRegList = async () => { - const wrRegList = await getFetch("wr", `/reuseFc/pubFc`); - return wrRegList; + const wrRegList = await getFetch("wr", `/reuseFc/pubDetailList`); + return wrRegList; }; const hasuListFetch = async (page: string, sggOrCity: string) => { - const checkWrRegListRes = await checkWrRegList(); - - const rainRes = await postFectch( - `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`, - checkWrRegListRes, - fetchType.COMMON + const checkWrRegListRes = await checkWrRegList(); + const rainRes = await postFectch( + `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`, + 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 hasuList = rainRes.data.map((item: any) => { - return { - ...item, - ruse: item.ruse === false ? "N" : "Y", - }; - }); - - return hasuList; -}; -export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (set: any) => { return { - prfmncHasuInit: async (page: string, sggOrCity: string) => { - try { - const prfmncRes = await hasuListFetch(page, sggOrCity); - console.log("prfmncRes", prfmncRes) - return set((state: pbnstPrfmncState) => ({ - ...state, - prfmnc: { - ...state.prfmnc, - prfmncRes: prfmncRes, - isInit: false, - }, - })); - } catch (errorHasu) { - console.log(errorHasu); - } - }, - } -} \ No newline at end of file + sido: findData?.sido, + gugun: findData?.gugun, + bscFctNm: findData?.bscFctNm, + ruseUtztnFcltNm: item.ruseUtztnFcltNm, + pbnstRuseFcltPk: item.pbnstRuseFcltPk, + prfList : item.prfList + }; + }); + return data; +}; +export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = ( + set: any +) => { + return { + prfmncHasuInit: async (page: string, sggOrCity: string) => { + try { + const prfmncRes = await hasuListFetch(page, sggOrCity); + console.log("prfmncRes", prfmncRes); + return set((state: pbnstPrfmncState) => ({ + ...state, + prfmnc: { + ...state.prfmnc, + prfmncRes: prfmncRes, + isInit: false, + }, + })); + } catch (errorHasu) { + console.log(errorHasu); + } + }, + 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: "하수재이용 시설 실적 등록", + }); + + } + }, + }; +}; diff --git a/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx new file mode 100644 index 000000000..3bd741663 --- /dev/null +++ b/apps/wr/app/store/prfmncReg/pbnstPrfmncReg/type.tsx @@ -0,0 +1,346 @@ +import { z } from "zod"; +import type { TableUpperProps } from "../../common/type/header"; +import { fcOperSchema } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; + +export const PrfSchema = z.object({ + pbnstRuseFcltFk: z.string(), + ym: z.string(), // 예: "202310" + wshwtr: z.number(), + coolUswtr: z.number(), + cleanUswtr: z.number(), + drwtUswtr: z.number(), + dltnUswtr: z.number(), + ithlRswtr: z.number(), + ithlEtcUswtr: z.number(), + cleanToilUswtr: z.number(), + resn: z.number(), + lndwtr: z.number(), + hydUswtr: z.number(), + rvrKeepUswtr: z.number(), + farmUswtr: z.number(), + ugwtChr: z.number(), + indstUswtr: z.number(), + regDt: z.date().default(new Date()).nullish(), + rgtr: z.string().nullish(), + mdfcnDt: z.date().default(new Date()).nullish(), + mdfr: z.string().nullish(), +}); + +export const FcPrfSchema = z.object({ + pbnstRuseFcltPk: z.string(), + ruseUtztnFcltNm: z.string(), + fcltCpct: z.number(), + ruseCpct: z.number(), + splyExtraCpct: z.number(), + regDt: z.date().default(new Date()), + rgtr: z.string(), + mdfcnDt: z.date().default(new Date()), + mdfr: z.string(), + prfList: z.array(PrfSchema), + operList:z.array(fcOperSchema), + bscFctNm: z.string().nullish(), +}); + +export type FcPrfType = z.infer<typeof FcPrfSchema>; +export type PrfType = z.infer<typeof PrfSchema>; + +export const initValInUsage = [ + { + usage: "wshwtr", + 용수명: "세척수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "coolUswtr", + 용수명: "냉각수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "cleanUswtr", + 용수명: "청소수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "drwtUswtr", + 용수명: "식수대", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "dltnUswtr", + 용수명: "희석용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "ithlRswtr", + 용수명: "중수도", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "ithlEtcUswtr", + 용수명: "기타", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "resn", + 용수명: "세척살수용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "cleanToilUswtr", + 용수명: "청소화장실용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, +]; + +export const initValOutUsage = [ + { + usage: "lndwtr", + 용수명: "조경용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "hydUswtr", + 용수명: "친수용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "ugwtChr", + 용수명: "지하수충전", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + { + usage: "farmUswtr", + 용수명: "농업용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + + { + usage: "rvrKeepUswtr", + 용수명: "하천등유지용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, + + { + usage: "indstUswtr", + 용수명: "공업용수", + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, + }, +]; + +export const subTotalObj = { + usage: "subtotal", + 용수명: "소계", + edit: false, + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, +}; + +export const totalObj = { + usage: "total", + 용수명: "총합계", + edit: false, + total: 0, + "1월": 0, + "2월": 0, + "3월": 0, + "4월": 0, + "5월": 0, + "6월": 0, + "7월": 0, + "8월": 0, + "9월": 0, + "10월": 0, + "11월": 0, + "12월": 0, +}; diff --git a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx index 768de0776..f112db0bd 100644 --- a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx +++ b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rainChkgdnSttn/headList.tsx @@ -1,15 +1,15 @@ -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export const rainChkgdnHeadSttnExport: TableUpperProps[] = [ - { id: 'order', title: "순번", rowSpan: true }, - { id: "cityText", title: "시도", rowSpan: true }, - { id: "sggText", title: "시군구", rowSpan: true }, - { id: "bdstNm", title: "시설명", rowSpan: true }, - { id: "operMngCd", title: "운영관리형태", rowSpan: true }, - { id: "oilqMeasMthd", title: "유량측정방법", rowSpan: true }, - { id: "anlOperCst", title: "연간운영비(원/년)", rowSpan: true }, - { id: "dtfcltCpct", title: "빗물저류조용량(m³)", rowSpan: true }, - { id: "chckYmd", title: "점검일", rowSpan: true }, + { id: 'order', title: "순번", mergeCell: true }, + { id: "cityText", title: "시도", mergeCell: true }, + { id: "sggText", title: "시군구", mergeCell: true }, + { id: "bdstNm", title: "시설명", mergeCell: true }, + { id: "operMngCd", title: "운영관리형태", mergeCell: true }, + { id: "oilqMeasMthd", title: "유량측정방법", mergeCell: true }, + { id: "anlOperCst", title: "연간운영비(원/년)", mergeCell: true }, + { id: "dtfcltCpct", title: "빗물저류조용량(m³)", mergeCell: true }, + { id: "chckYmd", title: "점검일", mergeCell: true }, { id: "utztnUsgCd", title: "이용용도" }, { id: "totalSplyUswtrUtztnQnt", title: "연간보급수이용량(m³)" }, { id: "totalRuseFcltUtztnQnt", title: "연간빗물이용량(m³)" }, diff --git a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx index f3b018d10..f67e98101 100644 --- a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx +++ b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/headList.tsx @@ -1,4 +1,4 @@ -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export const rswtChkSttnHeadListExport: TableUpperProps[] = [ { id: "order", title: "순번", rowSpan: true }, diff --git a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx index f1dbd6c6e..b985cd944 100644 --- a/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx +++ b/apps/wr/app/store/prfmncSttn/chkgdnSttn/rswtChkgdnSttn/index.tsx @@ -1,8 +1,7 @@ import { rswtHeadNmExport } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList"; import { rswtChkSttnHeadListExport, rswtDetailSttnHeadListExport } from "./headList"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { sheetParameter } from "@common/business_components/ui"; import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; import { getFetch } from "@/components/lib/api"; import { buildingExcelRswtSttn } from "./excel"; diff --git a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx new file mode 100644 index 000000000..d04ef7b20 --- /dev/null +++ b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/headList.tsx @@ -0,0 +1,59 @@ +import { z } from "zod"; +import type { TableUpperProps } from "../../ruseFcltMng/fcltReg/rainReg"; + +export const pbnstPrfmncSttnHeadListExport: TableUpperProps[] = [ + { + id: "number", + title: "No", + rowSpan: 2, + row: 0 + }, + { + id: "sido", + title: "시도", + rowSpan: 2, + row: 0 + }, + { + id: "gugun", + title: "시군구", + rowSpan: 2, + row: 0 + }, + { + id: "bscFctNm", + title: "시설명", + rowSpan: 2, + row: 0 + }, + { + id: "ruseUtztnFcltNm", + title: "재이용시설명", + rowSpan: 2, + row: 0 + }, + +] + +export const pbnstYearHeadListExport: TableUpperProps[] = [ + { + title: "년도", + colSpan: 3, + row: 0 + }, + { + id: "total", + title: "계", + row: 1 + }, + { + id: "inUsage", + title: "장내용수", + row: 1 + }, + { + id: "outUsage", + title: "장외용수", + row: 1 + }, +] diff --git a/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx new file mode 100644 index 000000000..e47301b48 --- /dev/null +++ b/apps/wr/app/store/prfmncSttn/pbnstPrfmncSttn/index.tsx @@ -0,0 +1,192 @@ +import { fetchType, getFetch, postFectch } from "@/components/lib/api"; +import type { TableUpperProps } from "../../common/type/header"; +import { pbnstPrfmncSttnHeadListExport, pbnstYearHeadListExport } from "./headList"; +import type { FcPrfType, PrfType } from "../../prfmncReg/pbnstPrfmncReg/type"; +import type { pubHasuType, selectLabel } from "../../ruseFcltMng/fcltReg/pbnstReg/type"; +import type { ReturnType } from "@common/business_components"; + +type pbnstPrfmncSttnActions = { + tableHeadMaker: (startYear: number, endYear: number) => void; + pbnstPrfmncInit: (page: string, sggOrCity: string) => void; + pbnstPrfmncSearch: (returnType: ReturnType, swtrmtFcltNm: string, fromDate: string, toDate: string) => void; +} + +const pbnstPrfmncRes: PrfType[] = []; +const prfmncRes: FcPrfType[] = []; + +export type pbnstPrfmncSttnState = { + pbnstPrfmncSttn: { + pbnstPrfHeadList: TableUpperProps[]; + pbnstPrfmncRes: PrfType[]; + prfmncRes: any[]; + isInit: boolean; + rawData: any[]; + selectYearList: selectLabel[] + } +} + +export type pbnstPrfmncSttnType = pbnstPrfmncSttnState & pbnstPrfmncSttnActions; + +export const pbnstPrfmncSttnExport: pbnstPrfmncSttnState = { + pbnstPrfmncSttn: { + pbnstPrfHeadList: [...pbnstPrfmncSttnHeadListExport], + pbnstPrfmncRes: pbnstPrfmncRes, + prfmncRes: prfmncRes, + isInit: false, + rawData: [], + selectYearList: [] + } +} + +const checkWrRegList = async () => { + const wrRegList = await getFetch("wr", `/reuseFc/pubDetailList`); + return wrRegList; +}; +const hasuListFetch = async (page: string, sggOrCity: string) => { + const checkWrRegListRes = await checkWrRegList(); + const rainRes = await postFectch( + `/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`, + 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) + ); + return { + sido: findData?.sido, + gugun: findData?.gugun, + bscFctNm: findData?.bscFctNm, + ruseUtztnFcltNm: item.ruseUtztnFcltNm, + pbnstRuseFcltPk: item.pbnstRuseFcltPk, + }; + }); + return data; +} + +export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions = ( + set: any +) => { + return { + tableHeadMaker: (startYear: number, endYear: number) => { + let yearHeader: TableUpperProps[] = [...pbnstPrfmncSttnHeadListExport]; + const selectList = [] as unknown as selectLabel[] + for (let i = startYear; i <= endYear; i++) { + const yearHead = JSON.parse(JSON.stringify(pbnstYearHeadListExport)); + if (yearHead) { + yearHead.forEach((item: { id?: number; }) => { + if (item.id) { + item.id = i + item.id; + + } + + }) + if (yearHead[0]) + yearHead[0].title = i + "년도" + } + yearHeader = [...yearHeader, ...yearHead] + selectList.push({text: i + "년도", val: String(i)} ) + } + set((state: pbnstPrfmncSttnState) => { + return { + ...state, + pbnstPrfmncSttn: { + pbnstPrfHeadList: [...yearHeader], + selectYearList: selectList + }, + }; + }); + }, + pbnstPrfmncInit: async (page: string, sggOrCity: string) => { + try { + const prfmncRes = await hasuListFetch(page, sggOrCity); + return set((state: pbnstPrfmncSttnState) => ({ + ...state, + pbnstPrfmncSttn: { + ...state.pbnstPrfmncSttn, + prfmncRes: prfmncRes, + isInit: false, + }, + })); + } catch (e) { + console.log(e) + } + }, + pbnstPrfmncSearch: async (returnType: ReturnType, swtrmtFcltNm: string, fromDate: string, toDate: string) => { + let searchUrl = ""; + + if (returnType.sigunValue !== undefined) { + if (swtrmtFcltNm !== "") { + searchUrl = `/prcsFclt/info/1/20/${returnType.partValue}/${returnType.sigunValue}/0/1/SW${'/' + swtrmtFcltNm}`; + } else { + searchUrl = `/prcsFclt/info/1/20/${returnType.partValue}/${returnType.sigunValue}/0/1/SW`; + } + } else { + if (swtrmtFcltNm !== "") { + searchUrl = `/prcsFclt/info/1/20/${returnType.partValue}/${returnType.sidoValue}/0/1/SW${'/' + swtrmtFcltNm}`; + } else { + searchUrl = `/prcsFclt/info/1/20/${returnType.partValue}/${returnType.sidoValue}/0/1/SW`; + } + } + + const pbnstRes = await getFetch( + fetchType.COMMON, + searchUrl + ); + const bscFctCdList = pbnstRes.map((item: any) => { + return item.bscFctCd; + }) + const res = await postFectch( + `/reuseFc/pubDetailList/${fromDate}/${toDate}`, + bscFctCdList, + `wr`, + ) + + let inUsageSum = 0; + let outUsageSum = 0; + let usageSum = 0; + let year = ""; + const yearsData = [] + res.data.forEach((item) => { + item.prfList.forEach((acc) => { + year = acc.ym.substring(0, 4); + inUsageSum = acc.wshwtr + acc.coolUswtr + acc.cleanUswtr + acc.drwtUswtr + + acc.dltnUswtr + acc.ithlRswtr + acc.ithlEtcUswtr + acc.cleanToilUswtr + acc.resn; + outUsageSum = acc.lndwtr + acc.hydUswtr + acc.ugwtChr + acc.farmUswtr + acc.rvrKeepUswtr + acc.indstUswtr; + const yearData = yearsData.find(yearItem => yearItem.year === year && yearItem.pbnstRuseFcltPk == acc.pbnstRuseFcltPk) + + if (yearData) { + yearData.inUsageSum += inUsageSum; + yearData.outUsageSum += outUsageSum; + } else { + const yearVal = { year: year, pbnstRuseFcltPk: acc.pbnstRuseFcltFk } + yearVal[year + 'inUsage'] = inUsageSum; + yearVal[year + 'outUsage'] = outUsageSum; + yearVal[year + 'total'] = inUsageSum + outUsageSum; + yearsData.push(yearVal); + } + + }) + }) + const resData: any[] = [] + pbnstRes.forEach((acc) => { + let data = yearsData.find((item) => item.pbnstRuseFcltPk.substring(0, 11) === acc.bscFctCd) + if (data) { + resData.push({ ...data, ...acc }) + } + }) + + + + return set((state: pbnstPrfmncSttnState) => ({ + ...state, + pbnstPrfmncSttn: { + ...state.pbnstPrfmncSttn, + prfmncRes: resData, + rawData: res.data + }, + })); + } + } +} \ No newline at end of file diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx index f72bf7692..931cd1305 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/bdstReg/index.tsx @@ -2,13 +2,9 @@ import { getFetch } from "@/components/lib/api"; import { TEST_UUID, type customRainBdst } from "../rainReg"; import type { customHtdflBdst } from "../htdflReg"; import type { customRswtBdst } from "../rswtReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; + -type TableUpperProps = { - id: string; - title: string; - upName?: string; - upSequnce?: number; - }; const moUpHeadList: TableUpperProps[] = [ { id: "cityText", title: "시도" }, { id: "sggText", title: "시군구" }, @@ -16,9 +12,6 @@ type TableUpperProps = { { id: "daddr", title: "위치" }, { id: "frstArchPrmsnDt", title: "최초건축허가일" }, { id: "archArea", title: "건축면적", }, - // { id: "archChgYn", title: "여부", upName: "upChangeRe", upSequnce: 1 }, - // { id: "archChgPrmsnDt", title: "허가일", upName: "upChangeRe", upSequnce: 2 }, - // { id: "archChgArea", title: "면적", upName: "upChangeRe", upSequnce: 3 }, ]; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx index a26173ed3..0a51ebb5d 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/htdflReg/index.tsx @@ -1,8 +1,9 @@ import { getFetch, postFectch, putFectch } from "@/components/lib/api"; -import { upHeadList, type chgBuilding, type TableUpperProps } from "../rainReg"; +import { upHeadList, type chgBuilding} from "../rainReg"; import { z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export const hdtflZod = z.object({ bdstInfoPk: z.number().nullish(), diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx index 186bfd3c0..5459c8a52 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/headList.tsx @@ -1,5 +1,5 @@ +import type { TableUpperProps } from "@/app/store/common/type/header"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { TableUpperProps } from "../rainReg"; export const pubFacHeadListExport: TableUpperProps[] = [ { id: "sido", title: "시도" }, @@ -14,12 +14,11 @@ export const pubFacHeadListExport: TableUpperProps[] = [ export const pbnstMngUpHeadListExport: TableUpperProps[] = [ { id: "choose", title: "선택", type: "checkbox" }, - { id: "operMthd", title: "운영방식", edit: true }, + { id: "operMthd", title: "운영방식",type: "select", selectData: "ruseMngMtd" }, { id: "rprtvBzenty", title: "대행업체", edit: true }, { id: "bgngDt", title: "시작일", - upName: "upChangeRe", upSequnce: 1, type: "date", }, @@ -50,7 +49,7 @@ export const pbnstDemandHeadListExport: TableUpperProps[] = [ ]; export const pbnstOrgwtHeadListRxport: TableUpperProps[] = [ - { id: "ruseUtztnFcltNm", title: "운영방식" }, + { id: "ruseUtztnFcltNm", title: "하수처리장명" }, { id: "orgwtWtritQnt", title: "원수취수량" }, { id: "tmsYn", title: "하수처리량TMS 전후" }, { id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​" }, diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx index 22980aa16..89efe821b 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/index.tsx @@ -1,5 +1,4 @@ -import { z } from "zod"; -import { TEST_UUID, type TableUpperProps } from "../rainReg"; +import { TEST_UUID } from "../rainReg"; import { deleteFectch, fetchType, @@ -9,8 +8,6 @@ import { } from "@/components/lib/api"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; import { - exampleData, - fcBizSchema, type customPbnst, type fcBizType, type pbnstInsertIndex, @@ -26,6 +23,7 @@ import { pbnstDemandHeadListExport, fcOrgwtsHeadListExport, } from "./headList"; +import type { TableUpperProps } from "@/app/store/common/type/header"; const selectLabel: SelectDataType[] = [{ text: "test", val: "1" }]; const pubFacHeadList = pubFacHeadListExport; @@ -71,7 +69,6 @@ type pubFacActions = { pbnstRuseFcltUpdate: (ruseRes: customPbnst[]) => void; pbnstRuseBizUpdate: (ruseRes: fcBizType[]) => void; }; - export type pubFacType = pubFacState & pubFacActions; export const pubFacStateExport: pubFacState = { @@ -216,6 +213,7 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { pbnstInsert: async (pbnstRes: customPbnst) => { try { + console.log( ' pbnstRes ' , pbnstRes) const response = await postFectch( `/reuseFc/pubFc`, JSON.stringify( writeRgtrAndMdfr([pbnstRes])) @@ -273,7 +271,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { }; }); - console.log(" pbnstBizCycle ", pbnstBizCycle); return set((state: pubFacState) => ({ ...state, pbnst: { @@ -322,7 +319,6 @@ 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 = @@ -374,6 +370,6 @@ export const pubFacActionsExport: (set: any) => pubFacActions = (set: any) => { } catch (e) { console.log(e); } - }, + } }; }; diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx index 01aac072a..e78040f11 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/pbnstReg/type.tsx @@ -72,7 +72,7 @@ export type fcFileType = z.infer<typeof fcFileSchema>; const pplInstlSchema = z.object({ - ruseFcltBizFk: z.number(), + ruseFcltBizFk: z.number().nullish(), choose:z.boolean().default(false), pdmt: z.string().default(''), ppMqlt: z.string().default(""), @@ -89,7 +89,7 @@ const fcFileSchema = z.object({ mdfr: z.string().nullish(), }); -const fcOperSchema = z.object({ +export const fcOperSchema = z.object({ pbnstRuseFcltOperInfoPk: z.number().nullish(), pbnstRuseFcltFk: z.string().nullish(), operMthd: z.string(), @@ -151,23 +151,22 @@ const dmdColist = z.object({ rgtr: z.string().nullish(), mdfr: z.string().nullish(), pbnstRuseFcltBizPk: z.number(), - pbnstRuseFcltFk: z.string(), + pbnstRuseFcltFk: z.string().nullish(), //telno:z.string().default('') }); - export const fcBizSchema = z.object({ - pbnstRuseFcltBizPk: z.number().default(1), + pbnstRuseFcltBizPk: z.number().nullish(), pbnstRuseFcltFk: z.string().nullish(), superkey: z.string().default("").nullish(), cycl: z.number().default(1), seCd: z.string().default(""), bizMthdCd: z.string().default(""), - instlAprvSncnDt: z.date().nullish(), - bizCmcnDay: z.date().nullish(), + instlAprvSncnDt: z.date().default(new Date()), + bizCmcnDay: z.date().default(new Date()), gvsbs: z.number().default(0), lcep: z.number().default(0), cusrAlotm: z.number().default(0), @@ -245,438 +244,4 @@ export const pbnstRegZod = z.object({ fcFiles: z.array(fcFileSchema).default([]), fcBizs: z.array(fcBizSchema).default([]), fcOpers: z.array(fcOperSchema).default([]), - hasuhasu: z.number().default(0), }); - -//관경 제외 -export const exampleData = [ - { - "swtrmtFcltFk": "11000SW001R", - "pbnstRuseFcltPk": "11000SW001R1", - "ruseUtztnFcltNm":'난지', - "fcltCpct": 123, - "ruseCpct": 123, - "splyExtraCpct": 123, - "hasuhasu": 123, - "fcFiles": [], - "fcBizs": [ - { - "pbnstRuseFcltFk": "11000SW001R1", - "cycl": 1, - "seCd": "123", - "bizMthdCd": "123", - "gvsbs": 123, - "lcep": 123, - "cusrAlotm": 123, - "etc": "123", - "rprcsFcltCpct": 123, - "majorPrcsMsrcCd": "123", - "addr": "123", - "rprcsMthdCd": "123", - "inoutYn": "123", - "mainSplyPumpCpct": 123, - "erctWtrOcrnCpct": 123, - "erctUswtrLinkSpt": "123", - "erctUswtrFcltCpct": 123, - "erctUswtrPrcsMeth": "123", - "erctUswtrPrcsMsrcCd": "123", - "bod": 123, - "grssClfg": 123, - "combResdch": 123, - "trbt": 123, - "smll": 1230, - "crmty": 123, - "tn": 123, - "tph": 1230, - "ph": 123, - "clIonQnt": 123, - "cdtnv": 123, - "pplInstls": [ - { - "ruseFcltBizFk": "", - "choose": false, - "ppMqlt": "PE관", - "pdmt": "D250", - "cpct": "123", - "id": "e1472f7c-7033-44ae-a953-f69e6b90fbc1" - } - ] - - - }, - { - "pbnstRuseFcltFk": "11000SW001R1", - "cycl": 2, - "seCd": "하하", - "bizMthdCd": "호호", - "gvsbs": 12, - "lcep": 12, - "cusrAlotm": 12, - "etc": "1", - "rprcsFcltCpct": 12, - "majorPrcsMsrcCd": "12", - "addr": "12", - "rprcsMthdCd": "12", - "inoutYn": "12", - "mainSplyPumpCpct": 12, - "erctWtrOcrnCpct": 13, - "erctUswtrLinkSpt": "12", - "erctUswtrFcltCpct": 13, - "erctUswtrPrcsMeth": "12", - "erctUswtrPrcsMsrcCd": "12", - "bod": 1, - "grssClfg": 1, - "combResdch": 1, - "trbt": 1, - "smll": 1, - "crmty": 1, - "tn": 1, - "tph": 1, - "ph": 1, - "clIonQnt": 1, - "cdtnv": 1, - "pplInstls": [ - { - "ruseFcltBizFk": "", - "choose": false, - "ppMqlt": "PE관", - "pdmt": "D300", - "cpct": "1", - "id": "e1472f7c-7033-44ae-a953-f69e6b90fbc1" - } - ] - } - ], - "fcOpers": [ - { - "choose": false, - "rgtr": "", - "mdfr": "", - "operMthd": "1", - "rprtvBzenty": "1", - "bgngDt": "20250513", - "endDt": "20250529", - "id": "cbef8f84-33df-406b-a85f-edd2a5d3618e" - } - ] -}, -{ - "swtrmtFcltFk": "11000SW001R", - "ruseUtztnFcltNm":'난지', - "pbnstRuseFcltPk": "11000SW001R2", - "fcltCpct": 123, - "ruseCpct": 123, - "splyExtraCpct": 123, - "hasuhasu": 123, - "fcFiles": [], - "fcBizs": [ - { - "pbnstRuseFcltFk": "11000SW001R2", - "cycl": 1, - "seCd": "123", - "bizMthdCd": "123", - "gvsbs": 123, - "lcep": 123, - "cusrAlotm": 123, - "etc": "123", - "rprcsFcltCpct": 123, - "majorPrcsMsrcCd": "123", - "addr": "123", - "rprcsMthdCd": "123", - "inoutYn": "123", - "mainSplyPumpCpct": 123, - "erctWtrOcrnCpct": 123, - "erctUswtrLinkSpt": "123", - "erctUswtrFcltCpct": 123, - "erctUswtrPrcsMeth": "123", - "erctUswtrPrcsMsrcCd": "123", - "bod": 123, - "grssClfg": 123, - "combResdch": 123, - "trbt": 123, - "smll": 1230, - "crmty": 123, - "tn": 123, - "tph": 1230, - "ph": 123, - "clIonQnt": 123, - "cdtnv": 123, - "pplInstls": [ - { - "ruseFcltBizFk": "", - "choose": false, - "ppMqlt": "PE관", - "pdmt": "D250", - "cpct": "123", - "id": "e1472f7c-7033-44ae-a953-f69e6b90fbc1" - } - ] - } - ], - "fcOpers": [ - { - "choose": false, - "rgtr": "", - "mdfr": "", - "operMthd": "123", - "rprtvBzenty": "123", - "bgngDt": "20250513", - "endDt": "20250529", - "id": "cbef8f84-33df-406b-a85f-edd2a5d3618e" - } - ] -} -] - - - -// [{ -// pbnstRuseFcltPk: 1, -// swtrmtFcltFk: "11000SW001R", -// ruseUtztnFcltNm: "재이용시설 A", -// hasuhasu: 0, -// fcltCpct: "100", -// ruseCpct: "90", -// splyExtraCpct: "10", -// rgtr: TEST_UUID, -// mdfr: TEST_UUID, -// fcFiles: [], -// fcBizs: [ -// { -// pbnstRuseFcltBizPk: 1, -// pbnstRuseFcltFk: 1, -// cycl: "1", -// seCd: "A010", -// bizMthdCd: "M02", -// instlAprvSncnDt: "2022-01-01", -// bizCmcnDay: "2022-02-01", -// gvsbs: "정부지원", -// lcep: "지자체", -// cusrAlotm: "고객", -// etc: "비고 없음", -// totalMoney: "100000000", -// rprcsFcltCpct: "50", -// majorPrcsMsrcCd: "MP01", -// addr: "서울시 종로구", -// rprcsMthdCd: "RP01", -// inoutYn: "Y", -// mainSplyPumpCpct: "30", -// erctWtrOcrnCpct: "5", -// erctUswtrLinkSpt: "있음", -// erctUswtrFcltCpct: "20", -// erctUswtrPrcsMeth: "생물학적", -// erctUswtrPrcsMsrcCd: "EM01", -// wwtEmsnFcltPrmsnYn: "Y", -// tmsInstlYn: "N", -// pbnstDrngInflwExclYn: "Y", -// bod: "30", -// grssClfg: "양호", -// combResdch: "적정", -// trbt: "10", -// clIonQnt: "5", -// smll: "없음", -// crmty: "정상", -// tph: "0.2", -// tn: "2", -// ph: "7.2", -// cdtnv: "100", -// designCst: "1000", -// cstrnSpvsCst: "500", -// fcltSbsdCst: "200", -// wstCst: "300", -// cnstCmcnCst: "1000", -// mntrgEqpmntInstlCst: "150", -// gisDbCst: "200", -// elpwrMtrngCst: "180", -// mchnCst: "700", -// archCst: "400", -// pplCst: "300", -// ruseFcltCst: "5000", -// designCstClcln: "990", -// cstrnSpvsCstClcln: "480", -// fcltSbsdCstClcln: "190", -// wstCstClcln: "280", -// cnstCmcnCstClcln: "980", -// mntrgEqpmntInstlCstClcln: "140", -// gisDbCstClcln: "190", -// elpwrMtrngCstClcln: "170", -// mchnCstClcln: "680", -// archCstClcln: "380", -// pplCstClcln: "290", -// ruseFcltCstClcln: "4800", -// pplInstls: [ -// { -// ruseFcltBizFk: "10", -// pdmt: "D200", -// ppMqlt: "도복장강관", -// cpct: "1", -// }, -// { -// ruseFcltBizFk: "10", -// pdmt: "D100", -// ppMqlt: "PE관", -// cpct: "2", -// }, -// ], -// fcOrgwts: [ -// { -// pbnstRuseFcltBizFk: 1, -// swtrmtFcltFk: "11000SW001R", -// orgwtWtritQnt: "100", -// tmsYn: "Y", -// dschgFmYn: "N", -// dtlPstnExpln: "배출 위치", -// regDt: "20250221", -// rgtr: "admin", -// mdfcnDt: "20250321", -// mdfr: "admin", -// }, -// { -// pbnstRuseFcltBizFk: 1, -// swtrmtFcltFk: "11200PB001R", -// orgwtWtritQnt: "153", -// tmsYn: "Y", -// dschgFmYn: "N", -// dtlPstnExpln: "배출 위치22", -// regDt: "20250221", -// rgtr: "admin", -// mdfcnDt: "20250421", -// mdfr: "admin", -// }, -// ], -// flg: "N", -// rgtr: TEST_UUID, -// mdfr: TEST_UUID, -// }, -// { -// pbnstRuseFcltBizPk: 11, -// pbnstRuseFcltFk: 1, -// cycl: "2", -// seCd: "A011", -// bizMthdCd: "M02", -// instlAprvSncnDt: "2022-01-01", -// bizCmcnDay: "2022-02-01", -// gvsbs: "민간", -// lcep: "지자체", -// cusrAlotm: "고객", -// etc: "비고 없음", -// totalMoney: "100000000", -// rprcsFcltCpct: "50", -// majorPrcsMsrcCd: "MP01", -// addr: "부산시 해운대구", -// rprcsMthdCd: "RP01", -// inoutYn: "Y", -// mainSplyPumpCpct: "30", -// erctWtrOcrnCpct: "5", -// erctUswtrLinkSpt: "있음", -// erctUswtrFcltCpct: "20", -// erctUswtrPrcsMeth: "생물학적", -// erctUswtrPrcsMsrcCd: "EM01", -// wwtEmsnFcltPrmsnYn: "Y", -// tmsInstlYn: "N", -// pbnstDrngInflwExclYn: "Y", -// bod: "30", -// grssClfg: "양호", -// combResdch: "적정", -// trbt: "10", -// clIonQnt: "5", -// smll: "없음", -// crmty: "정상", -// tph: "0.2", -// tn: "2", -// ph: "7.2", -// cdtnv: "100", -// designCst: "1000", -// cstrnSpvsCst: "500", -// fcltSbsdCst: "200", -// wstCst: "300", -// cnstCmcnCst: "1000", -// mntrgEqpmntInstlCst: "150", -// gisDbCst: "200", -// elpwrMtrngCst: "180", -// mchnCst: "700", -// archCst: "400", -// pplCst: "300", -// ruseFcltCst: "5000", -// designCstClcln: "990", -// cstrnSpvsCstClcln: "480", -// fcltSbsdCstClcln: "190", -// wstCstClcln: "280", -// cnstCmcnCstClcln: "980", -// mntrgEqpmntInstlCstClcln: "140", -// gisDbCstClcln: "190", -// elpwrMtrngCstClcln: "170", -// mchnCstClcln: "680", -// archCstClcln: "380", -// pplCstClcln: "290", -// ruseFcltCstClcln: "4800", -// pplInstls: [ -// { -// ruseFcltBizFk: "11", -// pdmt: "관경", -// ppMqlt: "1", -// cpct: "100", -// }, -// { -// ruseFcltBizFk: "11", -// pdmt: "관경", -// ppMqlt: "2", -// cpct: "200", -// }, -// ], -// fcOrgwts: [ -// { -// pbnstRuseFcltBizFk: 11, -// swtrmtFcltFk: "11000SW001R", -// orgwtWtritQnt: "152", -// tmsYn: "Y", -// dschgFmYn: "N", -// dtlPstnExpln: "배출 위치1", -// rgtr: TEST_UUID, -// mdfr: TEST_UUID, -// }, -// { -// pbnstRuseFcltBizFk: 11, -// swtrmtFcltFk: "11200PB001R", -// orgwtWtritQnt: "150", -// tmsYn: "Y", -// dschgFmYn: "N", -// dtlPstnExpln: "배출 위치", -// rgtr: TEST_UUID, -// mdfr: TEST_UUID, -// }, -// ], -// flg: "N", -// rgtr: TEST_UUID, -// mdfr: TEST_UUID, -// }, -// ], -// fcOpers: [ -// { -// pbnstRuseFcltOperInfoPk: 100, -// pbnstRuseFcltFk: 1, -// operMthd: "위탁", -// rprtvBzenty: "기관명", -// bgngDt: new Date("2023-09-30"), -// endDt: new Date("2023-12-31"), -// rgtr: TEST_UUID, -// mdfr: TEST_UUID, -// }, -// { -// pbnstRuseFcltOperInfoPk: 101, -// pbnstRuseFcltFk: 1, -// operMthd: "직영", -// rprtvBzenty: "기관명", -// bgngDt: new Date("2024-11-30"), -// endDt: new Date("2024-12-31"), -// rgtr:TEST_UUID , -// mdfr: TEST_UUID, -// }, -// ], -// } - - - - - -// ] diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx index e7e0a3653..f4e06f8dd 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rainReg/index.tsx @@ -1,7 +1,7 @@ import { getFetch, postFectch, putFectch } from "@/components/lib/api"; import { z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; -import type { SelectDataType } from "@common/business_components/ui"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export const TEST_UUID= '2d4b151d-1828-41e0-91d9-4cd28ea1cc7e' export const rainZod = z.object({ @@ -82,17 +82,6 @@ export type chgBuilding={ mdfr?:string|null; } export type customRainBdst = z.infer<typeof rainZod> -export type TableUpperProps = { - id: string; - title: string; - upName?: string; - upSequnce?: number; - edit?:boolean; - visible?:boolean; - rowSpan?: true; - type?: string; - selectData ?:string; -}; export const upHeadList: TableUpperProps[] = [ { id: "cityText", title: "시도" }, diff --git a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx index 42f13cd31..b0feeb969 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltReg/rswtReg/index.tsx @@ -1,8 +1,9 @@ import { getFetch, postFectch, putFectch } from "@/components/lib/api"; -import { upHeadList, type chgBuilding, type TableUpperProps } from "../rainReg"; +import { upHeadList, type chgBuilding } from "../rainReg"; import { z } from "zod"; import { makeMdfr, makeRstr } from "../bdstReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export const rswtZod = z.object({ bdstInfoPk: z.number().nullish(), diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx index 6caddd40a..8de673f16 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/headList.tsx @@ -1,6 +1,6 @@ import type { z } from "zod"; import type { sttnHeadListType } from "../rainSttn/headList"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; export const htdflSttHeadListExport: z.infer<typeof sttnHeadListType> = [ { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx index 2df318c45..2c86860a2 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/htdflSttn/index.tsx @@ -1,12 +1,10 @@ -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; import { htdflSttHeadListExport, htdflSttNodeListExport } from "./headList"; import type { sttnHeadListType } from "../rainSttn/headList"; import type { z } from "zod"; import { controlHeadView } from "../rainSttn"; import type { customHtdflBdst } from "../../fcltReg/htdflReg"; import { fetchType, getFetch } from "@/components/lib/api"; -import { excelHtdflSttnParsing } from "./excel"; -import { tableData } from "@/components/lib/func/commom"; const htdflSttHeadList = htdflSttHeadListExport; const htdflSttNodeList = htdflSttNodeListExport; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx index a85a009a4..8a1db05a2 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/excel.tsx @@ -5,23 +5,23 @@ export const excelPbnstSttnParsing = (data: any[]): string[][] => { data.forEach((item) => { excelExportData.push([ - item.a, - String(item.aaa), - item.aaaa ?? "", - item.operMngCd ?? "", - String(item.cityText ?? ""), - String(item.sggText ?? ""), - String(item.bdnstNm ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), - String(item.archArea ?? ""), + item.rvbsn, + String(item.lgbsn), + item.mdmbsn ?? "", + item.rgnNm ?? "", + String(item.sido ?? ""), + String(item.gugun ?? ""), + String(item.bscFctNm ?? ""), + String(item.efflWqltStndrdNm ?? ""), + String(item.fctCpc ?? ""), + String(item.tel ?? ""), + String(item.ruseUtztnFcltNm ?? ""), + String(item.fcltCpct ?? ""), + String(item.splyExtraCpct ?? ""), + String(item.ruseCpct ?? ""), + String(item.usageTotal ?? ""), + String(item.inUsage ?? ""), + String(item.outUsage ?? ""), ]) }) return excelExportData; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx index da20d9fc3..9fe7fddc9 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/headList.tsx @@ -1,36 +1,39 @@ import type { sttnHeadListType } from "../rainSttn/headList"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { + CommonTableProps, + TableUpperProps, +} from "@/app/store/common/type/header"; import { z } from "zod"; export const pbnSttHeadListExport: z.infer<typeof sttnHeadListType> = [ - { id: "a", title: "권역", visible: true }, + { id: "rvbsn", title: "권역", visible: true }, { - id: "aaa", + id: "lgbsn", title: "단위유역", visible: true, }, { - id: "aaaa", + id: "mdmbsn", title: "중권역", visible: true, }, - { id: "operMngCd", title: "환경청", visible: true }, + { id: "rgnNm", title: "환경청", visible: true }, { - id: "cityText", + id: "sido", title: "시도", visible: true, }, { - id: "sggText", + id: "gugun", title: "시군구", visible: true, }, - { id: "bdnstNm", title: "시설명", visible: true }, - { id: "locDiv", title: "지역구분", visible: true }, - { id: "phone", title: "전화번호", visible: true }, + { id: "bscFctNm", title: "시설명", visible: true }, + { id: "efflWqltStndrdNm", title: "지역구분", visible: true }, - { id: "fcltQuantity", title: "시설용량(톤/일)", visible: true }, - { id: "rusNm", title: "재이용시설명", visible: true }, + { id: "fctCpc", title: "시설용량(톤/일)", visible: true }, + { id: "tel", title: "전화번호", visible: true }, + { id: "ruseUtztnFcltNm", title: "재이용시설명", visible: true }, { id: "fcltCpct", @@ -38,7 +41,7 @@ export const pbnSttHeadListExport: z.infer<typeof sttnHeadListType> = [ visible: true, }, { - id: "trbt", + id: "splyExtraCpct", title: "하수처리량(m³/일)", visible: true, }, @@ -49,23 +52,23 @@ export const pbnSttHeadListExport: z.infer<typeof sttnHeadListType> = [ }, { - id: "total", + id: "usageTotal", title: "합계", visible: true, }, { - id: "ithlWtr", + id: "inUsage", title: "장내용수", visible: true, }, { - id: "othlWtr", + id: "outUsage", title: "장외용수", visible: true, }, { - id: "mngMeth", + id: "operMthd", title: "운영방식", visible: true, }, @@ -75,12 +78,12 @@ export const pbnSttHeadListExport: z.infer<typeof sttnHeadListType> = [ visible: true, }, { - id: "firstDay", + id: "bgngDt", title: "시작일", visible: true, }, { - id: "LastDay", + id: "endDt", title: "종료일", visible: true, }, @@ -203,7 +206,7 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ rowSpan: 1, colSpan: 1, }, - { + { id: "cityText", title: "시도", upName: "adminDiv", @@ -310,5 +313,240 @@ export const pbnstSttNodeListExport: CommonTableProps[] = [ row: 2, rowSpan: 1, colSpan: 1, - } -]; \ No newline at end of file + }, +]; + +export const ruseFcltNodeListExport: TableUpperProps[] = [ + { id: "cycl", title: "차수", visible: true, row: 1, rowSpan: 3, colSpan: 1 }, + { id: "seCd", title: "구분", visible: true, row: 1, rowSpan: 3, colSpan: 1 }, + { + id: "busiTotal", + title: "사업개요", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 10, + }, + { + id: "ruseFclt", + title: "재처리시설", + visible: true, + row: 1, + rowSpan: 1, + colSpan: 5, + }, + { + id: "mainSply", + title: "메인공급펌프용량", + visible: true, + row: 1, + rowSpan: 3, + colSpan: 1, + }, + { + id: "buziFee", + title: "사업비(백만원)", + visible: true, + row: 2, + rowSpan: 1, + colSpan: 6, + }, + { + id: "instlAprvSncnDt", + title: "설치승인・인가일", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { + id: "bizCmcnDay", + title: "사업준공일", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { + id: "rprcsFcltCpct", + title: "시설용량(m³/일)", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { + id: "rprcsMthdCd", + title: "재처리방식", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { + id: "majorPrcsMsrcCd", + title: "주처리공법", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { + id: "inoutYn", + title: "위치처리장(내・외)", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { + id: "addr", + title: "위치(주소)", + visible: true, + row: 2, + rowSpan: 2, + colSpan: 1, + }, + { id: "gvsbs", title: "국고", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, + { + id: "lcep", + title: "지방비", + visible: true, + row: 3, + rowSpan: 1, + colSpan: 1, + }, + { + id: "cusrAlotm", + title: "민간투자비", + visible: true, + row: 3, + rowSpan: 1, + colSpan: 1, + }, + { + id: "cusrAlotm2", + title: "원인자부담금", + visible: true, + row: 3, + rowSpan: 1, + colSpan: 1, + }, + { id: "etc", title: "기타", visible: true, row: 3, rowSpan: 1, colSpan: 1 }, + { + id: "totalMoney", + title: "합계", + visible: true, + row: 3, + rowSpan: 1, + colSpan: 1, + }, +]; + +export const ruseSplyHeadListExport: TableUpperProps[] = [ + { id: "cycl", title: "차수", visible: true }, + { id: "orgwtWtritQnt", title: "원수취수량", visible: true }, + { id: "tmsYn", title: "하수처리량TMS 전후", visible: true }, + { id: "dschgFmYn", title: "하수처리장 방류 유량계 전·후​", visible: true }, + { id: "dtlPstnExpln", title: "상세위치 설명", visible: true }, +]; + +export const rusePplHeadListExport: TableUpperProps[] = [ + { id: "cycl", title: "차수", visible: true }, + { id: "ppMqlt", title: "관재질", type: "select", visible: true }, + { id: "pdmt", title: "관경", type: "select", visible: true }, + { id: "cpct", title: "연장", edit: true, visible: true }, +]; + +export const ruseGuranteeHeadListExport: TableUpperProps[] = [ + { id: "cycl", title: "차수", visible: true }, + { id: "bod", title: "BOD(mg/L)", visible: true }, + { id: "grssClfg", title: "총대장균군수(개/mg)", visible: true }, + { id: "combResdch", title: "결합잔류염소(mh/L)", visible: true }, + { id: "trbt", title: "탁도(NTU)", visible: true }, + { id: "smll", title: "냄새", visible: true }, + { id: "crmty", title: "색도", visible: true }, + { id: "tn", title: "총질소(mg/L)", visible: true }, + { id: "tph", title: "총인(mg/L)", visible: true }, + { id: "ph", title: "수소이온농도", visible: true }, + { id: "clIonQnt", title: "염화물(mg/L)", visible: true }, + { id: "cdtnv", title: "전기전도도(μs/cm)​", visible: true }, +]; + +export const ruseDmdHeadListExport: TableUpperProps[] = [ + { id: "cycl", title: "차수", visible: true }, + { id: "dmdCoNm", title: "수요처명", visible: true }, + { id: "daddr", title: "위치(주소)", visible: true }, + { id: "useUsgCd", title: "사용용도", visible: true }, + { id: "splyBgngDay", title: "공급시작일", visible: true }, + { id: "splyEndDay", title: "공급종료일", visible: true }, + { id: "splyCpct", title: "공급량(m³/일)", visible: true }, + { id: "splyFmYon", title: "공급유량계 유무", visible: true }, +]; + +export const ruseFcltHeadListExport: CommonTableProps[] = [ + { id: "cycl", title: "차수", visible: true}, + { id: "seCd", title: "구분", visible: true}, + { id: "gvsbs", title: "국고", visible: true }, + { + id: "lcep", + title: "지방비", + visible: true, + }, + { + id: "cusrAlotm", + title: "민간투자비", + visible: true, + }, + { + id: "cusrAlotm2", + title: "원인자부담금", + visible: true, + }, + { id: "etc", title: "기타", visible: true }, + { + id: "totalMoney", + title: "합계", + visible: true, + }, + { + id: "instlAprvSncnDt", + title: "설치승인・인가일", + visible: true, + }, + { + id: "bizCmcnDay", + title: "사업준공일", + visible: true, + }, + { + id: "rprcsFcltCpct", + title: "시설용량(m³/일)", + visible: true, + }, + { + id: "rprcsMthdCd", + title: "재처리방식", + visible: true, + }, + { + id: "majorPrcsMsrcCd", + title: "주처리공법", + visible: true, + }, + { + id: "inoutYn", + title: "위치처리장(내・외)", + visible: true, + }, + { + id: "addr", + title: "위치(주소)", + visible: true, + }, + { + id: "mainSply", + title: "메인공급펌프용량", + visible: true, + }, +]; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx index cb6b8e392..6ce27db86 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/index.tsx @@ -1,33 +1,59 @@ -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps, TableUpperProps } from "@/app/store/common/type/header"; import type { z } from "zod"; -import { - pbnSttHeadListExport, - pbnstSttNodeListExport -} from "./headList"; -import { fetchType, getFetch } from "@/components/lib/api"; +import { pbnSttHeadListExport, pbnstSttNodeListExport, ruseDmdHeadListExport, ruseFcltHeadListExport, ruseFcltNodeListExport, ruseGuranteeHeadListExport, rusePplHeadListExport, ruseSplyHeadListExport } from "./headList"; +import { fetchType, getFetch, postFectch } from "@/components/lib/api"; import { controlHeadView } from "../rainSttn"; import type { sttnHeadListType } from "../rainSttn/headList"; -import type { customPbnst } from "../../fcltReg/pbnstReg/type"; +import type { customPbnst, pubHasuType } from "../../fcltReg/pbnstReg/type"; 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"; const pbnstSttHeadList = pbnSttHeadListExport; const pbnstSttNodeList = pbnstSttNodeListExport; export type pbnstSttnState = { pbnstSttn: { - pbnstSttnRes: customPbnst[]; + pbnstSttnRes: WaterReuseFacility[]; + pbnstSearchData: WaterReuseFacility[]; pbnstSttHeadList: CommonTableProps[]; pbnstSttNodeList: CommonTableProps[]; + pbnstDetail: customPbnst; + ruseFcltNodeList:TableUpperProps[] + ruseSplyHeadList:TableUpperProps[] + rusePplHeadList:TableUpperProps[] + ruseGuranteeHeadList:TableUpperProps[] + ruseDmdHeadList:TableUpperProps[] + ruseFcltHeadList:TableUpperProps[] excelList: []; isInit: boolean; }; }; type pbnstSttnActions = { - pbnstChSttnHead: ( - headList: z.infer<typeof sttnHeadListType>, + pbnstChSttnHead: (headList: z.infer<typeof sttnHeadListType>) => void; + pbnstSttnSearch: ( + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string + ) => void; + pbnSttnInit: ( + page: string, + total: string, + reurnValue: ReturnType, + year: string + ) => void; + getPbnStnDetail: (pbnstRuseFcltPk: string) => void; + pbnNmSearch: ( + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string ) => void; - pbnstSttnSearch: (page: number, total: string, con: string) => void; }; export type pbnstSttnType = pbnstSttnState & pbnstSttnActions; @@ -36,12 +62,121 @@ export const pbnstSttnStateExport: pbnstSttnState = { pbnstSttn: { pbnstSttHeadList: pbnstSttHeadList, pbnstSttNodeList: pbnstSttNodeList, + ruseFcltNodeList:ruseFcltNodeListExport, + ruseSplyHeadList:ruseSplyHeadListExport, + rusePplHeadList:rusePplHeadListExport, + ruseGuranteeHeadList:ruseGuranteeHeadListExport, + ruseDmdHeadList:ruseDmdHeadListExport, + ruseFcltHeadList:ruseFcltHeadListExport, pbnstSttnRes: [], + pbnstDetail: {} as customPbnst, + pbnstSearchData: [], excelList: [], isInit: false, }, }; +const hasuListFetch = async ( + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string +) => { + let url = ""; + if (reurnValue.partValue === "A") { + url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${ + reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue + }/0/1/SW` + } else if (reurnValue.partValue === "R") { + url = `/prcsFclt/info/${page}/${total}/${reurnValue.partValue}/${ + reurnValue.regionValue + ? reurnValue.regionValue + : reurnValue.unitWaterShedValue + ? reurnValue.unitWaterShedValue + : reurnValue.middleRegionValue + }/0/1/SW` + } else { + url = `/prcsFclt/info/${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue}/0/1/SW` + + } + if( searchNm&& searchNm?.length>0){ + url+="/"+searchNm + } + const pbnList = await getFetch(fetchType.COMMON, url); + const arrayList = pbnList.map((item: pubHasuType) => item.bscFctCd); + const getRuseList = await postFectch( + `/reuseFc/pubDetailList/${year}`, + arrayList, + fetchType.WR + ); + const checkWrRegListRes = getRuseList.data; + + const data: WaterReuseFacility[] = checkWrRegListRes.map( + (item: FcPrfType) => { + const findData = pbnList.find( + (fclt: pubHasuType) => + fclt.bscFctCd === item.pbnstRuseFcltPk.substring(0, 11) + ); + + const usage = item.prfList.reduce( + (acc, cur) => { + acc.inUsage += + cur.wshwtr + + cur.coolUswtr + + cur.cleanUswtr + + cur.drwtUswtr + + cur.dltnUswtr + + cur.ithlRswtr + + cur.ithlEtcUswtr + + cur.cleanToilUswtr + + cur.resn; + acc.outUsage += + cur.lndwtr + + cur.hydUswtr + + cur.ugwtChr + + cur.farmUswtr + + cur.rvrKeepUswtr + + cur.indstUswtr; + acc.total = acc.inUsage + acc.outUsage; + + return acc; + }, + { total: 0, inUsage: 0, outUsage: 0 } + ); + + return { + rvbsn: findData?.rvbsn, + lgbsn: findData?.lgbsn, + mdmbsn: findData?.mdmbsn, + rgnNm: findData?.rgnNm, + sido: findData?.sido, + gugun: findData?.gugun, + bscFctNm: findData?.bscFctNm, + efflWqltStndrdNm: findData?.efflWqltStndrdNm, + fctCpc: findData.fctCpc, + tel: findData?.tel ?? "-", + ruseUtztnFcltNm: item.ruseUtztnFcltNm, + fcltCpct: item.fcltCpct, + splyExtraCpct: item.splyExtraCpct, + ruseCpct: item.ruseCpct, + pbnstRuseFcltPk: item.pbnstRuseFcltPk, + usageTotal: usage.total, + inUsage: usage.inUsage, + 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?? "", + searchNm: findData.bscFctNm, + searchPk: findData.bscFctCd, + prfList:item?.prfList??[] + }; + } + ); + return data; +}; + export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( set: any ) => { @@ -49,9 +184,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( pbnstChSttnHead: async ( headList: z.infer<typeof sttnHeadListType> ): Promise<void> => { - - console.log('head ', headList) - const changeNodeList = controlHeadView(headList, pbnstSttNodeList) + const changeNodeList = controlHeadView(headList, pbnstSttNodeList); return set((state: pbnstSttnState) => ({ pbnstSttn: { @@ -61,12 +194,22 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }, })); }, - pbnstSttnSearch: async (page: number, total: string, con: string) => { + pbnstSttnSearch: async ( + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string + ) => { try { - const pbnstSttnRes = await getFetch( - fetchType.WR, - `/reuseFc/waterreuseFc/${page}/${total}/${con}` + const pbnstSttnRes = await hasuListFetch( + page, + total, + reurnValue, + searchNm, + year ); + console.log("pbnstSttnRes", pbnstSttnRes); if (Number(total) > 9000) { const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes); set((state: pbnstSttnState) => { @@ -80,7 +223,6 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( }); } else set((state: pbnstSttnState) => { - return { ...state, pbnstSttn: { @@ -94,5 +236,86 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = ( console.log("error", erTxt); } }, - } -} + pbnSttnInit: async ( + page: string, + total: string, + reurnValue: ReturnType, + year: string + ) => { + try { + + const pbnstSttnRes = await hasuListFetch( + page, + total, + reurnValue, + undefined, + year + ); + + console.log('pbnstSttnRes ', pbnstSttnRes) + set((state: pbnstSttnState) => { + return { + ...state, + pbnstSttn: { + ...state.pbnstSttn, + pbnstSttnRes: pbnstSttnRes, + isInit: false, + }, + }; + }); + } catch (erTxt) { + console.log("error", erTxt); + } + }, + getPbnStnDetail: async (pbnstRuseFcltPk: string) => { + try { + let pbnstDetail = await getFetch("wr", `/reuseFc/pubFc/${pbnstRuseFcltPk}`); + if(pbnstDetail.length>=0){ + pbnstDetail= pbnstDetail.find((item: customPbnst) =>item.pbnstRuseFcltPk === pbnstRuseFcltPk) + } + console.log( 'pbnstDetail ', pbnstDetail) + set((state: pbnstSttnState) => { + return { + ...state, + pbnstSttn: { + ...state.pbnstSttn, + pbnstDetail: pbnstDetail, + }, + }; + }); + } catch (errorHasu) { + console.log(errorHasu); + } + }, + pbnNmSearch: async ( + page: string, + total: string, + reurnValue: ReturnType, + searchNm: string | undefined, + year: string + ) => { + try { + + const pbnstSttnRes = await hasuListFetch( + page, + total, + reurnValue, + searchNm, + year + ); + + set((state: pbnstSttnState) => { + return { + ...state, + pbnstSttn: { + ...state.pbnstSttn, + pbnstSearchData: pbnstSttnRes, + }, + }; + }); + } catch (e) { + console.log(e); + } + }, + }; +}; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx new file mode 100644 index 000000000..e4e86da5d --- /dev/null +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type.tsx @@ -0,0 +1,27 @@ +import type { PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; + +export type WaterReuseFacility = { + bscFctNm: string; // 기본시설명 (예: "난지") + efflWqltStndrdNm: string; // 방류수 수질 기준명 (예: "500톤 이상(Ⅲ지역)") + fcltCpct: number; // 시설 용량 (숫자형, 예: 1) + fctCpc: string; // 시설 처리 능력 (예: "2360000") + gugun: string; // 구군 정보 (예: " ") + inUsage: number; // 유입량 (예: 1387) + lgbsn: string; // 대수계 (예: "한강본류") + mdmbsn: string; // 중권역 (예: "한강서울") + outUsage: number; // 유출량 (예: 900) + pbnstRuseFcltPk: string; // 공공하수 재이용 시설 PK (예: "11000SW001R1") + rgnNm: string; // 관할 기관명 (예: "한강유역환경청") + ruseCpct: number; // 재이용 가능 용량 (예: 123) + ruseUtztnFcltNm: string; // 재사용 활용 시설명 (예: "난지 재사용") + rvbsn: string; // 소수계 (예: "한강") + sido: string; // 시도 정보 (예: "서울특별시") + splyExtraCpct: number; // 추가 공급 용량 (예: 123) + tel: string; // 전화번호 (예: "-") + usageTotal: number; // 총 사용량 (예: 2287) + operMthd: string; + rprtvBzenty: string; + bgngDt: string; + endDt: string; + prfList:PrfType[]; +}; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx index 314997b4f..7db00678d 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/headList.tsx @@ -1,4 +1,4 @@ -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; import { z } from "zod"; export const sttnHeadListType = z.array( diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx index 53c4fe36e..853298d51 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rainSttn/index.tsx @@ -12,7 +12,7 @@ import { rainSttnDetailNodeListExport, } from "./headList"; import type { z } from "zod"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; // 테이블 헤드 리스트 const rainSttHeadList = rainSttHeadListExport; diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx index 2e901b000..804617ad8 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/headList.tsx @@ -1,6 +1,6 @@ import type { z } from "zod"; import type { sttnHeadListType } from "../rainSttn/headList"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; export const rswtSttHeadListExport: z.infer<typeof sttnHeadListType> = [ { diff --git a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx index b48fc3eae..05c845fde 100644 --- a/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx +++ b/apps/wr/app/store/ruseFcltMng/fcltSttn/rswtSttn/index.tsx @@ -1,4 +1,4 @@ -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; import type { customRswtBdst } from "../../fcltReg/rswtReg"; import type { sttnHeadListType } from "../rainSttn/headList"; import type { z } from "zod"; diff --git a/apps/wr/app/store/stats/matStat/headList.tsx b/apps/wr/app/store/stats/matStat/headList.tsx new file mode 100644 index 000000000..881662774 --- /dev/null +++ b/apps/wr/app/store/stats/matStat/headList.tsx @@ -0,0 +1,68 @@ +import type { TableUpperProps } from "../../common/type/header"; + +export const matStatHeadListExport :TableUpperProps[]=[ + { + id: "시도", + title: "시도", + row:0, + rowSpan:2 + }, + { + id: "개소", + title: "개소", + row:0, + rowSpan:2 + }, + { + id: "요구수량", + title: "요구수량", + row:0, + rowSpan:2 + }, + + + { + id: "용도", + title: "용도", + row:0, + colSpan:6 + }, + { + id: "조경용수", + title: "조경용수", + row:1, + }, + { + id: "청소화장실용수", + title: "청소화장실용수", + row:1, + }, + { + id: "농업용수", + title: "농업용수", + row:1, + }, + { + id: "공업용수", + title: "공업용수", + row:1, + }, + { + id: "친수용수", + title: "친수용수", + row:1, + }, + { + id: "기타", + title: "기타", + row:1, + }, + { + id: "사업비", + title: "사업비(천원)", + row:0, + rowSpan:2 + }, + + +] \ No newline at end of file diff --git a/apps/wr/app/store/stats/matStat/index.tsx b/apps/wr/app/store/stats/matStat/index.tsx new file mode 100644 index 000000000..3f2e5813f --- /dev/null +++ b/apps/wr/app/store/stats/matStat/index.tsx @@ -0,0 +1,28 @@ +import type { TableUpperProps } from "../../common/type/header"; +import { matStatHeadListExport } from "./headList"; + +type matStatActions = { +} + + +export type matStatState = { + matStat: { + matStatHeadList:TableUpperProps[] + } +} + +export type matStatType = matStatState & matStatActions; + +export const matStatExport: matStatState = { + matStat: { + matStatHeadList:matStatHeadListExport + } +} + +export const matStatActionsExport: (set: any) => matStatActions = ( + set: any +) => { + return { + + } +} \ No newline at end of file diff --git a/apps/wr/app/store/stats/rainStat/headList.tsx b/apps/wr/app/store/stats/rainStat/headList.tsx new file mode 100644 index 000000000..cc5386589 --- /dev/null +++ b/apps/wr/app/store/stats/rainStat/headList.tsx @@ -0,0 +1,70 @@ +import type { TableUpperProps } from "../../common/type/header"; + +export const rainStatHeadListExport: TableUpperProps[] = [ + { + id: "시도", + title: "시도", + row:0, + rowSpan:2 + }, + { + id: "개소", + title: "개소", + row:0, + rowSpan:2 + }, + { + id: "설치비", + title: "설치비(백만원)", + row:0, + rowSpan:2 + }, + { + id: "저류조용량", + title: "저류조용량(m³/년)", + row:0, + rowSpan:2 + }, + { + id: "이용용도", + title: "이용용도", + row:0, + colSpan:6 + }, + { + id: "조경용수", + title: "조경용수", + row:1, + }, + { + id: "청소화장실용수", + title: "청소화장실용수", + row:1, + }, + { + id: "농업용수", + title: "농업용수", + row:1, + }, + { + id: "공업용수", + title: "공업용수", + row:1, + }, + { + id: "친수용수", + title: "친수용수", + row:1, + }, + { + id: "기타", + title: "기타", + row:1, + }, + { + id: "연간운영비", + title: "연간운영비(백만원/년)", + row:0, + rowSpan:2 + }, +]; diff --git a/apps/wr/app/store/stats/rainStat/index.tsx b/apps/wr/app/store/stats/rainStat/index.tsx new file mode 100644 index 000000000..a50d54d58 --- /dev/null +++ b/apps/wr/app/store/stats/rainStat/index.tsx @@ -0,0 +1,28 @@ +import type { TableUpperProps } from "../../common/type/header"; +import { rainStatHeadListExport } from "./headList"; + +type rainStatActions = { +} + + +export type rainStatState = { + rainStat: { + rainStatHeadList:TableUpperProps[] + } +} + +export type rainStatType = rainStatState & rainStatActions; + +export const rainStatExport: rainStatState = { + rainStat: { + rainStatHeadList:rainStatHeadListExport + } +} + +export const rainStatActionsExport: (set: any) => rainStatActions = ( + set: any +) => { + return { + + } +} \ No newline at end of file diff --git a/apps/wr/app/store/stats/rswtStat/headList.tsx b/apps/wr/app/store/stats/rswtStat/headList.tsx new file mode 100644 index 000000000..2c8aebec9 --- /dev/null +++ b/apps/wr/app/store/stats/rswtStat/headList.tsx @@ -0,0 +1,101 @@ +import type { TableUpperProps } from "../../common/type/header"; + +export const rswtStatHeadListExport :TableUpperProps[]=[ + { + id: "시도", + title: "시도", + row:0, + rowSpan:2 + }, + { + id: "개소", + title: "개소", + row:0, + rowSpan:2 + }, + { + id: "시설현황", + title: "시설현황", + row:0, + colSpan:2 + }, + { + id: "건축연면적(m³)", + title: "건축연면적(m³)", + row:1, + }, + { + id: "처리용량", + title: "처리용량(m³)", + row:1, + }, + { + id: "물사용량", + title: "물사용량(m³/년)", + row:0, + rowSpan:2 + }, + { + id: "청소화장실용수", + title: "중수도+대체수이용량(m³/년)", + row:0, + rowSpan:2 + }, + { + id: "중수도이용량", + title: "중수도이용량(m³/년)", + row:0, + rowSpan:2 + }, + { + id: "대체수이용량", + title: "대체수이용량(m³/년)", + row:0, + rowSpan:2 + }, + + { + id: "용도", + title: "용도", + row:0, + colSpan:6 + }, + { + id: "조경용수", + title: "조경용수", + row:1, + }, + { + id: "청소화장실용수", + title: "청소화장실용수", + row:1, + }, + { + id: "농업용수", + title: "농업용수", + row:1, + }, + { + id: "공업용수", + title: "공업용수", + row:1, + }, + { + id: "친수용수", + title: "친수용수", + row:1, + }, + { + id: "기타", + title: "기타", + row:1, + }, + { + id: "연간운영비", + title: "연간운영비(백만원/년)", + row:0, + rowSpan:2 + }, + + +] \ No newline at end of file diff --git a/apps/wr/app/store/stats/rswtStat/index.tsx b/apps/wr/app/store/stats/rswtStat/index.tsx new file mode 100644 index 000000000..652917bc3 --- /dev/null +++ b/apps/wr/app/store/stats/rswtStat/index.tsx @@ -0,0 +1,28 @@ +import type { TableUpperProps } from "../../common/type/header"; +import { rswtStatHeadListExport } from "./headList"; + +type rswtStatActions = { +} + + +export type rswtStatState = { + rswtStat: { + rswtStatHeadList:TableUpperProps[] + } +} + +export type rswtStatType = rswtStatState & rswtStatActions; + +export const rswtStatExport: rswtStatState = { + rswtStat: { + rswtStatHeadList:rswtStatHeadListExport + } +} + +export const rswtStatActionsExport: (set: any) => rswtStatActions = ( + set: any +) => { + return { + + } +} \ No newline at end of file diff --git a/apps/wr/app/store/store.tsx b/apps/wr/app/store/store.tsx index 297983882..4557662f8 100644 --- a/apps/wr/app/store/store.tsx +++ b/apps/wr/app/store/store.tsx @@ -86,11 +86,17 @@ import { import { rswtChkStateExport, rswtChkSttnActionsExport, type rswtChkSttnState, type rswtChkSttnType } from "./prfmncSttn/chkgdnSttn/rswtChkgdnSttn"; import { pbnstSttnActionsExport, pbnstSttnStateExport, type pbnstSttnState, type pbnstSttnType } from "./ruseFcltMng/fcltSttn/pbnstSttn"; import { coSttnActionsExport, coSttnStateExport, type coSttnState, type coSttnType } from "./matDmd/coSttn"; // 옮겨야함 -import { ldrmntCoSttnActionsExport, ldrmntCoSttnStateExport, type ldrmntCoSttnState, type ldrmntCoSttnType } from "./matDmd/ldrmntCoSttn"; // 옮겨야함 import { searchActions, type comFcltActions, type comFcltState } from "./common/searchCode"; import { pbnstPrfmncActionsExport, pbnstPrfmncStateExport, type pbnstPrfmncState, type pbnstPrfmncType } from "./prfmncReg/pbnstPrfmncReg"; import { coRvwActionsExport, coRvwStateExport, type coRvwState, type coRvwType } from "./matDmd/coMatRvw"; import { ruseHstryActionsExport, ruseHstryStateExport, type ruseHstryState, type ruseHstryType } from "./matDmd/ruseRvwHstry"; +import { pbnstPrfmncSttnActionsExport, pbnstPrfmncSttnExport, type pbnstPrfmncSttnState, type pbnstPrfmncSttnType } from "./prfmncSttn/pbnstPrfmncSttn"; +import { drgtActionsExport, drgtStateExport, type drgtState, type drgtType } from "./matDmd/drgtSttn"; +import { ruseCaseActionsExport, ruseCaseStateExport, type ruseCaseType, type ruseCaseState } from "./matDmd/ruseCaseMng"; +import { rainStatActionsExport, rainStatExport, type rainStatState, type rainStatType } from "./stats/rainStat"; +import { type rswtStatType, type rswtStatState, rswtStatExport, rswtStatActionsExport } from "./stats/rswtStat"; +import { matStatActionsExport, matStatExport, type matStatState, type matStatType } from "./stats/matStat"; +import { ldrmntActionsExport, ldrmntStateExport, type ldrmntState, type ldrmntType } from "./matDmd/ldrmntCoSttn"; export type WrStore = comCodeType & pubFacType & @@ -109,10 +115,16 @@ export type WrStore = comCodeType & pbnstSttnType& comFcltActions&comFcltState& coSttnType& // 옮겨야함 - ldrmntCoSttnType& // 옮겨야함 + ldrmntType& // 옮겨야함 pbnstPrfmncType& coRvwType& - ruseHstryType + ruseHstryType& + pbnstPrfmncSttnType& + drgtType& + ruseCaseType& + rainStatType& + rswtStatType& + matStatType ; export const StoreZus = ( @@ -132,10 +144,16 @@ export const StoreZus = ( rswtChkSttnState & pbnstSttnState& coSttnState& // 옮겨야함 - ldrmntCoSttnState& // 옮겨야함 + ldrmntState& // 옮겨야함 pbnstPrfmncState& coRvwState& - ruseHstryState + ruseHstryState& + pbnstPrfmncSttnState& + drgtState& + ruseCaseState& + rainStatState& + rswtStatState& + matStatState = { ...comCodeStateExport, ...pubFacStateExport, @@ -153,10 +171,16 @@ export const StoreZus = ( ...rswtChkStateExport, ...pbnstSttnStateExport, ...coSttnStateExport, // 옮겨야함 - ...ldrmntCoSttnStateExport, // 옮겨야함 + ...ldrmntStateExport, // 옮겨야함 ...pbnstPrfmncStateExport, ...coRvwStateExport, ...ruseHstryStateExport, + ...pbnstPrfmncSttnExport, + ...drgtStateExport, + ...ruseCaseStateExport, + ...rainStatExport, + ...rswtStatExport, + ...matStatExport } ) => { return createStore<WrStore>()((set) => { @@ -185,10 +209,16 @@ export const StoreZus = ( ...rswtChkSttnActionsExport(set), ...pbnstSttnActionsExport(set), ...coSttnActionsExport(set), // 옮겨야함 - ...ldrmntCoSttnActionsExport(set), // 옮겨야함 + ...ldrmntActionsExport(set), // 옮겨야함 ...pbnstPrfmncActionsExport(set), ...coRvwActionsExport(set), ...ruseHstryActionsExport(set), + ...pbnstPrfmncSttnActionsExport(set), + ...drgtActionsExport(set), + ...ruseCaseActionsExport(set), + ...rainStatActionsExport(set), + ...rswtStatActionsExport(set), + ...matStatActionsExport(set) }; }); }; diff --git a/apps/wr/components/lib/func/TableData.tsx b/apps/wr/components/lib/func/TableData.tsx index c969c613c..c21a7e70a 100644 --- a/apps/wr/components/lib/func/TableData.tsx +++ b/apps/wr/components/lib/func/TableData.tsx @@ -1,6 +1,6 @@ +import type { TableUpperProps } from "@/app/store/common/type/header"; import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; import { Checkbox, Input, TableCell, TableRow } from "@common/components/ui"; export const rainChkTableData = (chkData: rainChkZodType[]) => { @@ -101,7 +101,7 @@ export const chRowspanTable = ( .map((head) => { const key = head.id; - const isMerged = head.rowSpan; + const isMerged = head.mergeCell; const value = row[key]; // 병합 대상이면 중복 렌더링 여부 판단 if (isMerged) { @@ -184,4 +184,65 @@ export const headVisibleChange = (headList: TableUpperProps[], isEdit: boolean) } }); +} + + +const handleChange = ( + rowIndex: number, + field: any, + value: string | number, + setInputData: (data:any) => void +) => { + if(Number(value) < 0 ||! Number(value)){ + value = 0; + }else{ + value = Number(value); + } + setInputData((prevData:any) => + prevData?.map((row:any, index: number) => { + if (index === rowIndex) { + return { + ...row, + [field ]: value, + }; + } + return row; + }) + ); +}; +; + + + +export const InputTableBody = (chgRes: any[] | [] ,headList:TableUpperProps[], setInputData: (data: any[]) => void) => { + return ( + <> + {chgRes.map((data, dataIndex) => ( + <TableRow key={dataIndex + "row"}> + {headList.map((head, headIndex) => ( + <TableCell key={head.id + headIndex} className="w-36" > + {head.edit ===true && data.edit !==false? + <Input + className={`${head.id !== "utztnUsgCd" ? "text-right" : "text-center"} !text-xl h-10 w-full`} + onChange={(e) => + handleChange(dataIndex, head.id, e.target.value,setInputData) + } + value={data[head.id as keyof any] ?? ""} + /> : ( + <div + className={` + ${head.id !== "utztnUsgCd" ? "text-right" : "text-center"} + !text-xl w-full h-10 + `} + > + {data[head.id as keyof any] ?? ""} + </div> + ) + } + </TableCell> + ))} + </TableRow> + ))} + </> + ); } \ No newline at end of file diff --git a/apps/wr/components/lib/func/commom.tsx b/apps/wr/components/lib/func/commom.tsx index 7add88e64..1d43f9aa0 100644 --- a/apps/wr/components/lib/func/commom.tsx +++ b/apps/wr/components/lib/func/commom.tsx @@ -4,7 +4,6 @@ import { type SelectDataType, type ReturnType, filePickedBlobArray, - sheetParameter, } from "@common/business_components/ui"; import type { RefObject } from "react"; @@ -21,6 +20,7 @@ export const getCity = (val: string, sggCd: SelectDataType[]) => { // cd text 넣기 export const tableData = (data: any, code: comCodeState) => { const chCode = code.code; + return data?.map( (item: { sggCd: string; @@ -29,17 +29,16 @@ export const tableData = (data: any, code: comCodeState) => { }) => { let returnData = {}; const sggText = chCode.sggCd.find( - (cd) => cd.val === String(item.sggCd) + (cd) => cd.val === String(item.sggCd).trim() )?.text; const cityText = chCode.cityCd.find( - (cd) => cd.val === String(item.ctpvCd) + (cd) => cd.val === String(item.ctpvCd).trim() )?.text; if (item?.reuseBuilding?.length > 0) { const bdsgUsgText = chCode.bdstUsgCd.find( (cd) => Number(cd.val) === item?.reuseBuilding[0]?.bdstUsgCd )?.text; const lawTrgtYn = item?.reuseBuilding[0]?.lawTrgtYn; - returnData = { ...item, sggText: sggText ?? "없음", @@ -54,7 +53,6 @@ export const tableData = (data: any, code: comCodeState) => { cityText: cityText ?? "없음", }; } - return returnData; } ); @@ -82,7 +80,7 @@ export const excelDownload = ( export const excelArrayDownload = ( fileNm: string, sampleFile: string, - sheetArray: [typeof sheetParameter] + sheetArray: [] ) => { if (!sheetArray) return; fetch(`/${sampleFile}`, {}).then(async (response) => { diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx index 04e17867c..f5a7a0530 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm.tsx @@ -75,6 +75,7 @@ export function PbnstBuseForm({ const [ppiYn, setPpiYn] = useState("Y"); const [isFcOrgwts, setIsFcOrgwts] = useState<boolean>(false); const [sumCpct, setSumCpct] = useState<number>(0); + const [getDmdList, setGetFmdList] = useState<number>(0); const [isDmdModal, setIsDmdModal] = useState<{ isMoal: boolean; data: DemandCompType; @@ -95,6 +96,7 @@ export function PbnstBuseForm({ pbnst.pbnsUpdateIndex.biz ] : fcBizSchema.parse({}), + mode: "onChange", }); // 2. Define a submit handler. @@ -157,7 +159,11 @@ export function PbnstBuseForm({ useEffect(() => { const formData = form.watch(); + //console.log(" formData.fcDemands. ", formData.fcDemands); formData.pplInstls = ref.current ? [...ref.current] : []; // ← form 내부 상태 기준으로 복사 + //formData.fcDemands = fcDemands; + //formData.fcOrgwts = fcOrgwtFiled; + console.log(" formData. ", formData); if (formType === "reg") { if ( firstBizData && @@ -172,16 +178,11 @@ export function PbnstBuseForm({ form.setValue("cycl", firstBizData[0].cycl); } pbnstBizData(formData as fcBizType); - }else if(formType === "update"){ - - console.log('formdata ', formData) + } else if (formType === "update") { pbnstBizData(formData as fcBizType); - - } }, [firstBizData, form.formState, formType, pbnst.pbnstRes]); - useEffect(() => { if (ppiYn === "N") { form.setValue("pplInstls", []); @@ -194,7 +195,8 @@ export function PbnstBuseForm({ const plusHist = () => { const regData = { - ruseFcltBizFk: ref.current?.[0]?.ruseFcltBizFk ?? form.getValues('pbnstRuseFcltBizPk'), + ruseFcltBizFk: + ref.current?.[0]?.ruseFcltBizFk ?? form.getValues("pbnstRuseFcltBizPk"), choose: false, ppMqlt: "", pdmt: "", @@ -219,8 +221,9 @@ export function PbnstBuseForm({ splyEndDay: new Date(), splyCpct: 0, splyFmYn: "Y", - pbnstRuseFcltBizPk: form.getValues('pbnstRuseFcltBizPk'), - pbnstRuseFcltFk: form.getValues('pbnstRuseFcltFk')??'', + pbnstRuseFcltBizPk: form.getValues("pbnstRuseFcltBizPk"), + pbnstRuseFcltFk: form.getValues("pbnstRuseFcltFk") ?? "", + dmdInfoFk: "", //telno: "", }); }; @@ -256,6 +259,13 @@ export function PbnstBuseForm({ } }, [code]); + useEffect(() => { + console.log(" fcDemands ", fcDemands); + }, [fcDemands]); + + useEffect(() => { + console.log(" demandCompList ", demandCompList); + }, [demandCompList]); useEffect(() => { console.log("form errors:", form.formState.errors); }, [form.formState.errors]); @@ -457,56 +467,74 @@ export function PbnstBuseForm({ render={({ field: f }) => ( <FormUi label="수요처명"> <SearchInputText - label={undefined} + label={"수요처"} initValue={f.value} setValue={(val) => { f.onChange(val); - - if (val) getDemandCompList(val, 3); + console.log("val ", val); + if (val && val.length > 2) { + getDemandCompList(val, 3); + } }} - setRtnData={(valList: PbnstDemandComType[]) => { - console.log('valList[0] ', index) - if ( - valList.length > 0 && - valList['0'] - ) { - form.setValue( - `fcDemands.${index}.pbnstRuseFcltBizPk`, - form.getValues('pbnstRuseFcltBizPk') + setRtnData={(valList: any) => { + if (valList) { + console.log( + " form.getValues ", + form.getValues("pbnstRuseFcltBizPk") ); + const bizPk = + form.getValues("pbnstRuseFcltBizPk"); + + if (form.getValues("pbnstRuseFcltBizPk")) { + form.setValue( + `fcDemands.${index}.pbnstRuseFcltBizPk`, + bizPk + ); + } form.setValue( `fcDemands.${index}.pbnstRuseFcltFk`, - form.getValues('pbnstRuseFcltFk')??'' - + form.getValues("pbnstRuseFcltFk") ?? "" ); form.setValue( `fcDemands.${index}.dmdCoNm`, - valList['0'].dmdCoNm + valList.dmdCoNm ); form.setValue( `fcDemands.${index}.daddr`, - valList['0'].daddr + valList.daddr ); form.setValue( `fcDemands.${index}.useUsgCd`, - valList['0'].useUsgCd + valList.useUsgCd ); form.setValue( `fcDemands.${index}.splyCpct`, - valList['0'].splyCpct + valList.splyCpct ); form.setValue( `fcDemands.${index}.splyFmYn`, - valList['0'].splyFmYn ?? "Y" + valList.splyFmYn ?? "Y" ); - form.setValue( - `fcDemands.${index}.dmdInfoPk`, - valList['0'].dmdInfoPk ?? "Y" + `fcDemands.${index}.dmdInfoFk`, + valList.dmdInfoPk?.toString() ?? "" ); - } + // field.daddr=valList.daddr; + // field.useUsgCd=valList.useUsgCd; + // field.splyCpct=valList.splyCpct; + // field.splyFmYn=valList.splyFmYn; + // field.dmdInfoFk=valList.dmdInfoPk?.toString(); + // field.dmdCoNm=valList.dmdCoNm; + } }} + searchList={demandCompList?.map((item) => { + return { + ...item, + searchNm: item.dmdCoNm, + searchPk: item.dmdInfoPk, + }; + })} ></SearchInputText> </FormUi> )} @@ -536,15 +564,13 @@ export function PbnstBuseForm({ name={`fcDemands.${index}.useUsgCd`} render={({ field: f }) => ( <FormUi label="사용용도"> - <SelectBox + <SelectBox label={""} selectClass={""} className="w-full" selectArray={code.dmdUszCd} - onSelectValue={(val: string | number) => - f.onChange(val) - } - value={f.value} + onSelectValue={f.onChange} + value={f.value ?? code.dmdUszCd[0]?.val} /> </FormUi> )} @@ -662,7 +688,6 @@ export function PbnstBuseForm({ getDemandCompList(searchText, pageCnt); }} rtnInputData={(data) => { - console.log(" rtn data ", data); regDemandCompany(data as DemandCompType); setIsDmdModal({ isMoal: false, data: data as DemandCompType }); }} diff --git a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx index 3f0776a4e..d1eb8ed3f 100644 --- a/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx +++ b/apps/wr/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm.tsx @@ -1,7 +1,7 @@ "use client"; import { useWrStore } from "@/app/store"; -import { FileUpload, FormUi, SelectBox } from "@common/business_components/ui"; +import { FileUpload, FormUi, SelectBox, type SelectDataType } from "@common/business_components/ui"; import { Form, FormField } from "@common/business_components/ui/form"; import { Button, Input } from "@common/components"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -18,7 +18,6 @@ import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTab import { pbnstRegZod, type customPbnst, - type fcBizType, type fcFileType, type operType, type selectLabel, @@ -39,6 +38,7 @@ export function PbnstMngForm({ firstFcltData?: customPbnst; }) { const { + code, pbnst, pbnstInsert, pbnstMngData, @@ -46,7 +46,7 @@ export function PbnstMngForm({ fileDownLoad, getBizCycle, getpbnstInsertIndex, - appendRuseFclt + appendRuseFclt, } = useWrStore((state) => state); const [regFileList, setRegFileList] = useState<fcFileType[] | null>(null); @@ -54,6 +54,7 @@ export function PbnstMngForm({ const [relationfiles, setRelationFiles] = useState<FilesType[] | null>(null); const [fcltNm, setFcltNm] = useState<selectLabel[] | null>(null); const [fcOpresData, setFcOpresData] = useState<operType[] | null>(null); + const [mngMtdCode, setMngMtdCode] = useState<{ name: string, val: SelectDataType[] }[]>(); const [progress, setProgress] = useState(0); //const new File([] as BlobPart[], "") 파일 다운로드 활용 @@ -69,7 +70,17 @@ export function PbnstMngForm({ pbnst.pbnsUpdateIndex.mng >= 0 && pbnst.pbnstRes ? pbnst.pbnstRes[pbnst.pbnsUpdateIndex.mng] - : pbnstRegZod.parse({}), + : formType === "sttn" && firstFcltData + ? { + ruseUtztnFcltNm: firstFcltData?.ruseUtztnFcltNm, + fcltCpct: firstFcltData?.fcltCpct, + ruseCpct: firstFcltData?.ruseCpct, + splyExtraCpct: firstFcltData?.splyExtraCpct, + fcOpers: firstFcltData?.fcOpers, + fcFiles: firstFcltData?.fcFiles, + } + : pbnstRegZod.parse({}), + mode: "onChange", }); const { fields: fcOpersField, @@ -88,16 +99,16 @@ export function PbnstMngForm({ if (pbnst.pbnstRes && pbnst.pbnstRes[val]) { getBizCycle(pbnst.pbnstRes[val]); form.reset(pbnst.pbnstRes[val]); + getpbnstInsertIndex({ ...pbnst.pbnsUpdateIndex, mng: val }); } }; - const plusHist = () => { const currentTableDataFromRef = ref.current ? [...ref.current] : []; const regData = { choose: false, - pbnstRuseFcltFk:form.getValues('pbnstRuseFcltPk')??"", + pbnstRuseFcltFk: form.getValues("pbnstRuseFcltPk") ?? "", rgtr: "", mdfr: "", operMthd: "", @@ -193,15 +204,13 @@ export function PbnstMngForm({ // 등록할때 신규 값을 계속 가지고 있으려고 useEffect(() => { if ( + formType === "reg" && firstFcltData && (form.getValues("swtrmtFcltFk") === "" || form.getValues("swtrmtFcltFk") === undefined) ) { form.setValue("swtrmtFcltFk", firstFcltData.swtrmtFcltFk); - form.setValue( - "pbnstRuseFcltPk", - String(firstFcltData.swtrmtFcltFk + "1") - ); + form.setValue("pbnstRuseFcltPk", String(firstFcltData.pbnstRuseFcltPk)); form.setValue("fcBizs", firstFcltData.fcBizs); } }, [firstFcltData]); @@ -249,40 +258,38 @@ export function PbnstMngForm({ } } }, [pbnst.pbnsUpdateIndex, pbnst.pbnstRes, formType, getBizCycle]); - + //신규 등록시 입력할때 데이터 넣기 useEffect(() => { const formData = form.watch(); formData.fcOpers = ref.current ? [...ref.current] : []; formData.fcFiles = regFileList ? [...regFileList] : []; if (formType === "reg") { + console.log("formData ", formData); pbnstMngData([formData] as customPbnst[]); - } else if (formType === "update"){ - const updateRes = pbnst.pbnstRes?.map((item)=>{ - if(item.pbnstRuseFcltPk === item.pbnstRuseFcltPk){ - item=formData as customPbnst + } else if (formType === "update") { + const updateRes = pbnst.pbnstRes?.map((item) => { + if (item.pbnstRuseFcltPk === item.pbnstRuseFcltPk) { + item = formData as customPbnst; } - return item - }) + return item; + }); pbnstMngData(updateRes as customPbnst[]); } }, [form.formState, regFileList, formType, pbnst.pbnstRes]); useEffect(() => { - pbnstMngData(pbnst.pbnstMngRegData); + // pbnstMngData(pbnst.pbnstMngRegData); }, [pbnst.pbnstMngRegData]); useEffect(() => { - - if ( pbnst.pbnstRes && pbnst.pbnstRes?.length<= 0) return; + 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 (fcltNmList) setFcltNm(fcltNmList); }, [pbnst.pbnstRes]); // 2. Define a submit handler. @@ -292,9 +299,6 @@ export function PbnstMngForm({ pbnstInsert(values); } - - - useEffect(() => { if (relationfiles) { setRegFileList(regFileFilter(relationfiles, "계통도", regFileList || [])); @@ -310,6 +314,12 @@ export function PbnstMngForm({ console.log("form errors:", form.formState.errors); }, [form.formState.errors]); + useEffect(() => { + if(code.ruseMngMtd){ + setMngMtdCode( [{name:"ruseMngMtd",val:code.ruseMngMtd}]) + } + }, [code]); + return ( <div className=" !mx-[1.6rem] !p-0r"> <div> @@ -321,7 +331,18 @@ export function PbnstMngForm({ 재이용 시설명 </Label> - {formType === "reg" ? ( + {formType === "update" ? ( + <SelectBox + label="" + className="mt-4 ml-2" + selectClass={undefined} + selectArray={fcltNm ?? []} + onSelectValue={(val) => { + selectFclt(Number(val)); + }} + value={""} + /> + ) : ( <FormField control={form.control} name="ruseUtztnFcltNm" @@ -339,23 +360,8 @@ export function PbnstMngForm({ </FormUi> )} /> - ) : ( - <SelectBox - label="" - className="mt-4 ml-2" - selectClass={undefined} - selectArray={fcltNm ?? []} - onSelectValue={(val) => { - selectFclt(Number(val)); - }} - value={""} - /> )} </div> - - {/* <Button onClick={addRuseFcltObj} type="button" size={commonButonSize}> - 추가 - </Button> */} </div> <div> @@ -385,6 +391,7 @@ export function PbnstMngForm({ tableData={fcOpersField} headList={pbnst.pbnstMngUpHeadList} upHeadList={pbnst.pbnstMngNm} + code={mngMtdCode || []} onTableSet={(val) => { setFcOpresData(val); }} @@ -400,25 +407,7 @@ export function PbnstMngForm({ control={form.control} name="fcltCpct" render={({ field }) => ( - <FormUi label="시설용량(m³/일)"> - <Input - placeholder="" - type="number" - onChange={(e) => { - field.onChange(Number(e.target.value)); - }} - value={field.value ?? 0} - /> - </FormUi> - )} - /> - </div> - <div className="col-span-3 mt-4"> - <FormField - control={form.control} - name="hasuhasu" - render={({ field }) => ( - <FormUi label="하수처리량(m³/일)"> + <FormUi label="재이용 시설용량(m³/일)"> <Input placeholder="" type="number" @@ -431,12 +420,13 @@ export function PbnstMngForm({ )} /> </div> + <div className="col-span-3 mt-4"> <FormField control={form.control} name="ruseCpct" render={({ field }) => ( - <FormUi label="재이용량(m³/일)"> + <FormUi label="재이용수공급량(m³/일)"> <Input placeholder="" type="number" diff --git a/apps/wr/components/ui/form/matDmd/coRegForm/component.tsx b/apps/wr/components/ui/form/matDmd/coRegForm/component.tsx deleted file mode 100644 index 57fd9239e..000000000 --- a/apps/wr/components/ui/form/matDmd/coRegForm/component.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { DatePicker, FormField, FormItem, FormLabel, FormUi, SelectBox } from "@common/business_components"; -import { Button, Input } from "@common/components"; -import { useState } from "react"; - -export function CoRegForm(form:any){ - - const { dmd } = useWrStore((state) => state); - - return( - - <> - <FormField - control={form.control} - name="ctpv" - render={({ field }) => ( - <FormUi label="시도"> - <SelectBox selectClass={selectClass} label={""} selectArray={dmd.selectSido} onSelectValue={field.onChange} className={""} /> - </FormUi> - - )} - /> - - <FormField - control={form.control} - name="sgg" - render={({ field }) => ( - <FormUi label="시군구"> - <SelectBox selectClass={selectClass} label={""} selectArray={dmd.selectSgg} onSelectValue={field.onChange} className={""} /> - </FormUi> - - )} - /> - - <FormField - control={form.control} - name="coNm" - render={({ field }) => ( - <FormUi label="회사명"> - <Input placeholder="" type="text" {...field} /> - </FormUi> - )} - /> - - <FormField - control={form.control} - name="bznmNo" - render={({ field }) => ( - <FormUi label="사업자번호"> - <Input - placeholder="a0123456789" - type="text" - {...field} /> - </FormUi> - )} - /> - - <FormField - control={form.control} - name="addr" - render={({ field }) => ( - <FormUi label="주소"> - <Input - placeholder="성북로24길 16" - - type="text" - {...field} /> - </FormUi> - )} - /> - - <FormField - control={form.control} - name="telNo" - render={({ field }) => ( - <FormUi label="전화번호"> - <Input - placeholder="01033332222" - - type="text" - {...field} /> - </FormUi> - - )} - /> - - - </> - ) -} \ No newline at end of file diff --git a/apps/wr/components/ui/form/matDmd/dmdRegform/component.tsx b/apps/wr/components/ui/form/matDmd/dmdRegform/component.tsx deleted file mode 100644 index efd3eb4ee..000000000 --- a/apps/wr/components/ui/form/matDmd/dmdRegform/component.tsx +++ /dev/null @@ -1,316 +0,0 @@ -import { useWrStore } from "@/app/store"; -import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; -import { DatePicker, FormField, FormItem, FormLabel, FormUi, SelectBox } from "@common/business_components"; -import { Button, Input } from "@common/components"; -import { useState } from "react"; - -export function DmdRegForm(form: any) { - const { dmd } = useWrStore((state) => state); - - const [dmdDate, setDmdDate] = useState(new Date()) - - - const onChangeDate = (val: Date|undefined) => { - if(val)setDmdDate(val) - } - - return ( - <> - <FormField - control={form.control} - name="dmdSel" - render={({ field }) => ( - <FormUi label="수요처명"> - <Input - placeholder="수요처명 검색" - - type="text" - {...field} /> - </FormUi> - )} - /> - - <FormField - control={form.control} - name="dmdTmng" - render={({ field }) => ( - <FormItem className="flex flex-col"> - <FormLabel>요구시기</FormLabel> - <DatePicker mode={"single"} field={{ value: dmdDate, onChange: onChangeDate }} selectClass={undefined} /> - </FormItem> - )} - /> - - <FormField - control={form.control} - name="dmdWq" - render={({ field }) => ( - <FormUi label="요구수질"> - <Input - placeholder="55.22" - - type="text" - {...field} /> - </FormUi> - - )} - /> - - <FormField - control={form.control} - name="useUsgCd" - render={({ field }) => ( - <FormUi label="사용용도"> - <SelectBox selectClass={selectClass} label={""} selectArray={dmd.selectUsg} onSelectValue={field.onChange} className={""} /> - </FormUi> - - )} - /> - - <FormField - control={form.control} - name="wntUntprc" - render={({ field }) => ( - <FormUi label="희망단가"> - <Input - placeholder="1000000000000000" - - type="text" - {...field} /> - </FormUi> - - )} - /> - - <div className="grid grid-cols-4"> - <h1 className=" col-span-2 pl-5 text-2xl underline"> - 요구수질 - </h1> - </div> - <div className="grid grid-cols-12 gap-4"> - - <div className="col-span-6"> - <FormField - control={form.control} - name="grssClfg" - render={({ field }) => ( - <FormUi label="총대장균군"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="tn" - render={({ field }) => ( - <FormUi label="총질소"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="combResdch" - render={({ field }) => ( - <FormUi label="결합잔류염소"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="tp" - render={({ field }) => ( - <FormUi label="총인"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="trbt" - render={({ field }) => ( - <FormUi label="탁도"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="ph" - render={({ field }) => ( - <FormUi label="수소이온농도"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="bod" - render={({ field }) => ( - <FormUi label="생물학적 산소요구량"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="clIonQnt" - render={({ field }) => ( - <FormUi label="염화물"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="smll" - render={({ field }) => ( - <FormUi label="냄새"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="cdtnv" - render={({ field }) => ( - <FormUi label="전기전도도"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-6"> - <FormField - control={form.control} - name="crmty" - render={({ field }) => ( - <FormUi label="색도"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - - <div className="col-span-6"> - <FormField - control={form.control} - name="rmrk" - render={({ field }) => ( - <FormUi label="비고"> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - <div className="grid grid-cols-4"> - <h1 className=" col-span-1 pl-2 text-2xl underline"> - 공급후보지 선택 - </h1> - <div className=" col-start-3 col-span-1 "> - <Button > - 후보지 조회 - </Button> - </div> - <div className=" col-start-4 col-span-1 "> - <Button > - 유사사례조회 - </Button> - </div> - - </div> - <div className="grid grid-cols-12 gap-4"> - <div className="col-span-4"> - <FormField - control={form.control} - name="sply1" - render={({ field }) => ( - <FormUi label="후보지_1"> - <Input placeholder="후보지1" type="text" {...field} /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="sply2" - render={({ field }) => ( - <FormUi label="후보지_2"> - <Input placeholder="후보지2" type="text" {...field} /> - </FormUi> - )} - /> - </div> - <div className="col-span-4"> - <FormField - control={form.control} - name="sply3" - render={({ field }) => ( - <FormUi label="후보지_3"> - <Input placeholder="후보지3" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - <div className="grid grid-cols-4"> - <h1 className=" col-span-2 pl-2 text-2xl underline"> - 수요신청 비밀번호 - </h1> - - <div className="col-start-3 col-span-2"> - <FormField - control={form.control} - name="password" - render={({ field }) => ( - <FormUi label=""> - <Input placeholder="10" type="text" {...field} /> - </FormUi> - )} - /> - </div> - </div> - </> - ); -} diff --git a/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx b/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx index 5ed40bacc..9572d1228 100644 --- a/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx +++ b/apps/wr/components/ui/modal/chkgd/chkgdModal/chkgdModal.tsx @@ -8,7 +8,7 @@ import type { splRuseWaterType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgd import type { rswtrPolutionsZode } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn/headList"; import type { z } from "zod"; import React from "react"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; export default function ChkgdModal({ type, obj }: { type: string; obj: any }) { const { diff --git a/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx b/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx index 8190b96e8..9fe45fc33 100644 --- a/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx +++ b/apps/wr/components/ui/modal/chkgd/pbnPrfExcelModal/pbnPrfExcelModal.tsx @@ -1,6 +1,7 @@ import { useWrStore } from "@/app/store"; import { excelToPbnPrfData } from "@/app/store/prfmncReg/pbnstPrfmncReg/excel"; import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList"; +import type { FcPrfType, PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; import { yearOptions } from "@/components/lib/func/commom"; import { ToastFormUi } from "@/components/ui/toast/toastFromUi"; import { @@ -13,19 +14,17 @@ import { type SelectDataType, filePicked, } from "@common/business_components/ui"; -import { Button } from "@common/components/ui"; +import { Button, Input } 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); +export default function PbnPrfExcelModal({ data }: { data: FcPrfType }) { + const { prfmnRegData } = useWrStore((state) => state); - - const [bscFctNmList, setBscFctNmList] = useState<SelectDataType[] | null>(null); const [files, setFiles] = useState<File[] | null>(null); -const [excelData, setExcelData] = useState<any[]>(); + const [excelData, setExcelData] = useState<PrfType[]>(); const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({ resolver: zodResolver(pbnPrfRegExcelZod), defaultValues: { @@ -33,28 +32,26 @@ const [excelData, setExcelData] = useState<any[]>(); }, }); 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) + if (excelData) { + prfmnRegData(excelData as unknown as PrfType); } - }, [prfmnc.prfmncRes]); + }; + useEffect(() => { + if (data && data.bscFctNm) + form.setValue("pbnstRuseFcltFk", data.pbnstRuseFcltPk); + form.setValue("bscFctNm", data.bscFctNm || ""); + form.setValue("pbnstRuseFcltNm", data.ruseUtztnFcltNm); + }, [data]); - useEffect(()=>{ - - if(files){ + useEffect(() => { + console.log("excelData", excelData); + }, [excelData]); + useEffect(() => { + if (files) { const file = files[0]; if (form.getValues("ym").length < 1) { ToastFormUi({ @@ -65,15 +62,13 @@ const [excelData, setExcelData] = useState<any[]>(); return; } - if(file) - filePicked(file, 0).then((res) => { - if (res !== undefined) - console.log(excelToPbnPrfData(res, form.getValues("ym"))) - }); - - + if (file) + filePicked(file, 0).then((res) => { + if (res !== undefined) + setExcelData(excelToPbnPrfData(res as unknown as JSON[], form.getValues("ym"),form.getValues('pbnstRuseFcltFk') ) as PrfType[]) + }); } - },[files]) + }, [files]); return ( <> @@ -116,13 +111,11 @@ const [excelData, setExcelData] = useState<any[]>(); name="bscFctNm" render={({ field }) => ( <FormUi label="시설명"> - <SelectBox + <Input className="w-1/4 text-3xl" - selectClass={""} - label="" - selectArray={bscFctNmList || [] } value={field.value} - onSelectValue={(val) => field.onChange(String(val))} + onChange={field.onChange} + readOnly /> </FormUi> )} @@ -132,13 +125,11 @@ const [excelData, setExcelData] = useState<any[]>(); name="pbnstRuseFcltNm" render={({ field }) => ( <FormUi label="재이용시설명"> - <SelectBox + <Input className="w-1/4 text-3xl" - selectClass={""} - label="" - selectArray={yearOptions} value={field.value} - onSelectValue={(val) => field.onChange(String(val))} + onChange={field.onChange} + readOnly /> </FormUi> )} diff --git a/apps/wr/components/ui/modal/coMat/cmpttnModal.tsx b/apps/wr/components/ui/modal/coMat/cmpttnModal.tsx new file mode 100644 index 000000000..ab18e3542 --- /dev/null +++ b/apps/wr/components/ui/modal/coMat/cmpttnModal.tsx @@ -0,0 +1,36 @@ +"use client" + +import { cmpttnHeadListExport } from "@/app/store/matDmd/coMatRvw/headList"; +import { yearOptions } from "@/components/lib/func/commom" +import { SelectBox, UiTable } from "@common/business_components/ui" +import { Label } from "@common/components/ui" +import { useState } from "react"; + +export function CmpttnModal({ data }: { data: [] }) { + const [year, setYear] = useState<string>(String(new Date().getFullYear())); + return ( + <> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label">공사비 산정표 보기</h3> + <hr/> + <div className="flex items-center"> + <Label className="text-xl text-gray-600">기준년도</Label> + <SelectBox + className="h-full text-2xl" + label="" + selectClass={"ml-4"} + selectArray={yearOptions} + value={year} + onSelectValue={(val: string | number) => setYear(String(val))} /> + </div> + <UiTable + headName={""} + tableData={[]} + headlist={cmpttnHeadListExport} + pageSize={0} + total={0} + cellClick={() => { }} + onPageChange={() => { }} + /> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/coMat/coMatModal.tsx b/apps/wr/components/ui/modal/coMat/coMatModal.tsx new file mode 100644 index 000000000..4717a89a3 --- /dev/null +++ b/apps/wr/components/ui/modal/coMat/coMatModal.tsx @@ -0,0 +1,32 @@ +"use client" + +import { coModalHeadListExport } from "@/app/store/matDmd/coMatRvw/headList"; +import { yearOptions } from "@/components/lib/func/commom" +import { SelectBox, UiTable } from "@common/business_components/ui" +import { Label } from "@common/components/ui" +import { useState } from "react"; + +export function CoMatModal({ data }: { data: [] }) { + const [year, setYear] = useState<string>(String(new Date().getFullYear())); + return ( + <> + <h3 className="mt-4 ml-2 text-2xl font-medium text-label">요율표 보기</h3> + <hr/> + <div className="flex items-center"> + <Label className="text-xl text-gray-600">기준년도</Label> + <SelectBox + className="h-full text-2xl" + label="" + selectClass={"ml-4"} + selectArray={yearOptions} + value={year} + onSelectValue={(val: string | number) => setYear(String(val))} /> + </div> + <UiTable + headName={""} + tableData={[]} + headlist={coModalHeadListExport} + onPageChange={() => { }} pageSize={0} total={0} cellClick={undefined} /> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx b/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx new file mode 100644 index 000000000..a6b05ca77 --- /dev/null +++ b/apps/wr/components/ui/modal/coMat/drgtDetailModal.tsx @@ -0,0 +1,48 @@ +"use client" + +import { btnClass } from "@/app/store/common/code" +import { drgtDetailHeadListExport } from "@/app/store/matDmd/drgtSttn/headList" +import { ContentsDiv, Title, UiTable } from "@common/business_components/ui" +import ListDiv from "@common/business_components/ui/list_div" +import { Button } from "@common/components/ui" + +export default function DrgtDetailModal() { + return ( + <> + <ContentsDiv> + <div className="grid grid-cols-4 gap-4 "> + <div className="col-span-4"> + <Title title={"우리동네가뭄 상세내용"} /> + <div className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 "> + <div className="flex flex-row space-x-2"> + <Button + size={"sm"} + className={`${btnClass} green`} + onClick={() => { }} + > + 다운로드 + </Button> + </div> + <div className="grid grid-cols-6 gap-4 "> + <div className="col-span-6"> + <ListDiv> + <UiTable + headName={[]} + tableData={[]} + headlist={drgtDetailHeadListExport} + pageSize={10} + total={10000} + cellClick={(index: number | undefined, headId: string) => { }} + onPageChange={() => { }} + ></UiTable> + </ListDiv> + </div> + </div> + </div> + </div> + </div> + + </ContentsDiv> + </> + ) +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx index d6f196b22..3d0eed82f 100644 --- a/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal.tsx @@ -94,7 +94,6 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) { useEffect(()=>{ setbdstTable([]) // 초기화 작업 },[]) - const nodeList = headMakeColSpan(bdst.moUpHeadList); return ( <> <div className="grid grid-cols-12 gap-4 mt-4 items-center"> @@ -135,7 +134,6 @@ export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) { onPageChange={function (page: number): void { throw new Error("Function not implemented."); }}> - {nodeList} </UiTable> </div> </ScrollArea> diff --git a/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx index b04386752..1b6b3950e 100644 --- a/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/fcOrgwtsRegModal/fcOrgwtsRegModal.tsx @@ -1,7 +1,7 @@ "use client"; import { useWrStore } from "@/app/store"; import type { pubHasuType, fcBizType, fcOrgwtType,} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import { tableData } from "@/components/lib/func/commom"; import RuseMngTable from "@/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable"; import { Title, UiTable } from "@common/business_components/ui"; diff --git a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx index 3929551e8..736fa6b41 100644 --- a/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx +++ b/apps/wr/components/ui/modal/fcltReg/pbnstRegModal/pbnstRegModal.tsx @@ -1,9 +1,10 @@ "use client"; import { useWrStore } from "@/app/store"; -import type { - customPbnst, - fcBizType, - pubHasuType, +import { + pbnstRegZod, + type customPbnst, + type fcBizType, + type pubHasuType, } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; import { ScrollArea } from "@common/business_components"; @@ -18,9 +19,11 @@ import { useEffect, useState } from "react"; import { PbnstBuseForm } from "@/components/ui/form/fcltReg/pbnstReg/buseReg/bugRegForm"; export function PbnstRegModal({ data }: { data: pubHasuType }) { - const { pbnst, pbnstInsert } = useWrStore((state) => { + const { pbnst, pbnstInsert, pbnstMngData } = useWrStore((state) => { return state; }); + + const { pbnstRes } = pbnst; const [pbnstBdstForm, setPbnstBdstForm] = useState<customPbnst>( {} as customPbnst ); @@ -36,23 +39,43 @@ export function PbnstRegModal({ data }: { data: pubHasuType }) { useEffect(() => { if (data) { - let regData = { - swtrmtFcltFk: String(data.bscFctCd), - pbnstRuseFcltPk: String(data.bscFctCd + "1"), - fcBizs: [ - { - pbnstRuseFcltFk: String(data.bscFctCd + "1"), - cycl: 1, - } as unknown as fcBizType, - ], - }; + 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); } - }, [data]); + }, [data, pbnstRes]); - useEffect(() => {}, [pbnstBdstForm]); - useEffect(() => {}, [pbnst.pbnstMngRegData]); return ( <> <h1 className="text-2xl font-medium text-label pl-8"> @@ -81,7 +104,10 @@ export function PbnstRegModal({ data }: { data: pubHasuType }) { <PbnstMngForm formType={"reg"} firstFcltData={pbnstBdstForm} /> </TabsContent> <TabsContent className="max-h-full" value="buse"> - <PbnstBuseForm formType={"reg"} firstBizData={pbnstBdstForm.fcBizs} /> + <PbnstBuseForm + formType={"reg"} + firstBizData={pbnstBdstForm.fcBizs} + /> </TabsContent> </Tabs> </ScrollArea> diff --git a/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx b/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx new file mode 100644 index 000000000..5427c5dd2 --- /dev/null +++ b/apps/wr/components/ui/modal/ldrmntSttn/ldrmntExcelModal.tsx @@ -0,0 +1,67 @@ +import { useWrStore } from "@/app/store"; +import { pbnPrfRegExcelZod } from "@/app/store/prfmncReg/pbnstPrfmncReg/headList"; +import type { FcPrfType, PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import { yearOptions } from "@/components/lib/func/commom"; +import { FileUpload, Form, FormField, FormUi, SelectBox, Title } from "@common/business_components/ui"; +import { Button, Input } from "@common/components/ui"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useState } from "react"; +import { useForm } from "react-hook-form"; +import type { z } from "zod"; + +export default function LdrmntExcelModal({ data }: { data: FcPrfType }) { + const { prfmnRegData } = useWrStore((state) => state); + const [excelData, setExcelData] = useState<PrfType[]>(); + const form = useForm<z.infer<typeof pbnPrfRegExcelZod>>({ + resolver: zodResolver(pbnPrfRegExcelZod), + defaultValues: { + ym: String(new Date().getFullYear()), + }, + }); + const onSubmit = (values: z.infer<typeof pbnPrfRegExcelZod>) => { + if (excelData) { + prfmnRegData(excelData as unknown as PrfType); + } + }; + const [files, setFiles] = useState<File[] | null>(null); + return ( + <> + <div> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)}> + <div> + <Title title={"잠재수요처 등록"}> +
+
+

+ {"잠재수요처 파일"} +

+ + +
+
+ ( + + { + if (files) setFiles(files); + }} + fileTypes="xlsx" + > + + )} + /> +
+ + +
+ + ) + +} \ No newline at end of file diff --git a/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx new file mode 100644 index 000000000..1704a481d --- /dev/null +++ b/apps/wr/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal.tsx @@ -0,0 +1,286 @@ +import { useWrStore } from "@/app/store"; +import type { TableUpperProps } from "@/app/store/common/type/header"; +import { initValInUsage, initValOutUsage, subTotalObj, totalObj, type PrfType } from "@/app/store/prfmncReg/pbnstPrfmncReg/type"; +import type { + customPbnst, + fcBizType, +} from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type"; +import { PbnstMngForm } from "@/components/ui/form/fcltReg/pbnstReg/mngReg/mngRegForm"; +import { ScrollArea, Title, UiTable } from "@common/business_components/ui"; +import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; +import { + Tabs, + TabsList, + TabsTrigger, + Button, + TabsContent, +} from "@common/components/ui"; +import { useEffect, useState } from "react"; +import { set } from "react-hook-form"; + +export function PbnstSttnModal({ data }: { data: customPbnst }) { + const { code, pbnstSttn,prfmnc } = useWrStore((state) => state); + const [fcltTab, setFcltTab] = useState("fclt"); + const [ruseTab, setRuseTab] = useState("inoutTotal"); + const [ruseBizData, setRuseBizData] = useState<{ + data: any[]; + head: TableUpperProps[]; + }>(); + const [ruseHeadList, setRuseHeadList] = useState([]); + const [ruseTableData, setRuseTableData] = useState([]); + const [prfData , setPrfData] = useState<{inPrf: any[],outPrf: any[], totalPrf:any[] }> () + + const {monthHeadList } = prfmnc; + useEffect(() => { + let tableData; + if (fcltTab === "fclt") { + tableData = data.fcBizs?.map((item: fcBizType) => { + return { + cycl: item.cycl + "차", + seCd: item.seCd, + gvsbs: item.gvsbs??'-', + lcep: item.lcep??'-', + cusrAlotm: item.cusrAlotm??'-', + etc: item.etc??'-', + totalMoney: + Number(item.addr) + + Number(item.gvsbs) + + Number(item.lcep) + + Number(item.cusrAlotm), + instlAprvSncnDt: item.instlAprvSncnDt?.toISOString??'-', + bizCmcnDay: item.bizCmcnDay?.toISOString??'-', + rprcsFcltCpct: item.rprcsFcltCpct??'-', + rprcsMthdCd: item.rprcsMthdCd??'-', + majorPrcsMsrcCd: item.majorPrcsMsrcCd??'-', + inoutYn: item.inoutYn??'-', + addr: item.addr??'-', + }; + }); + } else if (fcltTab === "sply") { + tableData = data.fcBizs.flatMap((item: fcBizType) => { + return item?.fcOrgwts?.map((fcOrgwt) => { + return { + cycl: item.cycl + "차", + orgwtWtritQnt: fcOrgwt.orgwtWtritQnt, + tmsYn: fcOrgwt.tmsYn, + dschgFmYn: fcOrgwt.dschgFmYn, + dtlPstnExpln: fcOrgwt.dtlPstnExpln, + }; + }) + }); + } else if (fcltTab === "ppi") { + tableData = data.fcBizs?.flatMap((item: fcBizType) => { + return item?.pplInstls?.map((ppl) => { + return { + cycl: item.cycl + "차", + ppMqlt: ppl.ppMqlt, + pdmt: ppl.pdmt, + cpct: ppl.cpct, + }; + }) + }); + } else if (fcltTab === "guarantee") { + tableData = data.fcBizs?.map((item: fcBizType) => { + return { + cycl: item.cycl + "차", + bod: item.bod, + grssClfg: item.grssClfg, + combResdch: item.combResdch, + trbt: item.trbt, + smll: item.smll, + crmty: item.crmty, + tph: item.tph, + tn: item.tn, + ph: item.ph, + cdtnv: item.cdtnv, + }; + }); + } else if (fcltTab === "dmdCo") { + tableData = data.fcBizs?.flatMap((item: fcBizType) => { + return item?.fcDemands?.map((dmd) => { + return { + cycl: item.cycl + "차", + dmdCoNm: dmd.dmdCoNm, + daddr: dmd.daddr, + useUsgCd: dmd.useUsgCd, + splyBgngDay: dmd.splyBgngDay?.toISOString, + splyEndDay: dmd.splyEndDay?.toISOString, + splyCpct: dmd.splyCpct, + splyFmYn: dmd.splyFmYn, + }; + }) + }); + } + console.log(tableData); + if (tableData && tableData.length > 0) { + setRuseTableData(tableData as any[]); + } + }, [fcltTab, data]); + useEffect(() => { + if (fcltTab === "fclt") { + setRuseHeadList(pbnstSttn.ruseFcltHeadList); + } else if (fcltTab === "sply") { + setRuseHeadList(pbnstSttn.ruseSplyHeadList); + } else if (fcltTab === "ppi") { + setRuseHeadList(pbnstSttn.rusePplHeadList); + } else if (fcltTab === "guarantee") { + setRuseHeadList(pbnstSttn.ruseGuranteeHeadList); + } else if (fcltTab === "dmdCo") { + setRuseHeadList(pbnstSttn.ruseDmdHeadList); + } + }, [ + fcltTab, + pbnstSttn.ruseFcltHeadList, + pbnstSttn.ruseSplyHeadList, + pbnstSttn.rusePplHeadList, + pbnstSttn.ruseGuranteeHeadList, + pbnstSttn.ruseDmdHeadList, + ]); + + const getTablePrfData = (prfList:PrfType[]) => { + const inUsageData = [...initValInUsage]; + const outUsageData = [...initValOutUsage]; + const inSubtotal = subTotalObj; + const outSubtotal = subTotalObj; + + if (prfList) { + prfList?.forEach((prfItem) => { + const month = Number(prfItem?.ym?.slice(4)); // "MM" + const monthKey = `${month}월`; + + inUsageData.forEach((inData: any) => { + const usageKey = inData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + inData[monthKey] = value; + inData.total += value; + + if (inSubtotal && usageKey !== "subtotal") { + (inSubtotal as any)[monthKey] = + ((inSubtotal as any)[monthKey] ?? 0) + value; + inSubtotal.total += value; + } + }); + + outUsageData.forEach((outData: any) => { + const usageKey = outData.usage; + const value = (prfItem as any)[usageKey] ?? 0; + + outData[monthKey] = value; + outData.total += value; + + if (usageKey !== "subtotal") { + (outSubtotal as any)[monthKey] = + ((outSubtotal as any)[monthKey] ?? 0) + value; + outSubtotal.total += value; + } + }); + }); + inUsageData.push(inSubtotal); + outUsageData.push(outSubtotal); + const usageTotalObj: { [key: string]: any } = totalObj; + for (const key in usageTotalObj) { + if (["usage", "gubun", "edit"].includes(key)) continue; + const val = + (Number((inSubtotal as any)[key]) || 0) + + (Number((outSubtotal as any)[key]) || 0); + + (usageTotalObj as any)[key] = val; + } + const tableData = [...inUsageData, ...outUsageData, usageTotalObj]; + + setPrfData({ + inPrf: inUsageData, + outPrf: outUsageData, + totalPrf: tableData, + }); + } + + } + useEffect(() => { + + if(pbnstSttn.pbnstSttnRes&&data){ + const prfList = pbnstSttn.pbnstSttnRes.find((item) => item.pbnstRuseFcltPk=== data.pbnstRuseFcltPk )?.prfList + + if(prfList){ + getTablePrfData(prfList) + } + + } + }, [pbnstSttn.pbnstSttnRes, data]); + + useEffect(() => {}, [ruseBizData?.head]); + return ( + <> +
+ + <ScrollArea className={"h-[70vh]"}> + <PbnstMngForm firstFcltData={data} formType={"sttn"} /> + <Tabs defaultValue="mng" onValueChange={setFcltTab}> + <TabsList className=""> + <TabsTrigger className="!text-xl" value="fclt"> + 하수처리수 재이용시설 현황 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="sply"> + 재이용 원수 취수 현황 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="ppi"> + 재이용 공급관로 현황 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="guarantee"> + 재이용 보증수질 현황 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="dmdCo"> + 재이용 수요처 현황 + </TabsTrigger> + </TabsList> + <TabsContent className="max-h-full" value={fcltTab}> + <UiTable + headName={undefined} + tableData={ruseTableData || []} + headlist={ruseHeadList || []} + pageSize={0} + total={0} + cellClick={undefined} + onPageChange={function (page: number): void { + throw new Error("Function not implemented."); + }} + children={fcltTab==='fclt'?<HeadMakeColSpan upHeadList={pbnstSttn.ruseFcltNodeList} />:undefined} + ></UiTable> + </TabsContent> + </Tabs> + + <Tabs defaultValue="mng" onValueChange={setRuseTab}> + <TabsList className=""> + <TabsTrigger className="!text-xl" value="totalPrf"> + 장내외합계 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="inPrf"> + 장내용수 + </TabsTrigger> + <TabsTrigger className="!text-xl" value="outPrf"> + 장외용수 + </TabsTrigger> + </TabsList> + <TabsContent className="max-h-full" value={ruseTab}> + {prfData && ( + <UiTable + headName={undefined} + tableData={prfData[ruseTab as keyof typeof prfData] || []} + headlist={monthHeadList || []} + pageSize={0} + total={0} + cellClick={undefined} + onPageChange={function (page: number): void { + throw new Error("Function not implemented."); + }} + ></UiTable> + )} + </TabsContent> + </Tabs> + + </ScrollArea> + </div> + </> + ); +} diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx index 8bfef0819..255ff0fc7 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/coDatailModal.tsx @@ -1,30 +1,824 @@ "use client"; import { useWrStore } from "@/app/store"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; -import { Title } from "@common/business_components/ui"; +import type { CommonTableProps } from "@/app/store/common/type/header"; +import { ldrmntZod, type customLdrmntBdst } from "@/app/store/matDmd/ldrmntCoSttn"; +import { rainZod, selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { handleCommaNumberChange, formatCommaNumber } from "@/components/lib/func/commom"; +import { DatePicker, Form, FormField, FormUi, ScrollArea, Title, UiTable } from "@common/business_components/ui"; +import { Button, Input } 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 SttnDetailModal( - {formObj,}: {formObj: any;}) { - const { code, rainSttn, rswtSttn, rainSttnChkSearch } = useWrStore( - (state) => state - ); - const [detailData, setDetailData] = useState({ - head: [] as CommonTableProps[], - node:[] as CommonTableProps[], - data: {} as any, +export default function SttnDetailModal({ + formObj, +}: { + formObj: any; +}) { + const defaultValues: z.infer<typeof ldrmntZod> = ldrmntZod.parse({}); + const form = useForm<z.infer<typeof ldrmntZod>>({ + resolver: zodResolver(ldrmntZod), + defaultValues: defaultValues, }); - useEffect(() =>{ - setDetailData({data:[] , head:[], node:[]}) + const onSubmit = (values: z.infer<typeof ldrmntZod>) => { - },[]) + }; + + useEffect(() => { + if (ldrmntZod) form.reset(formObj); + + console.log("이거", formObj) + }, [formObj]); return ( - <div> - <Title title="잠재수요처 상세정보"> - + +
+ +
+

+ 잠재수요처 상세정보 +

+ +
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + field.onChange(date), + }} + selectClass={"w-full"} + /> + + )} + /> +
+ +
+ ( + + field.onChange(date), + }} + selectClass={"w-full"} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + field.onChange(date), + }} + selectClass={"w-full"} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ ( + + { + handleCommaNumberChange(e, field.onChange); + }} + value={field.value} + /> + + )} + /> +
+
+ + + +
+ +
); } diff --git a/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx b/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx index d7f10ddd1..0ebd03ae2 100644 --- a/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx +++ b/apps/wr/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal.tsx @@ -8,7 +8,7 @@ import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg"; import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg"; import { useWrStore } from "@/app/store"; import { useEffect, useState } from "react"; -import type { CommonTableProps } from "@/app/store/common/type/headder"; +import type { CommonTableProps } from "@/app/store/common/type/header"; import { rainChkTableData, rswtChkTableData } from "@/components/lib/func/TableData"; import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan"; import type { rswtChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; diff --git a/apps/wr/components/ui/searchInput/searchInput.tsx b/apps/wr/components/ui/searchInput/searchInput.tsx index 413c3593a..984124abf 100644 --- a/apps/wr/components/ui/searchInput/searchInput.tsx +++ b/apps/wr/components/ui/searchInput/searchInput.tsx @@ -1,56 +1,69 @@ +import React, { useCallback, useEffect, useRef, useState } from "react"; -import { useWrStore } from '@/app/store'; -import type { PbnstDemandComType } from '@/app/store/ruseFcltMng/fcltReg/pbnstReg/type'; -import type { DemandCompType } from '@common/business_components/ui'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; - +type SearchType = { + searchNm: string; + searchPk: string; +}; type thisProps = { label: string | undefined; initValue: string | undefined; - setValue : (dmdCoNm?: string) => void; - setRtnData : (rtnData: PbnstDemandComType[]) => void; -} - - -export default function SearchInputText({label=undefined, initValue=undefined, setValue=()=>{}, setRtnData=()=>{}} :thisProps) { - - const { demandCompList } = useWrStore((state) => state); - - + setValue: (searchNm?: string) => void; + setRtnData: (rtnData: any) => void; + searchList?: any[]; +}; +export default function SearchInputText({ + label = undefined, + initValue = undefined, + setValue = () => {}, + setRtnData = () => {}, + searchList = undefined, +}: thisProps) { + const [isOpen, setIsOpen] = useState(false); - const [textValue, setTextValue] = useState(initValue || ''); - const wrapperRef = useRef(null); - const handleInputChange = useCallback((e: React.ChangeEvent) => { - const value = e.target.value; - setTextValue(value); - setValue(value); - if (value) { - setIsOpen(true); - } else { - setIsOpen(false); - } - }, [ setValue]); + const [textValue, setTextValue] = useState(initValue || ""); - const handleSuggestionClick = useCallback((dmdCoNm: string) => { - setTextValue(dmdCoNm); - setValue(dmdCoNm); - setIsOpen(false); - setRtnData(demandCompList); - }, [demandCompList, setRtnData, setValue]); + const wrapperRef = useRef(null); + const handleInputChange = useCallback( + (e: React.ChangeEvent) => { + const value = e.target.value; + setTextValue(value); + setValue(value); + if (value) { + setIsOpen(true); + } else { + setIsOpen(false); + } + }, + [setValue] + ); + + const handleSuggestionClick = useCallback( + (dmdCoNm: string) => { + setTextValue(dmdCoNm); + setValue(dmdCoNm); + setIsOpen(false); + setRtnData(searchList?.find((item) => item.dmdCoNm === dmdCoNm) || {}); + }, + [searchList, setRtnData, setValue] + ); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { - if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) { + if ( + wrapperRef.current && + !wrapperRef.current.contains(event.target as Node) + ) { setIsOpen(false); } }; - document.addEventListener('mousedown', handleClickOutside); + document.addEventListener("mousedown", handleClickOutside); return () => { - document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener("mousedown", handleClickOutside); }; }, []); + return (
- {demandCompList && demandCompList.length > 0 ? demandCompList.map((item : DemandCompType, index : number) => ( -
handleSuggestionClick(item.dmdCoNm)} - role="button" - tabIndex={0} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { - handleSuggestionClick(item.dmdCoNm); - } - }} - > - {item.dmdInfoPk.substring(0,10)} {item.dmdCoNm} -
- )) : ( + {searchList && searchList.length > 0 ? ( + searchList.map((item: SearchType, index: number) => ( +
handleSuggestionClick(item.searchNm)} + role="button" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + handleSuggestionClick(item.searchNm); + } + }} + > + {item.searchPk?.substring(0, 10)}  + {item.searchNm} +
+ )) + ) : (
검색 결과가 없습니다.
@@ -88,5 +104,5 @@ export default function SearchInputText({label=undefined, initValue=undefined, s
)}
- ) -} \ No newline at end of file + ); +} diff --git a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx index 8664db503..94be4ebb6 100644 --- a/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/guideDetailTable/guideDetailTable.tsx @@ -1,9 +1,10 @@ "use client"; import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead"; import { useWrStore } from "@/app/store"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import type { } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import { InputTableBody } from "@/components/lib/func/TableData"; import { Input, Table, @@ -12,7 +13,7 @@ import { TableHeader, TableRow, } from "@common/components/ui"; -import { useEffect, useState } from "react"; +import { useEffect, useState, type Dispatch, type SetStateAction } from "react"; export function GuideDetailsTable({ chgRes, @@ -26,80 +27,26 @@ export function GuideDetailsTable({ setChGuidData: (chgRes: any[]) => void; }) { const { code, rainChkgdn } = useWrStore((state) => state); - const [guidData, setGuidData] = useState(); + const [inputData, setInputData] = useState(); - - const handleChange = ( - rowIndex: number, - field: any, - value: string | number - ) => { - if(Number(value) < 0 ||! Number(value)){ - value = 0; - }else{ - value = Number(value); - } - setGuidData((prevData) => - prevData?.map((row, index) => { - if (index === rowIndex) { - return { - ...row, - [field as any]: value, - }; - } - return row; - }) - ); - }; - const tableBody = (chgRes: any[] | []) => { - return ( - <> - {chgRes.map((data, dataIndex) => ( - - {headList.map((head, headIndex) => ( - - {head.edit ===true && data.edit !==false? - - handleChange(dataIndex, head.id, e.target.value) - } - value={data[head.id as keyof any] ?? ""} - /> : ( -
- {data[head.id as keyof any] ?? ""} -
- ) - } -
- ))} -
- ))} - - ); - }; useEffect(() => { - setGuidData(chgRes); + setInputData(chgRes); }, [chgRes]); useEffect(() => { - setChGuidData(guidData??[] ); + setChGuidData(inputData??[] ); - }, [guidData]); + }, [inputData]); + return ( <>
{headMakeprfmnc(headList, rainChkgdn?.rainHeadNm)} - {tableBody(guidData ?? [])} + {InputTableBody(inputData ?? [],headList, setInputData) }
diff --git a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx index 9c9bdbb24..d0ad437b3 100644 --- a/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rainChkgd/rainChkgdTable.tsx @@ -3,7 +3,7 @@ import { headMakeprfmnc } from "@/app/ruseFcltMng/prfmncReg/chkgdnReg/TableHead" import { useWrStore } from "@/app/store"; import type { rainChkZodType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn"; import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import { tableData } from "@/components/lib/func/commom"; import { chRowspanTable, diff --git a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx index b4f0281ac..20db75f50 100644 --- a/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx +++ b/apps/wr/components/ui/table/chkgdTable/rswtChkgd/rswtChkgdTable.tsx @@ -6,7 +6,7 @@ import type { rswtChkZodType, rswtrChkDetailsZodType, } from "@/app/store/prfmncReg/chkgdnReg/rswrtChkgdn"; -import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg"; +import type { TableUpperProps } from "@/app/store/common/type/header"; import { tableData } from "@/components/lib/func/commom"; import { chRowspanTable, diff --git a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx index 43a08e203..f76ed23bb 100644 --- a/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx +++ b/apps/wr/components/ui/table/pbnstReg/ruseMngTable/ruseMngTable.tsx @@ -42,8 +42,7 @@ const RuseMngTable = React.forwardRef( }, [tableState,onTableSet]); - - + useEffect(() => { if(tableData) setTableState(tableData); @@ -92,7 +91,7 @@ const RuseMngTable = React.forwardRef( ) : head.type === "select" ? ( item.name === head.selectData)?.val ?? []} + selectArray={code?.find(item => item.name === head.selectData)?.val ?? []} value={ tableState[i][head.id] || "" } diff --git a/apps/wr/public/sample_coSttn.xlsx b/apps/wr/public/sample_coSttn.xlsx new file mode 100644 index 000000000..836ee002e Binary files /dev/null and b/apps/wr/public/sample_coSttn.xlsx differ diff --git a/apps/wr/public/sample_drgtSttn.xlsx b/apps/wr/public/sample_drgtSttn.xlsx new file mode 100644 index 000000000..7a0c868cd Binary files /dev/null and b/apps/wr/public/sample_drgtSttn.xlsx differ diff --git a/apps/wr/public/sample_ldrmntCoSttn.xlsx b/apps/wr/public/sample_ldrmntCoSttn.xlsx new file mode 100644 index 000000000..646e8e4b8 Binary files /dev/null and b/apps/wr/public/sample_ldrmntCoSttn.xlsx differ diff --git a/packages/common/business_components/src/ui/chart/DoubleBar.tsx b/packages/common/business_components/src/ui/chart/DoubleBar.tsx new file mode 100644 index 000000000..9627485aa --- /dev/null +++ b/packages/common/business_components/src/ui/chart/DoubleBar.tsx @@ -0,0 +1,137 @@ +"use client" +import { Bar, BarChart, CartesianGrid, Legend, XAxis, YAxis } from "recharts"; +import { + ChartContainer, + ChartTooltip, + type ChartConfig +} from "./lib/chart"; +import type { CSSProperties } from "react"; + +const customStyles = { + legendContainer: { + display: "flex", + justifyContent: "center", + gap: "20px", + fontSize: "9px", + fontWeight : "bold", + marginTop: "10px", + } as CSSProperties, +}; + +type BarChartProps = { + chartConfig: ChartConfig | undefined; + chartData: any[] | undefined; + chartTitle: string; + chartClassName?: string; + graphSize?: number; + yFieldText?: string; + showLegend?: boolean; +} + +// 커스텀 툴팁 +const CustomTooltip = ({ + active, + payload, + label +}: { + active?: boolean; + payload?: Array<{ + name: string; + value: number; + color: string; + }>; + label?: string; +}) => { + if (active && payload && payload.length) { + return ( +
+

{label}

+ {payload.map((item, index) => ( +
+ {/* 색상 박스 추가 (범례 색상과 동일) */} +
+ {` ${item.name} : ${item.value}`} +
+ ))} +
+ ); + } + return null; +}; + +// 커스텀 범례 (글씨 크기 키우기 + 스타일 추가) +const CustomLegend = (props: any) => { + const { payload } = props; + return ( +
+ {payload.map((entry: unknown, index: number) => ( +
+
+ {(entry as {value: string}).value} +
+ ))} +
+ ); +}; + +export default function DoubleBarChart({chartConfig=undefined, chartData=[], chartTitle='차트', chartClassName='w-full h-full', graphSize=40, yFieldText='', showLegend=false} : BarChartProps) { + const colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEEAD", "#D4A5A5"]; + const getMaxValue = (data: any[], keyPrefix: string) => { + return Math.max(...data.map(item => + Object.keys(item) + .filter(key => key.includes(keyPrefix)) + .map(key => item[key]) + ).flat()); + }; + console.log(chartData); + const barMaxValue = getMaxValue(chartData, 'barVal'); + return ( + <> + {chartTitle && chartTitle !== "" && chartTitle !== "undefined" ? ( +
+ {chartTitle} +
): null} +
+ + + + + + }/> + {chartData && chartData.length > 0 && ( + Object.keys(chartData[0]) + .filter(key => key !== "label") + .map((key, idx) => ( + + )) + )} + {showLegend && } + + +
+ + ) +} \ No newline at end of file diff --git a/packages/common/business_components/src/ui/chart/DoughnutChart.tsx b/packages/common/business_components/src/ui/chart/DoughnutChart.tsx index f88b35476..d666f1d14 100644 --- a/packages/common/business_components/src/ui/chart/DoughnutChart.tsx +++ b/packages/common/business_components/src/ui/chart/DoughnutChart.tsx @@ -1,27 +1,116 @@ "use client" import { Pie, PieChart } from "recharts"; - +import type { CSSProperties } from "react"; import { Card, CardContent } from "./lib/card"; -import { - ChartContainer, - ChartTooltip, - ChartTooltipContent, - type ChartConfig -} from "./lib/chart"; +import { ChartContainer, ChartTooltip } from "./lib/chart"; -// eslint-disable-next-line react-refresh/only-export-components -export default (props: { chartConfig: ChartConfig; chartData: never[] | undefined; chartTitle:string}) =>{ +type ChartDataItem = { + label: string; + val: number; +}; + +type ChartConfigItem = { + label: string; + fill: string; +}; + +type ChartConfig = { + [key: string]: ChartConfigItem; +}; + +type TooltipPayloadItem = { + name: string; + value: number; + payload: { + label: string; + val: number; + fill: string; + }; +}; + +type LegendEntry = { + value: string; + fill: string; + type?: string; + payload: { + label: string; + val: number; + fill: string; + }; +}; + +type LegendProps = { + payload?: LegendEntry[]; +}; + +/** 차트 기본 스타일 */ +const customStyles = { + legendContainer: { + display: "flex", + justifyContent: "center", + gap: "20px", + fontSize: "9px", + fontWeight: "bold", + marginTop: "10px", + } as CSSProperties, +}; + +// 커스텀 툴팁 +const CustomTooltip = ({ active, payload, label }: { + active?: boolean; + payload?: TooltipPayloadItem[]; + label?: string +}) => { + if (active && payload && payload.length) { + return ( +
+

{label}

+ {payload.map((item, index) => ( +
+
+ {` ${item.name} : ${item.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`} +
+ ))} +
+ ); + } + return null; +}; + +// 커스텀 범례 +const CustomLegend = (props: LegendProps) => { + const { payload } = props; + if (!payload) return null; + + return ( +
+ {payload.map((entry: LegendEntry, index: number) => ( +
+
+ {entry.value} +
+ ))} +
+ ); +}; + +export default function DoughnutChart(props: { + chartConfig: ChartConfig; + chartData: ChartDataItem[] | undefined; + chartTitle: string +}) { return ( - {props.chartTitle && props.chartTitle !== "" && props.chartTitle !== "undefined" ? ( -
- {props.chartTitle} -
): null} + {props.chartTitle && props.chartTitle !== "" && props.chartTitle !== "undefined" ? ( +
+ {props.chartTitle} +
+ ) : null}
} + content={} /> ({ + ...item, + fill: props.chartConfig[item.label]?.fill || 'blue' + }))} dataKey="val" nameKey="label" innerRadius={60} /> +
- ) + ); } diff --git a/packages/common/business_components/src/ui/chart/LineBarChart.tsx b/packages/common/business_components/src/ui/chart/LineBarChart.tsx index 2e83458d8..8c7202104 100644 --- a/packages/common/business_components/src/ui/chart/LineBarChart.tsx +++ b/packages/common/business_components/src/ui/chart/LineBarChart.tsx @@ -92,9 +92,6 @@ export default function LineBarchart({ return
데이터가 없습니다.
; } - const barConfig = chartConfig?.barVal; - const lineConfig = chartConfig?.lineVal; - // 데이터의 최대값 계산 const getMaxValue = (data: any[], keyPrefix: string) => { return Math.max(...data.map(item => diff --git a/packages/common/business_components/src/ui/chart/index.tsx b/packages/common/business_components/src/ui/chart/index.tsx index b30eef3c3..4c58549cc 100644 --- a/packages/common/business_components/src/ui/chart/index.tsx +++ b/packages/common/business_components/src/ui/chart/index.tsx @@ -5,6 +5,7 @@ import DoughnutChart from './DoughnutChart'; import { type ChartConfig } from './lib/chart'; import LineChart from './LineChart'; import LineBarchart from './LineBarChart'; +import DoubleBarChart from './DoubleBar'; /**차트 FORM */ const CHART_FORM = { @@ -15,7 +16,9 @@ const CHART_FORM = { /**도넛 차트 형태*/ DN :'daughnut', /**LINE,BAR차트 */ - LINEBAR : 'linebar' + LINEBAR : 'linebar', + /**더블바 차트 형태*/ + DOUBLEBAR : 'doublebar' }; /** @@ -34,7 +37,7 @@ const CHART_FORM = { type MainChartProps = { chartForm: string; - chartConfig: any; + chartConfig: ChartConfig; chartData: any; chartTitle: string; chartClassName?: string; @@ -47,23 +50,23 @@ type MainChartProps = { function MainChart(props: MainChartProps) { if( props.chartForm == CHART_FORM.BAR ){ return ( - - + ); } else if( props.chartForm == CHART_FORM.LINE ){ return ( - - + ); } else if( props.chartForm == CHART_FORM.DN ){ return ( - - + ); } else if (props.chartForm == CHART_FORM.LINEBAR){ return ( - - + + ); + } else if (props.chartForm == CHART_FORM.DOUBLEBAR){ + return ( + ); } } diff --git a/packages/common/business_components/src/ui/form_ui/index.tsx b/packages/common/business_components/src/ui/form_ui/index.tsx index 96214b6cf..27b74bd97 100644 --- a/packages/common/business_components/src/ui/form_ui/index.tsx +++ b/packages/common/business_components/src/ui/form_ui/index.tsx @@ -39,7 +39,7 @@ const FormUi = React.forwardRef( checked={isChecked} onCheckedChange={handleCheckboxChange} /> - + {children} diff --git a/packages/common/business_components/src/ui/map/Gis.js b/packages/common/business_components/src/ui/map/Gis.js index 5cfff011d..f68d0798a 100644 --- a/packages/common/business_components/src/ui/map/Gis.js +++ b/packages/common/business_components/src/ui/map/Gis.js @@ -1,6 +1,5 @@ import './lib/css/gis.common.css'; import React, { createContext, useContext, useEffect, useMemo, useRef, useState, useCallback } from 'react'; -import { Tabs, TabsList, TabsTrigger, TabsContent } from '@common/components/ui/tabs'; import OlMap from 'ol/Map'; import View from 'ol/View'; import { defaults as defaultControls, OverviewMap } from 'ol/control'; @@ -10,43 +9,88 @@ 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 GisLonLat from './GisLonLat'; +import GisSelect from './GisSelect'; import GisToolBar from './GisToolBar'; -import GisTab from './GisTab'; -import MapToggleBtn from './MapToggleBtn'; -import FeatureClickEventPopup from '@/map/featureClickEventPopup'; +import GisMapToggle from './GisMapToggle'; +import { Search } from 'lucide-react'; -export const GisContext = createContext({gisCore: null, gisMap: null, treeData:null, checkedLayerIds:null}); +export const GisContext = createContext({ gisCore: null, gisMap: null, treeData: null, checkedLayerIds: null }); export const useGisContext = () => useContext(GisContext); -function Gis({ treeData = [], isSearch = false }) { +function Gis({ isOpen , gisMaps, isSearchModalOpen, treeData = [], isSearch = false, isMiniMap = false, setIsOpen, setFeatureData, featureData, searchView : SearchView, detailView: DetailView, onFeatureSelect, setIsSearchModalOpen }) { const mapRef = useRef(); const [mapObject, setMapObject] = useState({}); const [tabVisible, setTabVisible] = useState(true); - const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 - const [featureData,setFeatureData] = useState(null) // 선택된 피쳐 데이터 - const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태 + // const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태 + // const [featureData, setFeatureData] = useState(null) // 선택된 피쳐 데이터 + // const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태 const gisCore = useMemo(() => new GisApp.core({ targetId: mapRef.current }), []); - const mapInstanceRef = useRef(null); // 맵 생성 여부를 추적할 ref + const mapInstanceRef = useRef(null); const checkedLayerIds = useRef([]); let gisMap = null; const closePopup = () => { setIsOpen(false); // 팝업 닫기 setFeatureData(null) }; - const handleFeatureSelect = (data) => { - console.log('check',data) - setFeatureData(data); // 선택된 피처 데이터 저장 - setIsOpen(true); // 팝업 열기 - }; - // SearchModal이 열릴 때 featureClickEventPopup 닫기 - useEffect(() => { - if (isSearchModalOpen && isOpen) { - setIsOpen(false); - setFeatureData(null); + // SearchModal, GisContent 등에서 호출 + const handleFeatureSelect = useCallback((data) => { + gisMap = mapInstanceRef.current; + + if (!gisMap) { + console.warn('지도가 초기화되지 않았습니다.'); + return; } - }, [isSearchModalOpen]); + + // 항상 같은 select 객체 사용 + const select = GisApp.Module.select; + if (!select) return; + + // 1. 기존 선택 초기화 + select.resetSelectedFeature(); + + // 2. data가 OpenLayers Feature 인스턴스인지 확인 + let foundFeature = null; + if (data && typeof data.getGeometry === 'function' && typeof data.setStyle === 'function') { + // 이미 Feature 인스턴스라면 그대로 사용 + foundFeature = data; + } else { + // 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용 + const featureId = data.fid || data.ftrIdn || data.id; + gisMap.getLayers().getArray().forEach(layer => { + const source = layer.getSource?.(); + if (source?.getFeatureById) { + const feature = source.getFeatureById(String(featureId).trim()); + if (feature) foundFeature = feature; + } + }); + } + + // 3. 피처 선택 + if (foundFeature) { + let geometry = foundFeature.getGeometry(); + if (geometry) { + let extent = geometry.getExtent(); + + gisMap.getView().fit(extent, { + duration: 300, + padding: [50, 50, 50, 50], + maxZoom: 16, + constrainResolution: true, + nearest: true, + }); + } + select.selectFeature(foundFeature, true); + } else { + console.warn('OpenLayers Feature를 찾을 수 없습니다:', data); + } + + setFeatureData(data); + setIsOpen(true); + setIsSearchModalOpen(false); + }, [mapInstanceRef]); useEffect(() => { if (!mapRef.current) return; @@ -78,7 +122,7 @@ function Gis({ treeData = [], isSearch = false }) { projection: GisApp.TO_PROJ, zoom: gisCore.defaults.zoom, center: olProj.transform( - [126.85306, 35.571634], + [126.6757, 37.5585], GisApp.FROM_PROJ, GisApp.TO_PROJ ), @@ -87,21 +131,24 @@ function Gis({ treeData = [], isSearch = false }) { }), }); + gisMaps.current = map + //미니맵 - const overviewMap = new OverviewMap({ - layers: [GisApp.Module.core.baseMiniMapLayers['base']], - view: new View({ - projection: GisApp.TO_PROJ, - minZoom: 9, - }), - collapsed: false, - collapseLabel: '\u00BB', - label: '\u00AB', - }); + if(isMiniMap){ + const overviewMap = new OverviewMap({ + layers: [GisApp.Module.core.baseMiniMapLayers['base']], + view: new View({ + projection: GisApp.TO_PROJ, + minZoom: 9, + }), + collapsed: false, + collapseLabel: '\u00BB', + label: '\u00AB', + }); + map.addControl(overviewMap); + } - map.addControl(overviewMap); gisCore.__proto__.map = map; - gisCore.scaleControl(); gisCore.changeBaseLayer('base'); setMapObject({ map: map }); @@ -122,7 +169,7 @@ function Gis({ treeData = [], isSearch = false }) { //setEditLayerItems(prev => [...layerItems]) }, [treeData]); - const getLayerItems= (layerCode) => { + const getLayerItems = (layerCode) => { const layerItems = Object.entries(layerCode) .filter(([key, obj], idx) => obj?.updtPsblYn === 'Y') .map(([key, obj]) => ({ @@ -149,21 +196,48 @@ function Gis({ treeData = [], isSearch = false }) { return ( <> - +
- - - {isOpen && featureData && ( - + + + {/* */} + + {/* isSearchModalOpen이 true면 visible=false로 팝업 숨김 */} + {isOpen && featureData && !isSearchModalOpen && ( + )} -
- {/* + + - */} + +
+ + {isSearch && ( +
+ +
+ )} ); diff --git a/packages/common/business_components/src/ui/map/GisContent.js b/packages/common/business_components/src/ui/map/GisContent.js index 93edcd12c..a8ac408e8 100644 --- a/packages/common/business_components/src/ui/map/GisContent.js +++ b/packages/common/business_components/src/ui/map/GisContent.js @@ -1,14 +1,14 @@ -import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import GisApp from './lib/gis.core'; import { useGisContext } from './Gis'; import GisLonLat from './GisLonLat'; import GisSelect from './GisSelect'; import GisToolBar from './GisToolBar'; import './lib/css/gis.edit.css'; -import MapToggleBtn from './MapToggleBtn'; -import GisEdit from './GisEdit'; +import GisMapToggle from './GisMapToggle'; +import { Search } from 'lucide-react'; -export default function GisContent({ edit = false, onFeatureSelect }) { +export default function GisContent({ edit = false, onFeatureSelect, isSearch, setIsSearchModalOpen }) { const { gisMap, gisCore } = useGisContext(); const [visibleComponents, setVisibleComponents] = useState({}); const addressResultLayer = useRef(null); @@ -16,12 +16,12 @@ export default function GisContent({ edit = false, onFeatureSelect }) { //셀렉트 버튼 이벤트 // const clickFeature = useCallback(feature => { - // if (feature) { - // const layer = feature.getLayer(); - // setVisibleComponents(prevState => ({ - // ...prevState, - // })); - // } + // if (feature) { + // const layer = feature.getLayer(); + // setVisibleComponents(prevState => ({ + // ...prevState, + // })); + // } // }, []); const selectRslt = useCallback(feature => { @@ -45,16 +45,35 @@ export default function GisContent({ edit = false, onFeatureSelect }) { })); } }, [gisMap]); - + if (!gisMap) return null; - + return ( <> {/**/} - + {/* - - + */} + {/* */} + + {/* 검색 모달 */} + {isSearch && ( +
+ +
+ )} ); } diff --git a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx index d59108c5b..6ccaac946 100644 --- a/packages/common/business_components/src/ui/sdmInsertForm/form.tsx +++ b/packages/common/business_components/src/ui/sdmInsertForm/form.tsx @@ -2,10 +2,43 @@ import { SelectBox } from "../select"; import { Input } from "@common/components"; import { FormUi } from "../form_ui"; -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import type { ControllerRenderProps, UseFormReturn } from "react-hook-form"; import { SdmSearchForm } from "./sdmNameBox"; -import type { DemandCompType } from "../../../../../../apps/dm/app/store/sdmMng"; +import { set } from "date-fns"; + +// 수요처 정보 +export type DemandCompType = { + index : number | ''; + dmdInfoPk : string | ''; + dmdInfoFk : string | ''; + bzmnNo : string | ''; + dmdCoNm : string | ''; + daddr : string | ''; + telno : string | ''; + rgtr : string | ''; + useUsgCd : string | ''; + ctpvCd : string | ''; + sggCd : string | ''; + dmdAplyPswd : string | ''; + wntUntprc : number | ''; + dmndTmng : Date | ''; + dmndQty : number | ''; + grssClfg : number | ''; + tn : number | ''; + combResdch : number | ''; + tph : number | ''; + trbt : number | ''; + ph : number | ''; + blgcOxygDmndQnt : number | ''; + clIonQnt : number | ''; + smll : number | ''; + cdtnv : number | ''; + crmty : number | ''; + rmrk : string | ''; + reqDt : string | ''; +} + type SelectDataType = { text: string; @@ -32,16 +65,19 @@ interface SdmRegFormProps { dataList: DemandCompType[]; rtnValue: (searchText: string, pageCnt: number) => void; setIsDuplicate: (value: boolean) => void; + updateList?:DemandCompType } type FieldComponent = (field: ControllerRenderProps) => JSX.Element; -export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigunData, dataList, rtnValue, setIsDuplicate }: SdmRegFormProps) { +export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigunData, dataList, rtnValue, setIsDuplicate ,updateList}: SdmRegFormProps) { const [sidoValue, setSidoValue] = useState(''); const [sigunValue, setSigunValue] = useState(''); const [filteredSigunData, setFilteredSigunData] = useState([{ text: "전체", val: '0' }]); const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true); const [orgBznmNo, setOrgBznmNo] = useState(''); + const [updateCoNm, setUpdateNm] = useState('') + const initializeSigunData = useCallback((sidoCd: string) => { if (sidoCd === '0') { @@ -62,6 +98,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun type: string, field: ControllerRenderProps | undefined ) => { + if(!updateList?.dmdInfoPk) switch (type) { case "ctpvCd": initializeSigunData(val); @@ -77,7 +114,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun form.setValue('bznmTotNo', ''); break; } - }, [initializeSigunData, form]); + }, [initializeSigunData, form,updateList]); const handleCheckboxChange = useCallback((checked: boolean) => { setIsBznmTotNoDisabled(checked); @@ -90,6 +127,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun const setRtnData = useCallback((item: DemandCompType) => { const rtnCompData = item; + form.setValue('dmdCoNm', rtnCompData?.dmdCoNm || ''); form.setValue('dmdInfoPk', rtnCompData?.dmdInfoPk.substring(0,10) || ''); form.setValue('bznmTotNo', rtnCompData?.dmdInfoPk.substring(10,14)==='0000' ? '' : rtnCompData?.dmdInfoPk.substring(10,14)); @@ -124,28 +162,46 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun form.setValue('dmdCoNm', text); }, [form]); - const bznNoChange = useCallback((e: React.ChangeEvent, noType: string) => { + const bznNoChange = useCallback((e: React.ChangeEvent, noType: string, field?: ControllerRenderProps) => { const value = e.target.value; - console.log('form value : '+form.getValues('dmdInfoPk')); - console.log('org value : '+orgBznmNo); - + if(noType === 'dmdInfoPk') { if(orgBznmNo.substring(0,10) === value) { setIsDuplicate(true); } else { setIsDuplicate(false); } - form.setValue('dmdInfoPk', value); + field?.onChange(value); } else { if(orgBznmNo.substring(10,14) === value) { setIsDuplicate(true); } else { setIsDuplicate(false); } - form.setValue('bznmTotNo', value); + field?.onChange(value); } + }, [orgBznmNo, setIsDuplicate]); - }, [form, orgBznmNo, setIsDuplicate]); + + useEffect(() => { + if(updateList?.dmdInfoPk){ + form.reset(updateList) + if(updateList?.dmdInfoPk.slice(10,14) !== '0000') { + handleCheckboxChange( false); + form.setValue('bznmTotNo', updateList?.dmdInfoPk.slice(10,14)); + } else { + handleCheckboxChange( true); + } + form.setValue('dmdInfoPk', updateList?.dmdInfoPk.slice(0,10)); + setUpdateNm(updateList?.dmdCoNm) + // setSigunValue(updateList?.sggCd) + }else{ + handleCheckboxChange( true); + } + }, [updateList,form]); + + useEffect(() => { + },[form.formState.errors]) const formFields: Array<{ name: keyof FormSchema; @@ -156,28 +212,51 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun name: "ctpvCd", label: "시도", component: (field) => ( - {field.onChange(e.target.value)} } + value={ selectSidoData.find(item => item.val === field.value?.trim() )?.text??''} + readOnly={!!updateList?.dmdInfoPk} + /> + ) : ( + onSelectValue(val.toString(), 'ctpvCd', field)} + onSelectValue={(val) => onSelectValue(val.toString(), 'ctpvCd', field??'')} className="" value={sidoValue} /> + ) ) }, { name: "sggCd", label: "시군구", component: (field) => ( + updateList?.dmdInfoPk ? ( + {field.onChange(e.target.value)} } + value={selectSigunData.find(item => item.val === field.value?.trim() )?.text??''} + readOnly={!!updateList?.dmdInfoPk} + /> + ) : ( onSelectValue(val.toString(), 'sggCd', field)} className="" value={sigunValue} /> + + ) ) }, { @@ -187,7 +266,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun bznNoChange(e, 'dmdInfoPk')} + onChange={(e) => bznNoChange(e, 'dmdInfoPk', field)} + value={field.value} + readOnly={!!updateList?.dmdInfoPk} /> ) }, @@ -222,8 +302,10 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun type="text" className="!mt-5 !text-xl text-gray-600" disabled={isBznmTotNoDisabled} - {...field} - onChange={(e) => bznNoChange(e, 'bznmTotNo')} + onChange={(e) => bznNoChange(e, 'bznmTotNo', field)} + // {...field} + value={ field.value} + readOnly={!!updateList?.dmdInfoPk} /> ) @@ -252,6 +334,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun /> ) }, + { name: "dmdAplyPswd", label: "패스워드", @@ -264,11 +347,18 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun /> ) } - ]; + ] return ( <> - {formFields.map(({ name, label, component }) => ( + {formFields.filter((item)=> + {if(updateList?.dmdInfoPk){ + return item.name !== 'dmdAplyPswd' + }else{ + return item + } + }) + .map(({ name, label, component }) => ( void; rtnInputData: (data: DemandCompType) => void; bodyClassNm?: string; + updateList?:DemandCompType } -const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean) => z.object({ +const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean ,updateList?:DemandCompType) => z.object({ ctpvCd: z.string().min(1, "시/도를 선택해주세요"), sggCd: z.string().min(1, "시/군/구를 선택해주세요"), dmdCoNm: z.string() @@ -57,19 +40,19 @@ const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean) => .max(40, "주소는 40자 이내로 입력해주세요"), telno: z.string() .min(8, "전화번호는 8자 이상 입력해주세요") - .max(12, "전화번호는 12자 이내로 입력해주세요") + .max(11, "전화번호는 11자 이내로 입력해주세요") .regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"), rgtr: z.string().optional(), - dmdAplyPswd : z.string() - .min(1, "패스워드를 입력해주세요") - .min(8, "패스워드는 8자 이상 입력해주세요") - .max(16, "패스워드는 16자 이내로 입력해주세요"), + dmdAplyPswd : updateList?.dmdInfoPk // 업데이트일경우 + ? z.string().optional() // 패스워드는 선택 사항이며 길이 제한 없음 + : z.string().optional() + .refine((val) => !val || (val.length >= 8 && val.length <= 16), "패스워드는 8자 이상 16자 이내로 입력해주세요"), + }); -type FormSchema = ReturnType; -export type FormData = z.infer; +type FormSchema = z.infer>; -const defaultValues: FormData = { +const defaultValues: FormSchema = { ctpvCd: '', sggCd: '', dmdCoNm: '', @@ -78,7 +61,7 @@ const defaultValues: FormData = { daddr: '', telno: '', rgtr: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - dmdAplyPswd : '', + dmdAplyPswd: '', }; /** @@ -117,15 +100,15 @@ const defaultValues: FormData = { }, [insertSdmData]); */ -export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm}: thisProps) { +export default function SdmInsertForm({selectSidoData, selectSigunData, dataList, rtnValue, rtnInputData,bodyClassNm, updateList}: thisProps) { /* const { insertSdmData } = useDmStore((state) => state); const router = useRouter(); */ - const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(true); + const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(false); const [isDuplicate, setIsDuplicate] = useState(false); - const formSchema = createFormSchema(isBznmTotNoDisabled, isDuplicate); + const formSchema = createFormSchema(isBznmTotNoDisabled, isDuplicate, updateList ); - const form = useForm>({ + const form = useForm({ resolver: zodResolver(formSchema), defaultValues, mode: "onChange", @@ -136,7 +119,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList // 체크박스 상태가 변경될 때마다 bznmTotNo 필드의 에러를 초기화 useEffect(() => { - if (isBznmTotNoDisabled) { + if (isBznmTotNoDisabled===true) { form.clearErrors('bznmTotNo'); form.setValue('bznmTotNo', ''); } @@ -146,7 +129,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList rtnValue(searchText, pageCnt); }, [rtnValue]); - const onSubmit: SubmitHandler> = async (data) => { + const onSubmit: SubmitHandler = async (data) => { try { // form 에러 체크 const formErrors = form.formState.errors; @@ -160,27 +143,18 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList const formData = { ...data, dmdInfoPk, + bzmnNo: data.dmdInfoPk, }; + + console.log(' formData ', formData) - console.log(formData); /* await insertSdmData(formData); */ rtnInputData(formData as DemandCompType); - const queryParams = new URLSearchParams({ - dmdCoNm: data.dmdCoNm, - ctpvCd: data.ctpvCd, - sggCd: data.sggCd, - dmdInfoPk, - bznmTotNo: data.bznmTotNo || '', - daddr: data.daddr, - telno: data.telno, - }); //router.push(`/pages/sdmMng/sdmInfoInsert?${queryParams.toString()}`); - toast.success('수요처가 성공적으로 등록되었습니다.'); } catch (error) { console.error('Error submitting form:', error); - toast.error('수요처 등록에 실패했습니다.'); } }; @@ -203,6 +177,7 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList dataList={dataList} rtnValue={setRtnValue} setIsDuplicate={setIsDuplicate} + updateList={updateList} />