This commit is contained in:
swcho
2025-08-09 22:42:20 +09:00
14 changed files with 187 additions and 67 deletions
+25
View File
@@ -0,0 +1,25 @@
"use client";
import type { MenuItem } from "@common/components/api";
import { NoFooterLayout } from "@common/components/ui";
import { usePathname,useRouter } from "next/navigation";
import { useWrStore } from "../store";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const { getMenuAuthrts } = useWrStore((state) => state);
const router = useRouter();
const pathname = usePathname();
const changeMenu = (path: MenuItem) => {
getMenuAuthrts(path.menuCd);
router.push(path.urlPath);
};
return (
<NoFooterLayout currentPath={pathname ?? ""} handleMenuClick={changeMenu}>
{children}
</NoFooterLayout>
);
}
@@ -2,11 +2,12 @@
import Gis from "@common/business_components/ui/map/Gis";
import { useEffect, useRef, useState, useCallback } from "react";
import { mapService } from "../service";
import { mapService } from "../../service";
import GisApp from "@common/business_components/ui/map/lib/gis.core";
import { SearchBar } from "@common/business_components/ui/map/searchBar/searchBar";
import { useWrStore } from "@/app/store";
import { getFeatureCd } from "@/components/lib/func/mapUtil";
import toast, { Toaster } from "react-hot-toast";
const Map = () => {
const { comMap } = useWrStore((state) => state);
@@ -228,7 +229,6 @@ const Map = () => {
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=no`;
popupRef.current = window.open(url, "지도 레이어 팝업", popupOptions);
} else {
console.log('isFeature 2', isFeature)
const layerNm = getSelectedLayers(isFeature);
const safeProps = isFeature.getProperties();
const featureCd = getFeatureCd(safeProps, String(layerNm));
@@ -266,7 +266,20 @@ const Map = () => {
};
const onOpenPopup = (data:any) => {
console.log(data)
if(data){
const url = `/mapDetailPopUp?layerNm=${encodeURIComponent(data)}`;
const width = window.screen.availWidth;
const height = window.screen.availHeight;
const left = 0;
const top = 0;
const popupOptions = `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=no`;
popupRef.current = window.open(url, "지도 레이어 팝업", popupOptions);
}else{
toast.error('시설 및 수요처가 선택되지 않았습니다.')
}
}
return (
@@ -307,7 +320,8 @@ const Map = () => {
onOpenPopup(data)
}}
/>
</div>
<Toaster position="top-center" />
</div>
);
};
@@ -16,7 +16,7 @@ export default function MapDetailPopUp() {
const renderConditionalContent = () => {
const layerId = searchParams.get("layerNm");
switch (layerId) {
case "하수재이용시설":
case "tb_wr_bdst_ruse_fclt":
return (
<RuseFacility
rtnFeature={(feature) => {
@@ -24,7 +24,7 @@ export default function MapDetailPopUp() {
}}
/>
);
case "하수처리시설":
case "tb_il_swage_prcs_fclt":
return (
<HasuFacility
rtnFeature={(feature) => {
@@ -32,7 +32,7 @@ export default function MapDetailPopUp() {
}}
/>
);
case "빗물이용시설":
case "tb_wr_rnwtr_utztn_fclt":
return (
<RainFacility
rtnFeature={(feature) => {
@@ -40,7 +40,7 @@ export default function MapDetailPopUp() {
}}
/>
);
case "중수도시설":
case "tb_wr_rswtr_fclt":
return (
<RswtFacility
rtnFeature={(feature) => {
@@ -48,7 +48,7 @@ export default function MapDetailPopUp() {
}}
/>
);
case "온배수시설":
case "tb_wr_htdfl_fclt":
return (
<HtdflFacility
rtnFeature={(feature) => {
@@ -56,7 +56,7 @@ export default function MapDetailPopUp() {
}}
/>
);
case "수요처":
case "tb_wr_ruse_fclt_dmd_co":
return (
<CoSttnMap
rtnFeature={(feature) => {
@@ -64,7 +64,7 @@ export default function MapDetailPopUp() {
}}
/>
);
case "잠재수요처":
case "tb_wr_tmpr_dmd_co":
return (
<LdrmntCoMap
rtnFeature={(feature) => {
@@ -1,6 +1,6 @@
"use client";
import { useWrStore } from "@/app/store";
import { RuseDetailPopup } from "@/components/ui/map/LayerPopUp/detailPopup/ruseDetailPopup";
import { RuseDetailPopup } from "@/components/ui/map/detailPopup/ruseDetailPopup";
import CoDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/coDatailModal";
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
import { Title, UiTable } from "@common/business_components/ui";
+30 -9
View File
@@ -1,4 +1,4 @@
import { fetchType, getFetch } from "@/components/lib/api";
import { fetchType, getFetch, postFectch } from "@/components/lib/api";
import type { CommonTableProps } from "../../common/type/header";
import type { WaterReuseFacility } from "../../ruseFcltMng/fcltSttn/pbnstSttn/type";
import {
@@ -16,7 +16,7 @@ export type ruseMapState = {
ruseMapCount: number;
isInit: boolean;
fclts: string[];
ruseDetailList:customPbnst[]
ruseDetailList: customPbnst[];
ruseMapHeadList: CommonTableProps[];
ruseMapNodeList: CommonTableProps[];
};
@@ -32,16 +32,17 @@ type ruseMapActions = {
fclts: string[]
) => void;
ruseMapDetail: (ruseFcltId: string) => Promise<customPbnst | undefined>;
getRuseMaplList :(ruseFcltId: string) => void;
getRuseMaplList: (bscFctCd: string) => void;
};
export type ruseMapType = ruseMapState & ruseMapActions;
export const ruseMapStateExport: ruseMapState = {
ruseMap: {
isInit: false,
ruseMapRes: [],
ruseDetailList:[],
ruseDetailList: [],
fclts: [],
ruseMapCount: 1,
ruseMapHeadList: pbnSttHeadListExport,
@@ -109,15 +110,36 @@ export const ruseMapActionsExport: (set: any) => ruseMapActions = (
console.log(errorHasu);
throw errorHasu; // 호출부에서 catch 가능하도록
}
},getRuseMaplList:async(bscFctCd: string) =>{
},
getRuseMaplList: async (bscFctCd: string) => {
try {
const ruseDetailList = await getFetch("wr", `/reuseFc/pubFc/${bscFctCd}`);
const ruseDetailList = await getFetch(
fetchType.WR,
`/reuseFc/pubFc/${bscFctCd}`
);
const year = new Date().getFullYear();
const data = [bscFctCd];
const rusePrfList = await postFectch(
`/reuseFc/pubDetailList/${year}/0/1/10`,
data,
fetchType.WR
);
const dataList = ruseDetailList.map((ruse) => {
const matchRuse = rusePrfList?.data.find(
(prf) => prf.pbnstRuseFcltId === ruse.pbnstRuseFcltId
);
return {
...ruse,
prfList: matchRuse.prfList,
};
});
console.log("/dataList ", dataList);
set((state: ruseMapState) => {
return {
...state,
ruseMap: {
...state.ruseMap,
ruseDetailList: ruseDetailList,
ruseDetailList: dataList,
},
};
});
@@ -125,7 +147,6 @@ export const ruseMapActionsExport: (set: any) => ruseMapActions = (
console.log(errorHasu);
throw errorHasu; // 호출부에서 catch 가능하도록
}
}
},
};
};
@@ -231,6 +231,30 @@ export const fcBizSchema = z.object({
mdfr: z.string().nullish(),
});
const PrfSchema = z.object({
pbnstRuseFcltId: 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 pbnstRegZod = z.object({
pbnstRuseFcltId: z.string().default(""),
swtrmtFcltId: z.string().default(""),
@@ -258,11 +282,14 @@ export const pbnstRegZod = z.object({
fcBizs: z.array(fcBizSchema).default([]),
fcOpers://z.array(fcOperSchema).default([]),
z .array(fcOperSchema)
.min(1, { message: "재이용시설의 운영정보를 최소 하나를 등록해주세요" })
.min(1, { message: "재이용시설의 운영정보를 최소 하나를 등록해주세요" }),
prfList: z.array(PrfSchema).nullish(),
});
export const pbnstRegArrayZod = z.array(pbnstRegZod);
export const pbnstRegArrayZod = z.array(pbnstRegZod);
export type PbnstRegArrrayType = z.infer<typeof pbnstRegArrayZod>;
export type fcBizType = z.infer<typeof fcBizSchema>;
+11 -2
View File
@@ -41,7 +41,10 @@ export const getFetch = async (type: string, url: string) => {
// JSON 응답 처리
const res = await response.json();
return res.data;
} else {
} else if(contentType.includes('application/octet-stream')) {
// 파일 응답 처리 (ex. PDF, Excel 등)
console.log('contentType ' ,contentType)
// 파일 응답 처리 (ex. PDF, Excel 등)
const blob = await response.blob();
const blobUrl = window.URL.createObjectURL(blob);
@@ -54,6 +57,8 @@ export const getFetch = async (type: string, url: string) => {
window.URL.revokeObjectURL(blobUrl);
return null; // 다운로드이므로 반환값 없음
}else{
throw Error('오류 발생')
}
};
@@ -89,8 +94,10 @@ export const getFetchWithCount = async (type: string, url: string) => {
const res = await response.json();
return res;
} else {
} else if(contentType.includes('application/octet-stream')) {
// 파일 응답 처리 (ex. PDF, Excel 등)
console.log('contentType ' ,contentType)
const blob = await response.blob();
const blobUrl = window.URL.createObjectURL(blob);
const a = document.createElement("a");
@@ -102,6 +109,8 @@ export const getFetchWithCount = async (type: string, url: string) => {
window.URL.revokeObjectURL(blobUrl);
return null; // 다운로드이므로 반환값 없음
}else{
throw Error('오류 발생')
}
};
@@ -50,6 +50,10 @@ export default function ConCostForm({
const ref = useRef<boolean>(false);
const [checkFinish, setCheckFinish] = useState<boolean>(false);
const [lastSub, setLastSub] = useState<{
ruseUtztnFcltNm: string;
ruseUtztnFcltCd: string;
} | null>(null);
useEffect(() => {
if (!ref.current) {
@@ -80,7 +84,7 @@ export default function ConCostForm({
const dmndQtyWatch = form.watch("dmndQty");
const totalConstCost = form.watch("totalConstCost");
const cstrnCst = form.watch("demandCst.cstrnCst");
const splyList = form.watch("splyCndtList");
const calculateConstCost = useCallback(() => {
const usgPrcsProcs = usgPrcsProcsWatch;
if (!dmndQtyWatch) {
@@ -157,8 +161,11 @@ export default function ConCostForm({
return;
}
const splycd = form.getValues("splyCndtList")
const pk = splycd&&splycd[0]?.ruseUtztnFcltCd?splycd[0]?.ruseUtztnFcltCd:'11000SW001R1'
const splycd = form.getValues("splyCndtList");
const pk =
splycd && splycd[0]?.ruseUtztnFcltCd
? splycd[0]?.ruseUtztnFcltCd
: "11000SW001R1";
if (type === "mat") {
if (value.demandCst) {
@@ -183,11 +190,7 @@ export default function ConCostForm({
onClick={() => {
toast.dismiss(t.id);
coMatRvwUpdate(
pk,
form.getValues("dmdInfoId"),
data
);
coMatRvwUpdate(pk, form.getValues("dmdInfoId"), data);
}}
>
확인
@@ -199,7 +202,6 @@ export default function ConCostForm({
</span>
));
} else {
coMatRvwUpdate(pk, form.getValues("dmdInfoId"), data);
}
}
@@ -216,6 +218,10 @@ export default function ConCostForm({
console.log(" form ", form.formState.errors);
}, [form.formState]);
useEffect(() => {
console.log("splyCndtList ", splyList);
}, [splyList]);
useEffect(() => {
form.register("dmdInfoSn");
form.register("dmdInfoId");
@@ -369,8 +375,8 @@ export default function ConCostForm({
console.log("dmndQty ", e);
//field.onChange(Number(e.target.value) * 365 );
}}
// value={Number(field.value) * 365 || 0}
value={Number(field.value) || 0}
// value={Number(field.value) * 365 || 0}
value={Number(field.value) || 0}
readOnly
/>
</FormUi>
@@ -501,30 +507,32 @@ export default function ConCostForm({
)}
/>
</div>
{/* <div className="col-span-3 mt-4">
<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
size={"sm"}
onClick={(e) => {
console.log(e);
setLastSub(null) // 빌드오류때문에 넣은거 삭제필요
//splyList => 해당객체가 대민에서 선택한 후보처 리스트
//setLastSub => 해당 스테이트가 선택한 마지막 후보처를 넣어야하는 스테이트
}}
className="bg-none"
>
후보지 조회
</Button>
</div>
<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> */}
<FormUi label="">
<Input
placeholder=""
type="text"
value={lastSub?.ruseUtztnFcltNm || ""}
readOnly
/>
</FormUi>
</div>
<div className="col-span-3 mt-4">
<FormField
control={form.control}
@@ -536,8 +544,7 @@ export default function ConCostForm({
type="number"
step="0.01"
onChange={(e) => {
if(readonly) return;
if (readonly) return;
field.onChange(Number(e.target.value));
}}
@@ -0,0 +1,10 @@
export default function coSttnDetailPopup(){
return(
<>
</>
)
}
@@ -223,17 +223,24 @@ export function PbnstSttnModal({ data, titleVisible,isMap}: { data: customPbnst;
}
};
useEffect(() => {
if (pbnstSttn.pbnstSttnRes && data) {
const prfList = pbnstSttn.pbnstSttnRes.find(
(item) => item.pbnstRuseFcltId === data.pbnstRuseFcltId
)?.prfList;
if(isMap){
if(data.prfList &&data.prfList.length>0){
getTablePrfData(data.prfList);
}
}else{
if (prfList) {
if (pbnstSttn.pbnstSttnRes && data) {
const prfList = pbnstSttn.pbnstSttnRes.find(
(item) => item.pbnstRuseFcltId === data.pbnstRuseFcltId
)?.prfList;
getTablePrfData(prfList);
if (prfList) {
getTablePrfData(prfList);
}
}
}
}, [pbnstSttn.pbnstSttnRes, data]);
}, [pbnstSttn.pbnstSttnRes, data,isMap]);
useEffect(() => {