Merge branch 'iipbs/sn/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/sn/dev
This commit is contained in:
@@ -7,7 +7,7 @@ import ListDiv from '@common/business_components/ui/list_div';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Toaster } from 'react-hot-toast';
|
||||
import SdmLogin from '../sdmLogin/page';
|
||||
import type { DemandCompType } from '@/app/store/sdmMng';
|
||||
import type { DemandCompBizType } from '@/app/store/sdmMng';
|
||||
import TransValueFormat from '@/app/common/transValueFormat';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
@@ -31,8 +31,8 @@ export default function SdmApplyList({}: SdmApplyProps) {
|
||||
const {selectSidoData, selectSigunData} = Common;
|
||||
const [isLogin, setIsLogin] = useState(false);
|
||||
const [isLoginStorageInfo, setIsLoginStorageInfo] = useState(false);
|
||||
const [sdmApplyDetail, setSdmApplyDetail] = useState<DemandCompType>({} as DemandCompType);
|
||||
const [transformedList, setTransformedList] = useState<DemandCompType[]>([]);
|
||||
const [sdmApplyDetail, setSdmApplyDetail] = useState<DemandCompBizType>({} as DemandCompBizType);
|
||||
const [transformedList, setTransformedList] = useState<DemandCompBizType[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('sessionStorage : ',sessionStorage.getItem('user'));
|
||||
@@ -60,10 +60,10 @@ export default function SdmApplyList({}: SdmApplyProps) {
|
||||
// 데이터 변환을 위한 별도의 useEffect
|
||||
useEffect(() => {
|
||||
if (sdmInfoStatusList.length > 0) {
|
||||
const newTransformedList = sdmInfoStatusList.map((item: DemandCompType) => ({
|
||||
const newTransformedList = sdmInfoStatusList.map((item: DemandCompBizType) => ({
|
||||
...item,
|
||||
ctpvCd: selectSidoData.find(sido => sido.val === item.ctpvCd?.trim())?.text || '',
|
||||
sggCd: selectSigunData.find(sigun => sigun.val === item.sggCd?.trim())?.text || ''
|
||||
sggCd: selectSigunData.find(sigun => sigun.val === item.sggCd?.trim())?.text || '',
|
||||
}));
|
||||
setTransformedList(newTransformedList);
|
||||
}
|
||||
@@ -73,6 +73,8 @@ export default function SdmApplyList({}: SdmApplyProps) {
|
||||
if (index !== undefined) {
|
||||
const selectedStatus = transformedList[index];
|
||||
if (selectedStatus) {
|
||||
|
||||
|
||||
setSdmApplyDetail(selectedStatus);
|
||||
}
|
||||
}
|
||||
@@ -121,33 +123,33 @@ export default function SdmApplyList({}: SdmApplyProps) {
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>총대장균군수(개/100ml)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.grssClfg} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.grssClfg ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>결합잔류염소(mg/L)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.combResdch} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.combResdch ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>탁도(NTU)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.trbt} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.trbt ?? ''} format="number"/>}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>생물학적 산소요구량(BOD)(mg/L)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.blgcOxygDmndQnt} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.blgcOxygDmndQnt ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>냄새</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.smll} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>색도(도)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.crmty} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.crmty ?? ''} format="number"/>}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>총질소(T-N)(mg/L)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tn} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tn ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>총인(T-P)(mg/L)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tph} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tph ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>수소이온농도(pH)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.ph} format="number"/>}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>염화물(mgCL/L)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.clIonQnt} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.clIonQnt ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>전기전도도(㎲/cm)</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.cdtnv} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.cdtnv ?? ''} format="number"/>}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>비고</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{sdmApplyDetail?.rmrk}</TableCell>
|
||||
</TableRow>
|
||||
@@ -156,11 +158,11 @@ export default function SdmApplyList({}: SdmApplyProps) {
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>후보지1</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}></TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{ sdmApplyDetail?.splyCndtList?.[0]?.ruseUtztnFcltNm ?? ""}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>후보지2</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}></TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{sdmApplyDetail?.splyCndtList?.[1]?.ruseUtztnFcltNm ?? ""}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>후보지3</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}></TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{sdmApplyDetail?.splyCndtList?.[2]?.ruseUtztnFcltNm ?? ""}</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
@@ -177,7 +179,7 @@ export default function SdmApplyList({}: SdmApplyProps) {
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>진행상태</TableCell>
|
||||
<TableCell colSpan={2} className={TABLE_STYLES.cell}>{sdmApplyDetail?.status?.toString()}</TableCell>
|
||||
<TableCell colSpan={1} className={TABLE_STYLES.header}>공급처매칭결과</TableCell>
|
||||
<TableCell colSpan={2} className={TABLE_STYLES.cell}></TableCell>
|
||||
<TableCell colSpan={2} className={TABLE_STYLES.cell}>{sdmApplyDetail?.ruseUtztnFcltNm??''}</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useDmStore } from "@/app/store";
|
||||
import type { DemandCompType } from "@/app/store/sdmMng";
|
||||
import type { DemandCompBizType } from "@/app/store/sdmMng";
|
||||
import { SdmInfoRegForm } from "@/components/ui/sdmInfoInsertForm/component";
|
||||
import { UiModal } from "@common/business_components/ui/dialog_ui";
|
||||
import { Button } from "@common/components/ui";
|
||||
@@ -14,60 +14,41 @@ import * as z from "zod";
|
||||
import SdmLogin from "../sdmLogin/page";
|
||||
|
||||
const sdmInfoFormSchema = z.object({
|
||||
sdmNm: z.string()
|
||||
.min(1, "수요처를 선택해주세요"),
|
||||
sdmNm: z.string().min(1, "수요처를 선택해주세요"),
|
||||
demandYmd: z.date().optional(),
|
||||
demandQnty: z.string()
|
||||
demandQnty: z
|
||||
.string()
|
||||
.min(1, "요구수량을 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "요구수량은 숫자만 입력 가능합니다"),
|
||||
usePurpose: z.string().optional(),
|
||||
money: z.string()
|
||||
.regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"),
|
||||
money: z.string().regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"),
|
||||
/**요구수질 */
|
||||
reqWaterQlty: z.string().optional(),
|
||||
grssClfg: z.string()
|
||||
.min(1, "총대장균군수를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "총대장균군수는 숫자만 입력 가능합니다"),
|
||||
tn: z.string()
|
||||
.min(1, "총질소를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "총질소는 숫자만 입력 가능합니다"),
|
||||
combResdch: z.string()
|
||||
.min(1, "결합잔류염소를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "결합잔류염소는 숫자만 입력 가능합니다"),
|
||||
tph: z.string()
|
||||
.min(1, "총인산물을 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "총인산물은 숫자만 입력 가능합니다"),
|
||||
trbt: z.string()
|
||||
.min(1, "탁도를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "탁도는 숫자만 입력 가능합니다"),
|
||||
ph: z.string()
|
||||
.min(1, "수소이온농도를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "수소이온농도는 숫자만 입력 가능합니다"),
|
||||
bod: z.string()
|
||||
.min(1, "생물학적 산소요구량을 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "생물학적 산소요구량은 숫자만 입력 가능합니다"),
|
||||
grssClfg: z.number().nullish(),
|
||||
tn: z.number().nullish(),
|
||||
combResdch: z.number().nullish(),
|
||||
tph: z.number().nullish(),
|
||||
trbt: z.number().nullish(),
|
||||
ph: z.string().nullish(),
|
||||
bod: z.number().nullish(),
|
||||
/**컬럼확인필요 */
|
||||
clIonQnt: z.string()
|
||||
.min(1, "염화물을 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "염화물은 숫자만 입력 가능합니다"),
|
||||
smll: z.string()
|
||||
.min(1, "냄새를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "냄새는 숫자만 입력 가능합니다"),
|
||||
cdtnv: z.string()
|
||||
.min(1, "전기전도도를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "전기전도도는 숫자만 입력 가능합니다"),
|
||||
crmty: z.string()
|
||||
.min(1, "색도를 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "색도는 숫자만 입력 가능합니다"),
|
||||
clIonQnt: z.number().nullish(),
|
||||
smll: z.string(),
|
||||
cdtnv: z.number().nullish(),
|
||||
crmty: z.number().nullish(),
|
||||
rmrk: z.string().optional(),
|
||||
/* telno: z.string()
|
||||
.min(8, "전화번호는 8자 이상 입력해주세요")
|
||||
.max(12, "전화번호는 12자 이내로 입력해주세요")
|
||||
.regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"), */
|
||||
candidateTitle: z.array(z.object({
|
||||
candidateTitle: z
|
||||
.array(
|
||||
z.object({
|
||||
ruseUtztnFcltNm: z.string(),
|
||||
ruseUtztnFcltCd: z.string(),
|
||||
})).optional(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type FormData = z.infer<typeof sdmInfoFormSchema>;
|
||||
@@ -80,55 +61,52 @@ function SdmInfoInsertContent() {
|
||||
const formSchema = sdmInfoFormSchema;
|
||||
|
||||
const [isLogin, setIsLogin] = useState(false);
|
||||
const [facilityName, setFacilityName] = useState<string>('');
|
||||
const [facilityName, setFacilityName] = useState<string>("");
|
||||
const [defaultValues, setDefaultValues] = useState<FormData>({
|
||||
sdmNm: '',
|
||||
sdmNm: "",
|
||||
demandYmd: new Date(),
|
||||
demandQnty: '',
|
||||
usePurpose: '',
|
||||
money: '',
|
||||
demandQnty: "",
|
||||
usePurpose: "",
|
||||
money: "",
|
||||
/**요구수질 */
|
||||
reqWaterQlty: '',
|
||||
grssClfg: '',
|
||||
tn: '',
|
||||
combResdch: '',
|
||||
tph: '',
|
||||
trbt: '',
|
||||
ph: '',
|
||||
bod: '',
|
||||
reqWaterQlty: "",
|
||||
grssClfg: null,
|
||||
tn: null,
|
||||
combResdch: null,
|
||||
tph: null,
|
||||
trbt: null,
|
||||
ph: null,
|
||||
bod: null,
|
||||
/**컬럼확인필요 */
|
||||
clIonQnt: '',
|
||||
smll: '',
|
||||
cdtnv: '',
|
||||
crmty: '',
|
||||
rmrk: '',
|
||||
clIonQnt: null,
|
||||
smll: "",
|
||||
cdtnv: null,
|
||||
crmty: null,
|
||||
rmrk: "",
|
||||
/** 후보지 제목 */
|
||||
candidateTitle: [
|
||||
{ ruseUtztnFcltNm: '', ruseUtztnFcltCd: '' },
|
||||
{ ruseUtztnFcltNm: '', ruseUtztnFcltCd: '' },
|
||||
{ ruseUtztnFcltNm: '', ruseUtztnFcltCd: '' },
|
||||
{ ruseUtztnFcltNm: "", ruseUtztnFcltCd: "" },
|
||||
{ ruseUtztnFcltNm: "", ruseUtztnFcltCd: "" },
|
||||
{ ruseUtztnFcltNm: "", ruseUtztnFcltCd: "" },
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const user = sessionStorage.getItem('user');
|
||||
setDefaultValues(prev => ({
|
||||
const user = sessionStorage.getItem("user");
|
||||
setDefaultValues((prev) => ({
|
||||
...prev,
|
||||
sdmNm: searchParams.get('dmdCoNm') || '',
|
||||
sdmNm: searchParams.get("dmdCoNm") || "",
|
||||
}));
|
||||
sessionStorage.setItem('user', searchParams.get('dmdInfoId') || '');
|
||||
setIsLogin(user || searchParams.get('dmdInfoId') ? true : false);
|
||||
sessionStorage.setItem("user", searchParams.get("dmdInfoId") || "");
|
||||
setIsLogin(user || searchParams.get("dmdInfoId") ? true : false);
|
||||
}, [searchParams]);
|
||||
|
||||
useEffect(() => {
|
||||
const local = localStorage.getItem('user');
|
||||
const local = localStorage.getItem("user");
|
||||
if (local) {
|
||||
setIsLogin(true);
|
||||
}
|
||||
setSubsInfo([]); // subsInfo 초기화 후보지 처음 화면 들어올때 초기화(스토어내 객체만)
|
||||
|
||||
}, [setSubsInfo]);
|
||||
|
||||
const form = useForm<FormData>({
|
||||
@@ -142,96 +120,135 @@ function SdmInfoInsertContent() {
|
||||
useEffect(() => {
|
||||
//map.subsInfo 스토어 객체 값이 변경되면 해당 값이 폼에 자동으로 들어가도록 수정 대신 값이 있어야함
|
||||
if (subsInfo.length > 0) {
|
||||
form.setValue('candidateTitle', subsInfo)
|
||||
form.setValue("candidateTitle", subsInfo);
|
||||
}
|
||||
|
||||
},[subsInfo, form])
|
||||
}, [subsInfo, form]);
|
||||
|
||||
//후보지 팝업 값 셋팅
|
||||
useEffect(() => {
|
||||
const handleMessage = (event: MessageEvent) => {
|
||||
if (event.data?.type === 'SET_SUBS_INFO') {
|
||||
if (event.data?.type === "SET_SUBS_INFO") {
|
||||
setSubsInfo(event.data.payload); // zustand로 값 설정
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleMessage);
|
||||
return () => window.removeEventListener('message', handleMessage);
|
||||
window.addEventListener("message", handleMessage);
|
||||
return () => window.removeEventListener("message", handleMessage);
|
||||
}, [setSubsInfo]);
|
||||
|
||||
// 로그인 성공 시 모달 닫기 및 폼 업데이트
|
||||
useEffect(() => {
|
||||
if (successLogin) {
|
||||
setIsLogin(true);
|
||||
const user = sessionStorage.getItem('user');
|
||||
const user = sessionStorage.getItem("user");
|
||||
if (user) {
|
||||
try {
|
||||
const userData = JSON.parse(user);
|
||||
if (userData.dmdCoNm) {
|
||||
setFacilityName(userData.dmdCoNm);
|
||||
form.setValue('sdmNm', userData.dmdCoNm);
|
||||
form.setValue("sdmNm", userData.dmdCoNm);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error parsing user data:', error);
|
||||
console.error("Error parsing user data:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [successLogin, form]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Form state changed:", form.formState.errors);
|
||||
}, [form.formState.errors]);
|
||||
|
||||
// 체크박스 상태가 변경될 때마다 money 필드의 에러를 초기화
|
||||
useEffect(() => {
|
||||
if (ismoneyDisabled) {
|
||||
form.clearErrors('money');
|
||||
form.setValue('money', '');
|
||||
form.clearErrors("money");
|
||||
form.setValue("money", "");
|
||||
}
|
||||
}, [ismoneyDisabled, form]);
|
||||
const router = useRouter();
|
||||
const onSubmit: SubmitHandler<FormData> = async (data) => {
|
||||
try {
|
||||
// Transform form data to match API schema
|
||||
const apiData: DemandCompType = {
|
||||
dmdInfoId: JSON.parse(sessionStorage.getItem('user') || '{}')?.dmdInfoId?.toString() || searchParams.get('dmdInfoId') + (searchParams.get('bznmTotNo') || ''),
|
||||
dmdInfoFk: JSON.parse(sessionStorage.getItem('user') || '{}')?.dmdInfoId?.toString() || searchParams.get('dmdInfoId') + (searchParams.get('bznmTotNo') || ''),
|
||||
dmdCoNm: JSON.parse(sessionStorage.getItem('user') || '{}')?.dmdCoNm?.toString() || data.sdmNm,
|
||||
ctpvCd: JSON.parse(sessionStorage.getItem('user') || '{}')?.ctpvCd?.toString() || searchParams.get('ctpvCd') || '',
|
||||
sggCd: JSON.parse(sessionStorage.getItem('user') || '{}')?.sggCd?.toString() || searchParams.get('sggCd') || '',
|
||||
daddr: JSON.parse(sessionStorage.getItem('user') || '{}')?.daddr?.toString() || searchParams.get('daddr') || '',
|
||||
telno: JSON.parse(sessionStorage.getItem('user') || '{}')?.telno?.toString() || searchParams.get('telno') || '',
|
||||
rgtr: JSON.parse(sessionStorage.getItem('user') || '{}')?.rgtr?.toString() || searchParams.get('rgtr') || '',
|
||||
useUsgCd: data.usePurpose || '',
|
||||
wntUntprc: Number(data.money) || '',
|
||||
const dmSubsInfo = data.candidateTitle?.filter(
|
||||
(item) => item.ruseUtztnFcltNm && item.ruseUtztnFcltCd
|
||||
);
|
||||
// Transform form data to madata.candidateTitletch API schema
|
||||
const apiData: DemandCompBizType = {
|
||||
dmdInfoId:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.dmdInfoId?.toString() ||
|
||||
searchParams.get("dmdInfoId") + (searchParams.get("bznmTotNo") || ""),
|
||||
dmdInfoFk:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.dmdInfoId?.toString() ||
|
||||
searchParams.get("dmdInfoId") + (searchParams.get("bznmTotNo") || ""),
|
||||
dmdCoNm:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.dmdCoNm?.toString() || data.sdmNm,
|
||||
ctpvCd:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.ctpvCd?.toString() ||
|
||||
searchParams.get("ctpvCd") ||
|
||||
"",
|
||||
sggCd:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.sggCd?.toString() ||
|
||||
searchParams.get("sggCd") ||
|
||||
"",
|
||||
daddr:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.daddr?.toString() ||
|
||||
searchParams.get("daddr") ||
|
||||
"",
|
||||
telno:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.telno?.toString() ||
|
||||
searchParams.get("telno") ||
|
||||
"",
|
||||
rgtr:
|
||||
JSON.parse(
|
||||
sessionStorage.getItem("user") || "{}"
|
||||
)?.rgtr?.toString() ||
|
||||
searchParams.get("rgtr") ||
|
||||
"",
|
||||
useUsgCd: data.usePurpose || "",
|
||||
wntUntprc: Number(data.money) || "",
|
||||
dmndTmng: data.demandYmd || new Date(),
|
||||
dmndQty: Number(data.demandQnty) || '',
|
||||
grssClfg: Number(data.grssClfg) || '',
|
||||
tn: Number(data.tn) || '',
|
||||
combResdch: Number(data.combResdch) || '',
|
||||
tph: Number(data.tph) || '',
|
||||
trbt: Number(data.trbt) || '',
|
||||
ph: Number(data.ph) || '',
|
||||
blgcOxygDmndQnt: Number(data.bod) || '',
|
||||
clIonQnt: Number(data.clIonQnt) || '',
|
||||
smll: Number(data.smll) || '',
|
||||
cdtnv: Number(data.cdtnv) || '',
|
||||
crmty: Number(data.crmty) || '',
|
||||
rmrk: data.rmrk || '',
|
||||
dmndQty: Number(data.demandQnty) || "",
|
||||
grssClfg: data.grssClfg === null ? -1 : Number(data.grssClfg),
|
||||
tn: Number(data.tn) || null,
|
||||
combResdch: Number(data.combResdch) || null,
|
||||
tph: Number(data.tph) || null,
|
||||
trbt: Number(data.trbt) || null,
|
||||
ph: data.ph || "",
|
||||
blgcOxygDmndQnt: Number(data.bod) ||null,
|
||||
clIonQnt: Number(data.clIonQnt) || null,
|
||||
smll: data.smll || "",
|
||||
cdtnv: Number(data.cdtnv) ||null,
|
||||
crmty: Number(data.crmty) || null,
|
||||
rmrk: data.rmrk || "",
|
||||
bzmnNo: "",
|
||||
dmdAplyPswd: "",
|
||||
index: 0,
|
||||
reqDt: "",
|
||||
dmdInfoSn: 0,
|
||||
status: '',
|
||||
splyCndtList: data.candidateTitle || [],
|
||||
status: "",
|
||||
splyCndtList: dmSubsInfo || [],
|
||||
};
|
||||
|
||||
|
||||
|
||||
await insertSdmInfoData(apiData);
|
||||
setTimeout(() => {
|
||||
router.push("/");
|
||||
}, 1000);
|
||||
}, 1000); // 0.8초 후 이동
|
||||
} catch (error) {
|
||||
console.error('Error submitting form:', error);
|
||||
console.error("Error submitting form:", error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -254,8 +271,10 @@ const router = useRouter();
|
||||
/>
|
||||
<div className="flex justify-center pt-4">
|
||||
<Button
|
||||
color="sky"
|
||||
size={"sm"}
|
||||
type="submit"
|
||||
className="w-40 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
|
||||
className="w-40 font-semibold py-2 px-4 rounded-md "
|
||||
>
|
||||
수요정보 등록
|
||||
</Button>
|
||||
@@ -265,7 +284,7 @@ const router = useRouter();
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!isLogin ?
|
||||
{!isLogin ? (
|
||||
<UiModal
|
||||
body={<SdmLogin />}
|
||||
bodyClass="sm:max-w-[90vw] w-[530px] h-[430px]"
|
||||
@@ -278,7 +297,7 @@ const router = useRouter();
|
||||
noHeaderYn="Y"
|
||||
noFooterYn="Y"
|
||||
/>
|
||||
: null}
|
||||
) : null}
|
||||
<Toaster position="top-center" />
|
||||
</div>
|
||||
);
|
||||
@@ -291,4 +310,3 @@ export default function MyForm() {
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useDmStore } from "@/app/store";
|
||||
import type { DemandCompType } from "@/app/store/sdmMng";
|
||||
import SdmInsertForm from '@common/business_components/ui/sdmInsertForm';
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
@@ -44,15 +44,9 @@ export default function MyForm() {
|
||||
const handleInsertSdmData = useCallback((data: import('@common/business_components/ui/sdmInsertForm/form').DemandCompType) => {
|
||||
const convertedData: DemandCompType = {
|
||||
...data,
|
||||
dmdInfoSn: '',
|
||||
dmdInfoFk: '',
|
||||
status: '',
|
||||
splyCndtList: []
|
||||
};
|
||||
formDataRef.current = convertedData;
|
||||
insertSdmData(convertedData).catch(error => {
|
||||
console.error('Error inserting SDM data:', error);
|
||||
});
|
||||
insertSdmData(convertedData)
|
||||
}, [insertSdmData]);
|
||||
|
||||
return (
|
||||
@@ -70,4 +64,3 @@ export default function MyForm() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,10 +62,9 @@ const Map = () => {
|
||||
Object.keys(item).length > 0 &&
|
||||
!prev.some((f) => f.pbnstRuseFcltId === item.pbnstRuseFcltId)
|
||||
);
|
||||
console.log(newItems)
|
||||
console.log(newItems);
|
||||
return [...prev, ...newItems];
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("데이터 불러오기 실패:", error);
|
||||
}
|
||||
@@ -232,14 +231,6 @@ const Map = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<SearchBar
|
||||
setHasuPk={(hasuPk: any) => {
|
||||
if (hasuPk) {
|
||||
setSelectDataPk(hasuPk);
|
||||
}
|
||||
}}
|
||||
onApply={onApply}
|
||||
/>
|
||||
<div className="bg-container">
|
||||
<Gis
|
||||
treeData={treeData}
|
||||
@@ -257,6 +248,17 @@ const Map = () => {
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={onCheckedLayersChange}
|
||||
imgVisble={false}
|
||||
searchBar={(props: any) => (
|
||||
<SearchBar
|
||||
setHasuPk={(hasuPk: any) => {
|
||||
if (hasuPk) {
|
||||
setSelectDataPk(hasuPk);
|
||||
}
|
||||
}}
|
||||
onApply={onApply}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<SelectedFcltList
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
import type { SelectDataType } from "@common/business_components/ui";
|
||||
import type { TableUpperProps } from "../common";
|
||||
import toast from "react-hot-toast";
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
|
||||
/**====================================
|
||||
* Store - 타입
|
||||
=====================================*/
|
||||
// 수요처 정보
|
||||
export type DemandCompType = {
|
||||
export type DemandCompBizType = {
|
||||
index : number | '';
|
||||
dmdInfoId : string | '';
|
||||
dmdInfoFk : string | '';
|
||||
@@ -23,22 +24,23 @@ export type DemandCompType = {
|
||||
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 | '';
|
||||
grssClfg : number | null //총대장균군수
|
||||
tn : number | null //총질소
|
||||
combResdch : number | null //결합잔류염소
|
||||
tph : number | null //총인
|
||||
trbt : number | null //탁도
|
||||
ph : string | ''; //수소이온농
|
||||
blgcOxygDmndQnt : number | null //생물학적산소요구량
|
||||
clIonQnt : number | null //염화물
|
||||
smll : string | ''; //냄새
|
||||
cdtnv : number | null; //전기전도도
|
||||
crmty : number | null //색도
|
||||
rmrk : string | '';
|
||||
reqDt : string | '';
|
||||
dmdInfoSn : number | '';
|
||||
status : string | '';
|
||||
splyCndtList:SupplyCandidate[]|[],
|
||||
ruseUtztnFcltNm?:string|''
|
||||
|
||||
}
|
||||
|
||||
@@ -152,7 +154,8 @@ export type MoneyDetailType = {
|
||||
clclnBrdnCst : string | '';
|
||||
clclnEcqrRt : string | '';
|
||||
}
|
||||
|
||||
// 규칙 타입 선언
|
||||
export type DisableRulesType = Record<string, string[]>;
|
||||
/**====================================
|
||||
* Store - 데이터
|
||||
====================================*/
|
||||
@@ -160,6 +163,131 @@ export type MoneyDetailType = {
|
||||
const demandCompList : DemandCompType[] = [
|
||||
]
|
||||
|
||||
|
||||
const disableRules: DisableRulesType = {
|
||||
"청소": ["tn", 'tph',"clIonQnt" ,'cdtnv'],
|
||||
"화장실용수": ["tn", 'tph',"clIonQnt" ,'cdtnv'],
|
||||
"세척": ["combResdch", "crmty",'tph',"clIonQnt",'cdtnv'],
|
||||
"살수": ["combResdch", "crmty",'tph',"clIonQnt",'cdtnv'],
|
||||
"조경": ["combResdch", "crmty",'tph','cdtnv'],
|
||||
"농업_간접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
|
||||
"농업_직접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
|
||||
"하천": ["combResdch", "trbt", "crmty" ,'clIonQnt','cdtnv'],
|
||||
'공업':[]
|
||||
};
|
||||
|
||||
const defaultRules: Record<string, object> = {
|
||||
"청소": {
|
||||
grssClfg: null,
|
||||
combResdch:0.2,
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
crmty: 20,
|
||||
ph: "5.8~8.5",
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
cdtnv: null,
|
||||
|
||||
},
|
||||
"화장실용수": {
|
||||
grssClfg: null,
|
||||
combResdch:0.2,
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
crmty: 20,
|
||||
ph: "5.8~8.5",
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
cdtnv: null,
|
||||
},
|
||||
"세척": {
|
||||
grssClfg: null,
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
ph: "5.8~8.5",
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
cdtnv: null,
|
||||
},
|
||||
"살수": {
|
||||
grssClfg: null,
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
ph: "5.8~8.5",
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
cdtnv: null,
|
||||
},
|
||||
"조경": {
|
||||
grssClfg: null,
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
ph: "5.8~8.5",
|
||||
clIonQnt:250,
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
tn:null,
|
||||
tph: null,
|
||||
cdtnv: null,
|
||||
},
|
||||
"농업_간접용수": {
|
||||
grssClfg: null,
|
||||
trbt: 5,
|
||||
bod: 8,
|
||||
ph: "5.8~8.5",
|
||||
cdtnv:2000,
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
},
|
||||
"농업_직접용수": {
|
||||
grssClfg: null,
|
||||
trbt: 2,
|
||||
bod: 8,
|
||||
ph: "5.8~8.5",
|
||||
cdtnv:700,
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
},
|
||||
"하천": {
|
||||
grssClfg: 1000,
|
||||
bod: 5,
|
||||
tn: 10,
|
||||
tph: 0.5,
|
||||
ph: "5.8~8.5",
|
||||
combResdch:null,
|
||||
trbt:null,
|
||||
crmty:null,
|
||||
clIonQnt: null,
|
||||
cdtnv:null
|
||||
},
|
||||
공업:{
|
||||
grssClfg: null,
|
||||
bod: null,
|
||||
tn: null,
|
||||
tph: null,
|
||||
ph: "~",
|
||||
combResdch:null,
|
||||
trbt:null,
|
||||
crmty:null,
|
||||
clIonQnt: null,
|
||||
cdtnv:null
|
||||
}
|
||||
};
|
||||
|
||||
// 사용용도
|
||||
const useTypesData : SelectDataType[] = [
|
||||
{ text: '청소', val: "청소" },
|
||||
@@ -167,7 +295,8 @@ const useTypesData : SelectDataType[] = [
|
||||
{ text: "세척", val: "세척" },
|
||||
{ text: "살수", val: "살수" },
|
||||
{ text: "조경", val: "조경" },
|
||||
{ text: "농업", val: "농업" },
|
||||
{ text: "농업_간접용수", val: "농업_간접용수" },
|
||||
{ text: "농업_직접용수", val: "농업_직접용수" },
|
||||
{ text: "하천", val: "하천" },
|
||||
{ text: "지하수", val: "지하수" },
|
||||
{ text: "공업", val: "공업" },
|
||||
@@ -280,7 +409,7 @@ const postSdmData = async (data: DemandCompType) => {
|
||||
}
|
||||
|
||||
// 수요정보 등록
|
||||
const postSdmInfoData = async (data: DemandCompType) => {
|
||||
const postSdmInfoData = async (data: DemandCompBizType) => {
|
||||
try {
|
||||
await postFetch("/reuseFc/request/demandInfo", data);
|
||||
toast.success('수요 정보 등록에 성공하였습니다.');
|
||||
@@ -360,7 +489,7 @@ const fetchGetSimilarCaseList = async (part: string, value: number|string) => {
|
||||
export type SdmActions = {
|
||||
initializeSdmData: () => void;
|
||||
insertSdmData: (data: DemandCompType) => Promise<void>;
|
||||
insertSdmInfoData: (data: DemandCompType) => Promise<void>;
|
||||
insertSdmInfoData: (data: DemandCompBizType) => Promise<void>;
|
||||
getDemandCompList: (searchText: string, pageCnt: number) => Promise<void>;
|
||||
actionLogin: (data: DemandCompType) => Promise<void>;
|
||||
getSdmInfoStatusList: (dmdInfoId: string) => Promise<void>;
|
||||
@@ -378,9 +507,10 @@ export type SdmType ={
|
||||
moneyDetailList: MoneyDetailType[];
|
||||
|
||||
// 수요정보 신청현황
|
||||
sdmInfoStatusList: DemandCompType[];
|
||||
sdmInfoStatusList: DemandCompBizType[];
|
||||
upHeadSdmInfoStatus: TableUpperProps[];
|
||||
|
||||
defaultRules: Record<string, object>
|
||||
disableRules: DisableRulesType;
|
||||
// 로그인관련
|
||||
successNextPage : boolean;
|
||||
successLogin: boolean;
|
||||
@@ -398,7 +528,10 @@ export const SdmState: SdmType = {
|
||||
moneyDetailList: moneyDetailList,
|
||||
// 수요정보 신청현황
|
||||
sdmInfoStatusList: [],
|
||||
defaultRules:defaultRules,
|
||||
disableRules:disableRules,
|
||||
upHeadSdmInfoStatus: upHeadSdmInfoStatus,
|
||||
|
||||
// 로그인관련
|
||||
successNextPage : false,
|
||||
successLogin: false,
|
||||
@@ -428,7 +561,7 @@ export const SdmReducer = (set: any): SdmActions => {
|
||||
}
|
||||
},
|
||||
|
||||
insertSdmInfoData: async (data: DemandCompType) => {
|
||||
insertSdmInfoData: async (data: DemandCompBizType) => {
|
||||
postSdmInfoData(data);
|
||||
},
|
||||
|
||||
@@ -465,11 +598,13 @@ export const SdmReducer = (set: any): SdmActions => {
|
||||
}))
|
||||
return;
|
||||
}
|
||||
const sdmInfoStatusList : DemandCompType[] = [];
|
||||
const sdmInfoStatusList : DemandCompBizType[] = [];
|
||||
|
||||
res.demandInfo.map((el: DemandCompType, index: number) => {
|
||||
res.demandInfo.map((el: DemandCompBizType, index: number) => {
|
||||
const matchingInfo = res.demandMatchings.find((matching: DemandMatchings) => matching.dmdInfoSn === el.dmdInfoSn);
|
||||
const status = matchingInfo?.splyFcltFlg?.trim() === 'Sub' ? '검토' : matchingInfo?.splyFcltFlg?.trim() === 'matched' ? '매칭완료' : '신청';
|
||||
const ruseUtztnFcltNm = matchingInfo?.ruseUtztnFcltNm ? matchingInfo.ruseUtztnFcltNm : '';
|
||||
|
||||
|
||||
const tmpData = {
|
||||
...el,
|
||||
@@ -485,7 +620,9 @@ export const SdmReducer = (set: any): SdmActions => {
|
||||
useUsgCd: el.useUsgCd,
|
||||
dmndTmng: el.dmndTmng,
|
||||
dmdInfoSn : el.dmdInfoSn,
|
||||
status : status
|
||||
status : status,
|
||||
splyCndtList: el.splyCndtList,
|
||||
ruseUtztnFcltNm: ruseUtztnFcltNm || ''
|
||||
}
|
||||
sdmInfoStatusList.push(tmpData);
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useDmStore } from '@/app/store';
|
||||
import type { DemandCompType } from '@/app/store/sdmMng';
|
||||
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
type thisProps = {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export const sanitizeInput = (val: string, allowDecimal = false) => {
|
||||
if (val === "") return ""; // 빈 값 허용
|
||||
|
||||
// 소숫점 허용
|
||||
if (allowDecimal) {
|
||||
// 숫자와 점만 허용
|
||||
let cleaned = val.replace(/[^0-9.]/g, "");
|
||||
// 소숫점 여러 개일 경우 첫 번째만 유지
|
||||
const parts = cleaned.split(".");
|
||||
if (parts.length > 2) {
|
||||
cleaned = parts[0] + "." + parts.slice(1).join("");
|
||||
}
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
// 정수만 허용
|
||||
return val.replace(/[^0-9]/g, "");
|
||||
};
|
||||
@@ -1,27 +1,29 @@
|
||||
import { FormUi } from "@common/business_components/ui";
|
||||
import type { ReactNode } from "react";
|
||||
import type { ControllerRenderProps, FieldError, FieldValues, Path } from "react-hook-form";
|
||||
|
||||
|
||||
import { cloneElement, isValidElement } from "react";
|
||||
interface AccessibleFormFieldProps<T extends FieldValues> {
|
||||
field: ControllerRenderProps<T, Path<T>>;
|
||||
label: string;
|
||||
required?: boolean;
|
||||
error?: FieldError;
|
||||
inputComponent: ReactNode;
|
||||
isDisabled?: boolean;
|
||||
inputComponent: React.ReactElement<{ disabled?: boolean }>;
|
||||
}
|
||||
|
||||
export function AccessibleFormField<T extends FieldValues>({
|
||||
label,
|
||||
required = false,
|
||||
inputComponent,
|
||||
isDisabled = false,
|
||||
}: AccessibleFormFieldProps<T>) {
|
||||
const labelText = required ? `${label} *` : label;
|
||||
|
||||
return (
|
||||
<FormUi label={labelText}>
|
||||
<FormUi label={labelText} isDisabled={isDisabled}>
|
||||
<div>
|
||||
{inputComponent}
|
||||
{isValidElement(inputComponent)
|
||||
? cloneElement(inputComponent, { disabled: isDisabled } as Partial<typeof inputComponent.props>)
|
||||
: inputComponent}
|
||||
{/* {error?.message && Array.from(new Set(error.message.split('\n'))).map((msg, idx) => (
|
||||
<p key={idx} className="text-red-500 text-sm mt-1" role="alert">
|
||||
{msg}
|
||||
|
||||
@@ -11,13 +11,20 @@ import {
|
||||
UiModal,
|
||||
} from "@common/business_components";
|
||||
import { Input } from "@common/components";
|
||||
import { Button } from "@common/components/ui";
|
||||
import { Button, Label } from "@common/components/ui";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { AccessibleFormField } from "./AccessibleFormField";
|
||||
import type { ControllerRenderProps, UseFormReturn, FieldError } from "react-hook-form";
|
||||
import {
|
||||
type ControllerRenderProps,
|
||||
type UseFormReturn,
|
||||
type FieldError,
|
||||
useWatch,
|
||||
} from "react-hook-form";
|
||||
import SearchInputText from "../common/searhDemandInput/component";
|
||||
import type { DemandCompType } from "@/app/store/sdmMng";
|
||||
import React from "react";
|
||||
import { sanitizeInput } from "../common/utils/utils";
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
|
||||
export interface SdmInfoRegFormProps {
|
||||
form: UseFormReturn<FormData>;
|
||||
@@ -35,12 +42,15 @@ export function SdmInfoRegForm({
|
||||
facilityName,
|
||||
}: SdmInfoRegFormProps) {
|
||||
const { initializeCommonData, Sdm } = useDmStore((state) => state);
|
||||
const { useTypesData } = Sdm;
|
||||
const { useTypesData, defaultRules, disableRules } = Sdm;
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const [sdmNmValue, setSdmNmValue] = useState<string>(
|
||||
searchParams.get("dmdCoNm") || ""
|
||||
);
|
||||
|
||||
const [frontPHdata, setFrontPHdata] = useState("0");
|
||||
const [backPHdata, setBackPHdata] = useState("0");
|
||||
const [isBznmTotNoDisabled, setIsBznmTotNoDisabled] = useState(false);
|
||||
const [isSimilarCase, setIsSimilarCase] = useState(false);
|
||||
const [key, setKey] = useState(0);
|
||||
@@ -58,6 +68,7 @@ export function SdmInfoRegForm({
|
||||
useEffect(() => {
|
||||
console.log("candidateTitle ", form.getValues("candidateTitle"));
|
||||
}, [form.getValues]);
|
||||
|
||||
useEffect(() => {
|
||||
if (useTypesData && useTypesData.length > 0) {
|
||||
setTimeout(() => {
|
||||
@@ -109,6 +120,54 @@ export function SdmInfoRegForm({
|
||||
onCheckboxChange?.(checked);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const watchPH = form.getValues(`ph`);
|
||||
if (watchPH && watchPH !== undefined) {
|
||||
const [frontPH, backPH] = watchPH.split("~");
|
||||
if (frontPH) {
|
||||
setFrontPHdata(frontPH);
|
||||
}
|
||||
if (backPH) {
|
||||
setBackPHdata(backPH);
|
||||
}
|
||||
} else {
|
||||
setFrontPHdata("0");
|
||||
setBackPHdata("0");
|
||||
}
|
||||
}, [form.getValues(`ph`)]);
|
||||
|
||||
const isSetPh = useCallback(
|
||||
(typePHdata: string, index: number) => {
|
||||
const PHdata = form.getValues("ph");
|
||||
const isPH = PHdata?.split("~")[index] || "";
|
||||
if (index == 0) {
|
||||
form.setValue("ph", `${isPH}~${typePHdata}`);
|
||||
setBackPHdata(typePHdata);
|
||||
} else if (index == 1) {
|
||||
form.setValue("ph", `${typePHdata}~${isPH}`);
|
||||
setFrontPHdata(typePHdata);
|
||||
}
|
||||
},
|
||||
[form]
|
||||
);
|
||||
|
||||
const usePurpose = useWatch({ control: form.control, name: "usePurpose" });
|
||||
|
||||
useEffect(() => {
|
||||
if (!usePurpose) return;
|
||||
|
||||
// Apply default values
|
||||
const defaults = defaultRules[usePurpose];
|
||||
|
||||
console.log("usePurpose", usePurpose);
|
||||
console.log("defaults", defaults);
|
||||
if (defaults) {
|
||||
Object.entries(defaults).forEach(([field, value]) => {
|
||||
form.setValue(field as keyof FormData, value, { shouldDirty: true });
|
||||
});
|
||||
}
|
||||
}, [form.getValues("usePurpose")]);
|
||||
|
||||
// 시설 선택시 이벤트
|
||||
const selectComp = useCallback(
|
||||
(rtnData: DemandCompType[]) => {
|
||||
@@ -178,7 +237,6 @@ export function SdmInfoRegForm({
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="요구수량(㎥/d)을 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
@@ -222,7 +280,6 @@ export function SdmInfoRegForm({
|
||||
isDisabled={isBznmTotNoDisabled}
|
||||
>
|
||||
<Input
|
||||
placeholder="희망단가(원/㎥)을 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
@@ -244,221 +301,7 @@ export function SdmInfoRegForm({
|
||||
required: true,
|
||||
component: undefined,
|
||||
},
|
||||
{
|
||||
name: "grssClfg",
|
||||
label: "총대장균군수(개/100ml)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="총대장균군수를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "tn",
|
||||
label: "총질소(T-N)(mg/L)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="총질소를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "combResdch",
|
||||
label: "결합잔류염소(mg/L)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="결합잔류염소를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "tph",
|
||||
label: "총인(T-P)(mg/L)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="총인을 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "trbt",
|
||||
label: "탁도(NTU)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="탁도를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "ph",
|
||||
label: "수소이온농도(pH)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="수소이온농도를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "bod",
|
||||
label: "생물학적 산소요구량(BOD)(mg/L)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="생물학적 산소요구량을 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "clIonQnt",
|
||||
label: "염화물(mgCL/L)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="염화물을 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "smll",
|
||||
label: "냄새",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="냄새를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "cdtnv",
|
||||
label: "전기전도도(㎲/cm)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="전기전도도를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "crmty",
|
||||
label: "색도(도)",
|
||||
formIndex: 1,
|
||||
required: true,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="색도를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "rmrk",
|
||||
label: "비고",
|
||||
formIndex: 1,
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="비고를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
value={field.value as string}
|
||||
onChange={field.onChange}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
),
|
||||
},
|
||||
|
||||
{
|
||||
name: "candidateTitle",
|
||||
label: CANDIDATE || "공급처 후보지 선택(필수아님)",
|
||||
@@ -466,10 +309,20 @@ export function SdmInfoRegForm({
|
||||
component: () => (
|
||||
<div>
|
||||
<div className="-mt-14 float-right flex gap-10">
|
||||
<Button className={"bg-gray-200"} onClick={searchCandidate}>
|
||||
<Button
|
||||
className="rounded-md"
|
||||
color="sky"
|
||||
size={"sm"}
|
||||
onClick={searchCandidate}
|
||||
>
|
||||
후보지 조회
|
||||
</Button>
|
||||
<Button className={"bg-gray-200"} onClick={searchSimilarCase}>
|
||||
<Button
|
||||
className="rounded-md"
|
||||
color="sky"
|
||||
size={"sm"}
|
||||
onClick={searchSimilarCase}
|
||||
>
|
||||
유사사례
|
||||
</Button>
|
||||
</div>
|
||||
@@ -495,9 +348,9 @@ export function SdmInfoRegForm({
|
||||
const normalFields = formFields.filter(
|
||||
(f) => f.formIndex === 0 && f.component
|
||||
);
|
||||
const groupFields = formFields.filter(
|
||||
(f) => f.formIndex === 1 && f.component
|
||||
);
|
||||
// const groupFields = formFields.filter(
|
||||
// (f) => f.formIndex === 1 && f.component
|
||||
// );
|
||||
const candidateFields = formFields.filter(
|
||||
(f) => f.formIndex === 2 && f.component
|
||||
);
|
||||
@@ -512,17 +365,15 @@ export function SdmInfoRegForm({
|
||||
name={name}
|
||||
render={({ field }) =>
|
||||
name === "money" ? (
|
||||
component(field)
|
||||
// component(field)
|
||||
<FormUi label={label + "*"}>{component(field)}</FormUi>
|
||||
) : (
|
||||
// <FormUi label={label}>
|
||||
// {component(field)}
|
||||
// </FormUi>
|
||||
<AccessibleFormField
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
error={
|
||||
typeof form.formState.errors[name]?.message === 'string'
|
||||
typeof form.formState.errors[name]?.message === "string"
|
||||
? (form.formState.errors[name] as FieldError)
|
||||
: undefined
|
||||
}
|
||||
@@ -534,37 +385,527 @@ export function SdmInfoRegForm({
|
||||
) : null
|
||||
)}
|
||||
|
||||
{groupFields.length > 0 && (
|
||||
<div className="mt-10">
|
||||
<FormLabel className="text-xl">요구수질</FormLabel>
|
||||
<div className="flex flex-wrap justify-start gap-10 mt-3 mb-3">
|
||||
{groupFields.map(({ name, label, component, required }) => (
|
||||
<div key={name} className="min-w-[180px]">
|
||||
<div className="grid grid-cols-2 gap-x-10 gap-y-6 mt-3 mb-3">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
// <FormUi label={label}>
|
||||
// {component?.(field)}
|
||||
// </FormUi>
|
||||
<AccessibleFormField
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
error={
|
||||
typeof form.formState.errors[name]?.message === 'string'
|
||||
? (form.formState.errors[name] as FieldError)
|
||||
: undefined
|
||||
name={`grssClfg`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={
|
||||
!isDisabled ? `총대장균군수(개/mg)*` : "총대장균군수(개/mg)"
|
||||
}
|
||||
inputComponent={component?.(field)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: "불검출"
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
{/* TODO: 총대장균군수 확인 필요*/}
|
||||
{field.value !== null ? (
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`tn`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={
|
||||
!isDisabled ? `총질소(T-N)(mg/L)*` : "총질소(T-N)(mg/L)"
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`combResdch`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={
|
||||
!isDisabled ? `결합잔류염소(mg/L)*` : "결합잔류염소(mg/L)"
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const cleanValue = sanitizeInput(
|
||||
e.target.value,
|
||||
true
|
||||
);
|
||||
field.onChange(
|
||||
cleanValue === "" ? null : Number(cleanValue)
|
||||
);
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이상
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`tph`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={!isDisabled ? `총인(T-P)(mg/L)*` : "총인(T-P)(mg/L)"}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const cleanValue = sanitizeInput(
|
||||
e.target.value,
|
||||
true
|
||||
);
|
||||
field.onChange(
|
||||
cleanValue === "" ? null : Number(cleanValue)
|
||||
);
|
||||
}}
|
||||
value={field.value ?? ""}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`trbt`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi label={!isDisabled ? `탁도(NTU)*` : "탁도(NTU)"}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<div className="col-span-1">
|
||||
<Label className="text-xl">수소이온농도(PH)</Label>
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<Input
|
||||
className="!text-xl w-36"
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
const cleanValue = sanitizeInput(e.target.value, true);
|
||||
isSetPh(cleanValue, 1);
|
||||
}}
|
||||
value={frontPHdata ?? ""}
|
||||
maxLength={5}
|
||||
/>
|
||||
<span className="text-xl mx-2">~</span>
|
||||
<Input
|
||||
className="!text-xl w-36 "
|
||||
placeholder=""
|
||||
type="text"
|
||||
onChange={(e) => {
|
||||
const cleanValue = sanitizeInput(e.target.value, true);
|
||||
isSetPh(cleanValue, 0);
|
||||
}}
|
||||
value={backPHdata ?? ""}
|
||||
maxLength={5}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`bod`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={
|
||||
!isDisabled
|
||||
? `생물학적 산소요구량(BOD)(mg/L)*`
|
||||
: "생물학적 산소요구량(BOD)(mg/L)"
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`clIonQnt`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={!isDisabled ? `염화물(mgCL/L)*` : "염화물(mgCL/L)"}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`smll`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi label={!isDisabled ? `냄새*` : "냄새"}>
|
||||
<SelectBox
|
||||
className="!text-2xl rounded-md"
|
||||
label={""}
|
||||
selectClass={undefined}
|
||||
selectArray={[
|
||||
{ text: "불쾌하지않을것", val: "불쾌하지않을것" },
|
||||
{ text: "해당사항없음", val: "해당사항없음" },
|
||||
]}
|
||||
onSelectValue={(val: string | number) => {
|
||||
field.onChange(val.toString());
|
||||
}}
|
||||
value={field.value || "불쾌하지않을것"}
|
||||
readOnly={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
ref={field.ref}
|
||||
/>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`cdtnv`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi
|
||||
label={
|
||||
!isDisabled ? `전기전도도(㎲/cm)*` : "전기전도도(㎲/cm)"
|
||||
}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`crmty`}
|
||||
render={({ field }) => {
|
||||
const disabledFields = usePurpose ? disableRules[usePurpose] : [];
|
||||
const isDisabled = disabledFields
|
||||
? disabledFields.includes(field.name)
|
||||
: true;
|
||||
return (
|
||||
<FormUi label={!isDisabled ? `색도(도)*` : "색도(도)"}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
const inputValue = e.target.value.replace(
|
||||
/[^0-9]/g,
|
||||
""
|
||||
); // 정수만
|
||||
field.onChange(
|
||||
inputValue === "" ? null : Number(inputValue)
|
||||
);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== null
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
maxLength={6}
|
||||
disabled={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
|
||||
이하
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`rmrk`}
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormUi label={"비고"}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1 min-w-0">
|
||||
<Input
|
||||
type="text"
|
||||
className="w-full pr-16 border py-2 text-right rounded-md"
|
||||
placeholder=""
|
||||
onChange={(e) => {
|
||||
field.onChange(e.target.value);
|
||||
}}
|
||||
value={
|
||||
field.value !== undefined && field.value !== ""
|
||||
? `${field.value}`
|
||||
: ""
|
||||
}
|
||||
onBlur={field.onBlur}
|
||||
name={field.name}
|
||||
ref={field.ref}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</FormUi>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{candidateFields.map(({ name, label, component, required }, index) =>
|
||||
component ? (
|
||||
@@ -581,7 +922,7 @@ export function SdmInfoRegForm({
|
||||
label={label}
|
||||
required={required}
|
||||
error={
|
||||
typeof form.formState.errors[name]?.message === 'string'
|
||||
typeof form.formState.errors[name]?.message === "string"
|
||||
? (form.formState.errors[name] as FieldError)
|
||||
: undefined
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useDmStore } from "@/app/store";
|
||||
import type { DemandCompType } from "@/app/store/sdmMng";
|
||||
import { BZNM_TOT_NO, FormField, FormUi } from "@common/business_components";
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
import { Button, Input } from "@common/components";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { sha512 } from 'js-sha512';
|
||||
|
||||
@@ -16,7 +16,6 @@ export class LoginApiService implements LoginService {
|
||||
|
||||
public async login(payload: ILogin): Promise<void> {
|
||||
try {
|
||||
console.log(' ENDPOINT.USER_SERVICE.LOGIN ', ENDPOINT.USER_SERVICE.LOGIN)
|
||||
const response = await fetch( PROXY_HOST+ ENDPOINT.USER_SERVICE.LOGIN, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
|
||||
@@ -169,10 +169,9 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
|
||||
} else if (index === 8) {
|
||||
el['item'] = (Number(searchYear)-0).toString();
|
||||
el['provisionalApproval'] = waterUsage1;
|
||||
} else if(index === 4){
|
||||
el['provisionalApproval'] = Math.round((Number(waterUsage1)+Number(waterUsage2)+Number(waterUsage3))/3 * 100)/100;
|
||||
}
|
||||
});
|
||||
console.log('planFcltyList :', planFcltyList);
|
||||
}
|
||||
}, [waterUsage1, waterUsage2, waterUsage3, searchYear, planFcltyList]);
|
||||
// 연도가 바뀌면 hasSearched를 false로 리셋
|
||||
@@ -226,8 +225,8 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
|
||||
:(index < 5 || index > 5)&& (index!= 4) && (head.id ==='provisionalApproval'||head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour')
|
||||
?<TableCell className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
|
||||
:(head.id === "provisionalApproval" && index === 4)
|
||||
?<TableCell colSpan={6} className="text-right border border-[var(--border)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
|
||||
:((head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour') && index === 4)
|
||||
?<TableCell colSpan={6} className="text-right border border-[var(--border)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{Math.round((Number(waterUsage1)+Number(waterUsage2)+Number(waterUsage3))/3 * 100)/100}</TableCell>
|
||||
:((head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour') )
|
||||
?null
|
||||
:(head.id === 'item' && index != 5)?
|
||||
<TableCell className="text-center text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
|
||||
|
||||
@@ -13,7 +13,11 @@ interface FeatureData {
|
||||
}
|
||||
|
||||
interface MapInstance {
|
||||
getLayers: () => { getArray: () => Array<{ getSource?: () => { getFeatureById?: (id: string) => FeatureData | null } }> };
|
||||
getLayers: () => {
|
||||
getArray: () => Array<{
|
||||
getSource?: () => { getFeatureById?: (id: string) => FeatureData | null };
|
||||
}>;
|
||||
};
|
||||
getView: () => { fit: (extent: number[], options: object) => void };
|
||||
}
|
||||
|
||||
@@ -26,13 +30,13 @@ const Map = () => {
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}/v1/map`
|
||||
const API_URL = `${process.env.NEXT_PUBLIC_SEWERAGE_API_URL}/v1/map`;
|
||||
const reqUrl = `${API_URL}/lyrStngs/FO_NETWORK`;
|
||||
const response = await fetch(reqUrl, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -60,7 +64,12 @@ const Map = () => {
|
||||
}
|
||||
|
||||
// 항상 같은 select 객체 사용
|
||||
const select = (GisApp.Module.select as unknown) as { resetSelectedFeature: () => void; selectFeature: (feature: FeatureData, selected: boolean) => void } | undefined;
|
||||
const select = GisApp.Module.select as unknown as
|
||||
| {
|
||||
resetSelectedFeature: () => void;
|
||||
selectFeature: (feature: FeatureData, selected: boolean) => void;
|
||||
}
|
||||
| undefined;
|
||||
if (!select) return;
|
||||
|
||||
// 1. 기존 선택 초기화
|
||||
@@ -115,9 +124,12 @@ const Map = () => {
|
||||
};
|
||||
|
||||
// onCheckedLayersChange handler
|
||||
const handleCheckedLayersChange = (checkedIds: string[], checkedNodesData: unknown[]) => {
|
||||
const handleCheckedLayersChange = (
|
||||
checkedIds: string[],
|
||||
checkedNodesData: unknown[]
|
||||
) => {
|
||||
// Handle checked layers change if needed
|
||||
console.log('Checked layers changed:', checkedIds, checkedNodesData);
|
||||
console.log("Checked layers changed:", checkedIds, checkedNodesData);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -137,6 +149,8 @@ const Map = () => {
|
||||
isOpen={isOpen}
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={handleCheckedLayersChange}
|
||||
imgVisble={false}
|
||||
searchBar={undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1232,9 +1232,9 @@ export const dashBoardReducer:(set:(fn: (state: DashBoardType) => DashBoardType)
|
||||
}
|
||||
|
||||
if(operationalStatusList[0] && operationalStatusList[7]){
|
||||
operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : data.yearData.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg) / Number(data.yearData.AVG_INFL_AMNT) * 100) * 10) / 10+'%';
|
||||
operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : data.summer.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer) / Number(data.summer.AVG_INFL_AMNT) * 100) * 10) / 10+'%';
|
||||
operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : data.winter.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter) / Number(data.winter.AVG_INFL_AMNT) * 100) * 10) / 10+'%';
|
||||
operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : data.yearData && data.yearData.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterAvg) / (data.yearData && data.yearData.AVG_INFL_AMNT ? Number(data.yearData.AVG_INFL_AMNT) : 0) * 100) * 10) / 10+'%';
|
||||
operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : data.summer && data.summer.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterSummer) / (data.summer && data.summer.AVG_INFL_AMNT ? Number(data.summer.AVG_INFL_AMNT) : 0) * 100) * 10) / 10+'%';
|
||||
operationalStatusList[7].groundWaterWinter = operationalStatusList[0].groundWaterWinter === null ? '' : data.winter && data.winter.AVG_INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].groundWaterWinter) / (data.winter && data.winter.AVG_INFL_AMNT ? Number(data.winter.AVG_INFL_AMNT) : 0) * 100) * 10) / 10+'%';
|
||||
operationalStatusList[7].rdi = operationalStatusList[0].rdi === null ? '' : data.summerBod && data.summerBod.INFL_AMNT === 0 ? '' : Math.round((Number(operationalStatusList[0].rdi) / (data.summerBod&&data.summerBod.INFL_AMNT&&data.summerBod.INFL_AMNT!='null'?Number(data.summerBod.INFL_AMNT):0) * 100) * 10) / 10+'%';
|
||||
/* operationalStatusList[7].groundWaterAvg = operationalStatusList[0].groundWaterAvg === null ? '' : Number(Number(operationalStatusList[0].groundWaterAvg) / Number(data.yearData.AVG_INFL_AMNT)) * 100;
|
||||
operationalStatusList[7].groundWaterSummer = operationalStatusList[0].groundWaterSummer === null ? '' : Number(Number(operationalStatusList[0].groundWaterSummer) / Number(data.summer.AVG_INFL_AMNT)) * 100;
|
||||
|
||||
@@ -446,7 +446,6 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
|
||||
let maxWaterUsage = 0;
|
||||
let minWaterUsage = 9999999999;
|
||||
let avgWaterUsage = 0;
|
||||
console.log('monthData : ', monthData);
|
||||
monthData.forEach((item, index) => {
|
||||
item.usege = item.sum/item.cnt
|
||||
tableData.push({
|
||||
@@ -465,8 +464,6 @@ export const underWaterReducer:(set:(fn: (state: UnderWaterType) => UnderWaterTy
|
||||
|
||||
});
|
||||
avgWaterUsage = tot/cnt
|
||||
console.log('avgWaterUsage : ', avgWaterUsage);
|
||||
console.log('tableData : ', tableData);
|
||||
const newData= [
|
||||
{
|
||||
msrDt: '평균',
|
||||
|
||||
@@ -17,8 +17,6 @@ export class LoginApiService implements LoginService {
|
||||
|
||||
public async login(payload: ILogin): Promise<void> {
|
||||
try {
|
||||
console.log(' ENDPOINT.USER_SERVICE.LOGIN ', ENDPOINT.USER_SERVICE.LOGIN)
|
||||
console.log(payload.userId+' '+payload.password)
|
||||
const response = await fetch( PROXY_HOST+ ENDPOINT.USER_SERVICE.LOGIN, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
|
||||
@@ -2,7 +2,8 @@ export const SITE_ID = process.env.NEXT_PUBLIC_SITE_ID || "FO";
|
||||
export const PORT = process.env.NEXT_PUBLIC_PORT || "3000";
|
||||
export const PROXY_HOST = process.env.NEXT_PUBLIC_PROXY_HOST || `http://localhost:${PORT}`;
|
||||
export const SERVER_API_WR_URL = process.env.NEXT_PUBLIC_WR_SERVER_API_URL ||'http://con.mind-one.co.kr:11080/api/v1';
|
||||
export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL||' http://con.mind-one.co.kr:11082/api/v1';
|
||||
//export const SERVER_API_URL = process.env.NEXT_PUBLIC_SERVER_API_URL||' http://con.mind-one.co.kr:11082/api/v1';
|
||||
export const SERVER_API_URL = process.env.NEXT_PUBLIC_CS_SERVER_API_URL||' http://con.mind-one.co.kr:11082/api/v1';
|
||||
export const SERVER_API_CS_URL = process.env.NEXT_PUBLIC_CS_SERVER_API_URL||'http://dev.onasys.co.kr:8000';
|
||||
export const CLAIM_NAME = process.env.NEXT_PUBLIC_CLAIM_NAME || "Authorization";
|
||||
export const ACCESS_TOKEN = process.env.NEXT_PUBLIC_ACCESS_TOKEN || "access-token";
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
import SearchModal from "./searchModal/searchModal";
|
||||
import FeatureClickEventPopup from "./components/popupComponent/featureClickEventPopup";
|
||||
import { SearchBar } from "./searchBar/searchBar";
|
||||
|
||||
// 타입 정의 추가
|
||||
export type LyrStngProps = {
|
||||
@@ -132,6 +133,7 @@ const Map = () => {
|
||||
isOpen={isOpen}
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={undefined}
|
||||
searchBar={SearchBar}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
"use client";
|
||||
import {
|
||||
SearchDiv,
|
||||
SearchFormLeft,
|
||||
SelectBox,
|
||||
type SelectDataType,
|
||||
} from "@common/business_components/ui";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export function SearchBar() {
|
||||
const [sidoValue, setSidoValue] = useState<string>("");
|
||||
const [sigunValue, setSigunValue] = useState<string>("");
|
||||
const [filteredSigunData, setFilteredSigunData] = useState<SelectDataType[]>([
|
||||
{ text: "시도 선택", val: "0" },
|
||||
]);
|
||||
|
||||
const initializeSigunData = useCallback((sidoCd: string) => {
|
||||
if (sidoCd === "0") {
|
||||
setSigunValue("0");
|
||||
setFilteredSigunData([{ text: "시도 선택", val: "0" }]);
|
||||
} else {
|
||||
const newFilteredData = [
|
||||
{ text: "데이터", val: "0" },
|
||||
// ...Common.selectSigunData.filter(
|
||||
// (item: SelectDataType) => item.val.substring(0, 2) === sidoCd,
|
||||
// ),
|
||||
];
|
||||
setSigunValue("0");
|
||||
setFilteredSigunData(newFilteredData);
|
||||
}
|
||||
}, []);
|
||||
const onSelectValue = useCallback(
|
||||
(val: string, type: string) => {
|
||||
switch (type) {
|
||||
case "ctpvCd":
|
||||
initializeSigunData(val);
|
||||
setSidoValue(val);
|
||||
break;
|
||||
case "sggCd":
|
||||
setSigunValue(val);
|
||||
}
|
||||
},
|
||||
[initializeSigunData],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="col-span-4">
|
||||
<div className="card card-border flex">
|
||||
<div className="col-span-10 flex flex-row">
|
||||
<SelectBox
|
||||
className="mr-10 w-[200px]"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="시도"
|
||||
selectArray={/* Common.selectSidoData || */ []}
|
||||
onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")}
|
||||
value={sidoValue || /* Common.selectSidoData[0]?.val || */ ""}
|
||||
/>
|
||||
<SelectBox
|
||||
className="mr-10 w-[200px]"
|
||||
selectClass="rounded-lg bg-white"
|
||||
label="시군구"
|
||||
selectArray={filteredSigunData || []}
|
||||
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
|
||||
value={sigunValue}
|
||||
/>
|
||||
<SelectBox
|
||||
className="mr-3 w-[250px]"
|
||||
selectClass="rounded-lg bg-white"
|
||||
labelClass="w-[200px]"
|
||||
label="하수처리시설명"
|
||||
selectArray={filteredSigunData || []}
|
||||
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
|
||||
value={sigunValue}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -61,13 +61,16 @@ const Map = () => {
|
||||
|
||||
// 2. data가 OpenLayers Feature 인스턴스인지 확인
|
||||
let foundFeature: any = null;
|
||||
console.log(data)
|
||||
//console.log(data.getId())
|
||||
let featureId = data.fid;
|
||||
const layerName = data.layerNm;
|
||||
if (layerName === "tb_wr_bdst_ruse_fclt") {
|
||||
|
||||
if (layerName === "재이용시설") {
|
||||
// 재이용시설
|
||||
featureId = `${layerName}.${data.searchPk}`;
|
||||
} else if ( //빗물이용시설, 중수도시설
|
||||
layerName === "tb_wr_rnwtr_utztn_fclt" ||
|
||||
layerName === "빗물이용시설" ||
|
||||
layerName == "tb_wr_rswtr_fclt"
|
||||
) {
|
||||
featureId = `${layerName}.${data.bdstInfoSn}`;
|
||||
@@ -136,16 +139,6 @@ const Map = () => {
|
||||
gisMaps={gisMaps}
|
||||
isMiniMap={false}
|
||||
searchView={undefined}
|
||||
// searchView={(props: any) => (
|
||||
// <MapSearchBar
|
||||
// searchType="공급처 후보지 조회"
|
||||
// showApplyButton={false}
|
||||
// checkedLayers={checkedLayers}
|
||||
// checkedLayersData={checkedLayersData}
|
||||
// {...props}
|
||||
// />
|
||||
// )
|
||||
// }
|
||||
detailView={(props: any) => (
|
||||
<NewWindowPopup
|
||||
onClose={handlePopupClose} // 메모이제이션된 함수 사용
|
||||
@@ -163,6 +156,7 @@ const Map = () => {
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={handleCheckedLayersChange}
|
||||
imgVisble={true}
|
||||
searchBar={undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -116,6 +116,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
|
||||
const [mngList, setMngList] = useState<DemandCompType[]>(coSttnRes || []);
|
||||
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
|
||||
const getSelectedLayers = () => {
|
||||
console.log(1)
|
||||
let result = null;
|
||||
const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
|
||||
let featureLayer: { get: (key: string) => any } = { get: () => null };
|
||||
@@ -127,6 +128,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
|
||||
}
|
||||
});
|
||||
result = featureLayer.get('lyrNm');
|
||||
console.log(result)
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -156,15 +158,15 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
|
||||
}
|
||||
};
|
||||
const detainSttn = async (featureCd: string, layerNm: string) => {
|
||||
if (layerNm == 'tb_wr_rnwtr_utztn_fclt') { //빗물이용시설
|
||||
if (layerNm == '빗물이용시설') { //빗물이용시설
|
||||
const res = await getFetch(fetchType.WR, `/reuseFc/rainyInfoList/1/20/0/${featureCd}`)
|
||||
setRainList(res)
|
||||
}
|
||||
else if (layerNm == 'tb_wr_rswtr_fclt') { //중수도 시설
|
||||
else if (layerNm == '중수도시설') { //중수도 시설
|
||||
const res = await getFetch(fetchType.WR, `/reuseFc/waterreuseFc/1/20/0/${featureCd}`)
|
||||
setRswtrList(res)
|
||||
}
|
||||
else if(layerNm =='tb_wr_ruse_fclt_dmd_co'){ //수요처
|
||||
else if(layerNm =='수요처'){ //수요처
|
||||
const res = await getFetch(fetchType.WR, `/reuseFc/request/1/20/0/${featureCd}`)
|
||||
setMngList(res)
|
||||
}
|
||||
@@ -192,6 +194,7 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
|
||||
},[mngList])
|
||||
|
||||
const layerId = getSelectedLayers();
|
||||
console.log(layerId)
|
||||
if (featureData && typeof featureData.getProperties === "function") {
|
||||
const selectedVal = featureData.getProperties();
|
||||
let featureCd = layerId == '하수재이용시설' ? selectedVal?.swtrmt_fclt_cd : layerId == '빗물이용시설' || layerId == '중수도시설' || layerId == '온배수시설' || layerId == '수요처' ? selectedVal?.bdst_nm : layerId == '하수처리시설' ? selectedVal?.swtrmt_fclt_nm : null;
|
||||
@@ -505,17 +508,17 @@ const NewWindowPopup: React.FC<NewWindowPopupProps> = ({
|
||||
layerId = seletectedLayerNm || '';
|
||||
}
|
||||
//하수처리시설
|
||||
const isPrcsFclt = layerId == 'tb_il_swage_prcs_fclt'
|
||||
const isPrcsFclt = layerId == '하수처리시설'
|
||||
// 재이용시설
|
||||
const isPbnst = layerId == 'tb_wr_bdst_ruse_fclt';
|
||||
const isPbnst = layerId == '재이용시설';
|
||||
// 빗물이용시설
|
||||
const isRain = layerId == 'tb_wr_rnwtr_utztn_fclt';
|
||||
const isRain = layerId == '빗물이용시설';
|
||||
// 중수도시설
|
||||
const isRswt = layerId == 'tb_wr_rswtr_fclt';
|
||||
const isRswt = layerId == '중수도시설';
|
||||
// 온배수시설
|
||||
const isHtdfl = layerId == 'tb_wr_htdfl_fclt';
|
||||
const isHtdfl = layerId == '온배수시설';
|
||||
// 수요처관리
|
||||
const isReuseMng = layerId == 'tb_wr_ruse_fclt_dmd_co';
|
||||
const isReuseMng = layerId == '수요처관리';
|
||||
if (isPrcsFclt) {
|
||||
if (viewMode == 'list') {
|
||||
return (
|
||||
|
||||
@@ -123,16 +123,6 @@ const Map = () => {
|
||||
gisMaps={gisMaps}
|
||||
isMiniMap={false}
|
||||
searchView={undefined}
|
||||
// searchView={(props: any) => (
|
||||
// <MapSearchBar
|
||||
// searchType="공급처 후보지 조회"
|
||||
// showApplyButton={false}
|
||||
// checkedLayers={checkedLayers}
|
||||
// checkedLayersData={checkedLayersData}
|
||||
// {...props}
|
||||
// />
|
||||
// )
|
||||
// }
|
||||
detailView={(props: any) =>(
|
||||
<NewWindowPopup
|
||||
onClose={handlePopupClose} // 메모이제이션된 함수 사용
|
||||
@@ -150,6 +140,7 @@ const Map = () => {
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={handleCheckedLayersChange}
|
||||
imgVisble={true}
|
||||
searchBar={undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function PublicReuseFaciltyInsert() {
|
||||
// defaultValues: { items: pbnstRegArrayZod.parse([]) },
|
||||
mode: "onChange",
|
||||
});
|
||||
const { isDirty } = form.formState;
|
||||
// const { isDirty } = form.formState;
|
||||
|
||||
const {
|
||||
fields: items,
|
||||
@@ -90,10 +90,10 @@ export default function PublicReuseFaciltyInsert() {
|
||||
}, [pbnst.isInit, pubHasuInit]);
|
||||
|
||||
const onSubmit = async (valuse: { items: PbnstRegArrrayType }) => {
|
||||
if (!isDirty) {
|
||||
toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시
|
||||
return;
|
||||
}
|
||||
// if (!isDirty) {
|
||||
// toast.error("변경사항이 없습니다."); // 변경사항이 없으면 메시지 표시
|
||||
// return;
|
||||
// }
|
||||
const data = writeRgtrAndMdfr(valuse.items);
|
||||
let bizs = [] as fcBizType[];
|
||||
data.forEach((fclt) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { prfRegPageSize } from "@/app/store/prfmncReg/pbnstPrfmncReg";
|
||||
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
|
||||
import { excelDownload, yearOptions } from "@/components/lib/func/commom";
|
||||
@@ -33,6 +34,8 @@ export default function PbnstSttn() {
|
||||
} = useWrStore((state) => state);
|
||||
|
||||
const { pbnstSttnRes, fclts, pbnstSttnResCount } = pbnstSttn;
|
||||
|
||||
const [isReset, setIsReset] = useState(false);
|
||||
const ref = useRef<ReturnType>({} as ReturnType);
|
||||
const [searchYear, setSearchYear] = useState<string>(
|
||||
String(new Date().getFullYear())
|
||||
@@ -67,6 +70,24 @@ export default function PbnstSttn() {
|
||||
},
|
||||
[getPbnStnDetail, pbnstSttnRes]
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!pbnstSttn.isInit) {
|
||||
getFlcts();
|
||||
}
|
||||
}, [pbnstSttn.isInit]);
|
||||
useEffect(() => {
|
||||
|
||||
pbnSttnInit("1", "15", ref.current, searchYear, fclts);
|
||||
}, [fclts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (pbnstSttnRes && pbnstSttnRes.length > 0) {
|
||||
setBdstTable(pbnstSttnRes);
|
||||
} else {
|
||||
setBdstTable([]);
|
||||
}
|
||||
}, [pbnstSttnRes]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (pbnstSttn.excelList.length >= 0) {
|
||||
@@ -79,23 +100,7 @@ export default function PbnstSttn() {
|
||||
);
|
||||
}
|
||||
}, [pbnstSttn.excelList]);
|
||||
useEffect(() => {
|
||||
|
||||
if (!pbnstSttn.isInit) {
|
||||
getFlcts();
|
||||
}
|
||||
}, [pbnstSttn.isInit, pbnSttnInit, ref.current]);
|
||||
useEffect(() => {
|
||||
if (pbnstSttnRes && pbnstSttnRes.length > 0) {
|
||||
setBdstTable(pbnstSttnRes);
|
||||
} else {
|
||||
setBdstTable([]);
|
||||
}
|
||||
}, [pbnstSttnRes]);
|
||||
|
||||
useEffect(() => {
|
||||
pbnSttnInit("1", "15", ref.current, searchYear, fclts);
|
||||
}, [fclts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (pbnstSttn.pbnstDetail.pbnstRuseFcltId)
|
||||
@@ -157,16 +162,11 @@ export default function PbnstSttn() {
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
queryClick={function (returnType: ReturnType): void {
|
||||
pbnstSttnSearch(
|
||||
false,
|
||||
"1",
|
||||
"15",
|
||||
returnType,
|
||||
pbnRuseNm,
|
||||
searchYear,
|
||||
fclts
|
||||
);
|
||||
queryClick={ ()=> {
|
||||
// pbnSearch(returnType);
|
||||
|
||||
//setTableIndex(0)
|
||||
setIsReset(true);
|
||||
}}
|
||||
excelClick={excelClick}
|
||||
initClick={function (): void {
|
||||
@@ -194,13 +194,16 @@ export default function PbnstSttn() {
|
||||
pbnstSttnSearch(
|
||||
false,
|
||||
String(page),
|
||||
String(15),
|
||||
String(prfRegPageSize),
|
||||
ref.current,
|
||||
pbnRuseNm,
|
||||
searchYear,
|
||||
fclts
|
||||
);
|
||||
setIsReset(false);
|
||||
}}
|
||||
|
||||
resetPageNo={isReset}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
|
||||
</UiTable>
|
||||
|
||||
@@ -38,11 +38,12 @@ import { useTranslation } from "react-i18next";
|
||||
import { headMakeprfmnc } from "../chkgdnReg/TableHead";
|
||||
|
||||
export default function PrfmncPrfmncReg() {
|
||||
const { auth, prfmnc, prfmncHasuInit, prfmnRegData, prfmncHasuNmSearch } = useWrStore(
|
||||
const { auth, prfmnc, prfmncHasuInit, prfmnRegData, prfmncHasuNmSearch,getPrfFmcRes } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const { pbnstPrfmncHeadList, monthHeadList, prfmncRes, prfmncResCount } = prfmnc;
|
||||
const { prfPbnFclts, pbnstPrfmncHeadList, monthHeadList, prfmncRes, prfmncResCount } = prfmnc;
|
||||
const { regAuthrtYn, mdfcnAuthrtYn } = auth;
|
||||
const [isReset, setIsReset] = useState(false);
|
||||
const [bdstTable, setbdstTable] = useState<FcPrfType[]>();
|
||||
const [searchTxt, setSearchTxt] = useState<string>();
|
||||
const [isExcelOpen, setIsExcelOPen] = useState<{
|
||||
@@ -51,7 +52,6 @@ export default function PrfmncPrfmncReg() {
|
||||
}>({ isModal: false, data: {} as FcPrfType });
|
||||
const [inputData, setInputData] = useState<any[]>();
|
||||
const [pbnstRuseFcltId, setpbnstRuseFcltId] = useState<string>();
|
||||
const [pageNation, setPageNation] = useState<number>(1);
|
||||
const [cellNum, setCellNum] = useState<number>(1);
|
||||
const [searchYear, setSearchYear] = useState<string>(
|
||||
String(new Date().getFullYear())
|
||||
@@ -65,20 +65,6 @@ export default function PrfmncPrfmncReg() {
|
||||
"A1:O1"
|
||||
);
|
||||
}, [prfmnc.excelList]);
|
||||
/*
|
||||
const onSave = useCallback(
|
||||
async() => {
|
||||
if (pbnstRuseFcltId) {
|
||||
await prfmnRegData(pageNation,'41',
|
||||
excelToPbnPrfData(
|
||||
inputData as unknown as JSON[],
|
||||
searchYear,
|
||||
pbnstRuseFcltId
|
||||
) as unknown as PrfType
|
||||
);
|
||||
// cellClick(cellNum)
|
||||
}
|
||||
}, [inputData, searchYear, pbnstRuseFcltId, pageNation,cellNum]);*/
|
||||
|
||||
const { t } = useTranslation('base');
|
||||
const onSave = useCallback(() => {
|
||||
@@ -86,19 +72,20 @@ export default function PrfmncPrfmncReg() {
|
||||
if (!pbnstRuseFcltId) return;
|
||||
|
||||
prfmnRegData(
|
||||
pageNation,
|
||||
1,
|
||||
'41',
|
||||
excelToPbnPrfData(
|
||||
inputData as unknown as JSON[],
|
||||
searchYear,
|
||||
pbnstRuseFcltId
|
||||
) as unknown as PrfType
|
||||
, searchYear
|
||||
, searchYear,
|
||||
prfPbnFclts
|
||||
);
|
||||
};
|
||||
|
||||
confirmToast(t('isUpdateMsg'), handleConfirm);
|
||||
}, [inputData, searchYear, pbnstRuseFcltId, pageNation, cellNum]);
|
||||
}, [inputData, searchYear, pbnstRuseFcltId, cellNum,prfPbnFclts]);
|
||||
|
||||
const cellClick = useCallback(
|
||||
(index: number | undefined) => {
|
||||
@@ -194,10 +181,15 @@ export default function PrfmncPrfmncReg() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!prfmnc.isInit) {
|
||||
const year = new Date().getFullYear()
|
||||
prfmncHasuInit(1, '41', String(year));
|
||||
getPrfFmcRes()
|
||||
}
|
||||
}, [prfmnc.isInit, prfmncHasuInit]);
|
||||
}, [prfmnc.isInit, getPrfFmcRes]);
|
||||
|
||||
|
||||
useEffect(() =>{
|
||||
const year = new Date().getFullYear()
|
||||
prfmncHasuInit(1, '41',String(year) ,prfPbnFclts);
|
||||
},[prfPbnFclts])
|
||||
useEffect(() => {
|
||||
|
||||
|
||||
@@ -254,14 +246,8 @@ export default function PrfmncPrfmncReg() {
|
||||
<div className="flex flex-row space-x-2">
|
||||
<Button size={"sm"} onClick={() => {
|
||||
|
||||
if (searchTxt && searchTxt?.length > 0) {
|
||||
prfmncHasuNmSearch(1, '41', searchYear, searchTxt)
|
||||
setPageNation(1)
|
||||
} else {
|
||||
prfmncHasuInit(1, '41', searchYear)
|
||||
setPageNation(1)
|
||||
}
|
||||
|
||||
setIsReset(true)
|
||||
}}>
|
||||
조회
|
||||
</Button>
|
||||
@@ -314,10 +300,15 @@ export default function PrfmncPrfmncReg() {
|
||||
setCellNum(index ?? 0);
|
||||
}}
|
||||
onPageChange={
|
||||
(page) => {
|
||||
prfmncHasuInit(page, '41', searchYear);
|
||||
setPageNation(page)
|
||||
(page:number) => {
|
||||
if (searchTxt && searchTxt?.length > 0) {
|
||||
prfmncHasuNmSearch(page, '41', searchYear, searchTxt,prfPbnFclts)
|
||||
} else {
|
||||
prfmncHasuInit(page, '41', searchYear,prfPbnFclts)
|
||||
}
|
||||
setIsReset(false);
|
||||
}}
|
||||
resetPageNo={isReset}
|
||||
/>
|
||||
</ScrollArea>
|
||||
</ListDiv>
|
||||
@@ -350,9 +341,10 @@ export default function PrfmncPrfmncReg() {
|
||||
setIsExcelOPen({ ...isExcelOpen, isModal: open })
|
||||
}}
|
||||
setModalExcelData={async (excelData) => {
|
||||
await prfmnRegData(pageNation, '41',
|
||||
await prfmnRegData(1, '41',
|
||||
excelData,
|
||||
searchYear
|
||||
,prfPbnFclts
|
||||
);
|
||||
// 데이터 저장 후 UI 업데이트는 useEffect가 감지하여 처리하므로 여기서는 호출하지 않습니다.
|
||||
}
|
||||
|
||||
@@ -150,9 +150,9 @@ export default function PbnstPrfmncSttn() {
|
||||
}
|
||||
const tableData = [...inUsageData, ...outUsageData, usageTotalObj];
|
||||
setPrfData(tableData);
|
||||
setExcelData(excelPrfmncSttnParsing(prfData ?? []))
|
||||
// });
|
||||
setExcelData(excelPrfmncSttnParsing(tableData ?? []))
|
||||
} else {
|
||||
setExcelData(excelPrfmncSttnParsing([]))
|
||||
setPrfData([]);
|
||||
}
|
||||
}
|
||||
@@ -605,7 +605,11 @@ export default function PbnstPrfmncSttn() {
|
||||
isResetPage(true)
|
||||
}}
|
||||
excelClick={excelClick}
|
||||
initClick={function (): void { }}
|
||||
initClick={function (): void {
|
||||
setPbnRuseNm("");
|
||||
setFromDate(String(new Date().getFullYear()));
|
||||
setToDate(String(new Date().getFullYear()))
|
||||
}}
|
||||
btnClass={btnClass}
|
||||
ref={ref} isAdmin={false} />
|
||||
</div>
|
||||
|
||||
@@ -98,7 +98,7 @@ export const DmdCoReqSchema = z.object({
|
||||
z.object({
|
||||
ruseUtztnFcltNm: z.string(),
|
||||
ruseUtztnFcltCd: z.string(),
|
||||
})
|
||||
}).nullish()
|
||||
).nullish(),
|
||||
totalConstCost: z.number().nullish(),
|
||||
});
|
||||
|
||||
@@ -52,8 +52,6 @@ export const coSttnActionsExport: (set: any) => coSttnActions = (
|
||||
`/reuseFc/request/${pageNo}/${pageCnt}/${con}`
|
||||
);
|
||||
|
||||
console.log('coSttnRes ', coSttnRes)
|
||||
|
||||
set((state: coSttnState) => {
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -7,7 +7,7 @@ import toast from "react-hot-toast";
|
||||
|
||||
const pbnstPrfmncHeadList = pbnstPrfmncHeadListExport;
|
||||
const monthHeadList = monthHeadListExport;
|
||||
|
||||
export const prfRegPageSize = 10;
|
||||
export type pbnstPrfmncState = {
|
||||
prfmnc: {
|
||||
isInit: boolean;
|
||||
@@ -16,7 +16,8 @@ export type pbnstPrfmncState = {
|
||||
prfmncRes: FcPrfType[];
|
||||
prfmncResCount: number;
|
||||
excelList: number[];
|
||||
pageKey:number
|
||||
pageKey: number;
|
||||
prfPbnFclts: string[];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -26,68 +27,126 @@ export const pbnstPrfmncStateExport: pbnstPrfmncState = {
|
||||
pbnstPrfmncHeadList: pbnstPrfmncHeadList,
|
||||
monthHeadList: monthHeadList,
|
||||
prfmncRes: [],
|
||||
prfPbnFclts: [],
|
||||
prfmncResCount: 1,
|
||||
excelList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||
pageKey:1
|
||||
pageKey: 1,
|
||||
},
|
||||
};
|
||||
|
||||
export type pbnstPrfmncType = pbnstPrfmncState & pbnstPrfmncActions;
|
||||
|
||||
type pbnstPrfmncActions = {
|
||||
prfmncHasuInit: (page: number, sggOrCity: string ,year:string) => void;
|
||||
prfmncHasuNmSearch: (page: number, sggOrCity: string , txt:string ,year:string) => void;
|
||||
prfmnRegData: (page:number,sggOrCity:string, data: PrfType,year:string) => void;
|
||||
prfmncHasuInit: (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
year: string,
|
||||
prfPbnFclts: string[]
|
||||
) => void;
|
||||
prfmncHasuNmSearch: (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
year: string,
|
||||
searchTxt: string,
|
||||
prfPbnFclts: string[]
|
||||
) => void;
|
||||
prfmnRegData: (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
data: PrfType,
|
||||
year: string,
|
||||
prfPbnFclts: string[]
|
||||
) => void;
|
||||
getPrfFmcRes: () => void;
|
||||
};
|
||||
|
||||
const checkWrRegList = async (year:string) => {
|
||||
const url =`/reuseFc/pubDetailList`
|
||||
if(year&& year.length>0){
|
||||
// url+=`/${year}`
|
||||
}
|
||||
const wrRegList = await getFetch("wr", url);
|
||||
return wrRegList;
|
||||
};
|
||||
const hasuListFetch = async (page: number, sggOrCity: string , year:string,searchNm?:string ) => {
|
||||
const checkWrRegListRes = await checkWrRegList(year);
|
||||
const rainRes = await postFectch(
|
||||
`/prcsFclt/ruseInfo/${page ? page : 1}/10/A/${sggOrCity ? sggOrCity : "11"}/0/1/SW`,
|
||||
checkWrRegListRes?.fcltCds,
|
||||
fetchType.COMMON
|
||||
);
|
||||
let findData = rainRes.data.map((item: pubHasuType) => {
|
||||
const data = checkWrRegListRes?.fcPrfList.find(
|
||||
(fclt: FcPrfType) =>
|
||||
fclt.pbnstRuseFcltId.substring(0, 11) === item?.bscFctCd
|
||||
);
|
||||
if(data !==undefined){
|
||||
return( {
|
||||
|
||||
sido: item.sido,
|
||||
gugun: item.gugun,
|
||||
bscFctNm: item.bscFctNm,
|
||||
bscFctCd: item.bscFctCd,
|
||||
ruseUtztnFcltNm: data.ruseUtztnFcltNm,
|
||||
pbnstRuseFcltId: data.pbnstRuseFcltId,
|
||||
prfList: data.prfList,
|
||||
const hasuListFetch = async (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
year: string,
|
||||
prfPbnFclts: string[],
|
||||
searchTxt?: string
|
||||
) => {
|
||||
let filteredFclt = prfPbnFclts;
|
||||
if (sggOrCity !== "0") {
|
||||
filteredFclt = prfPbnFclts?.filter((fclt: string) => {
|
||||
return sggOrCity.length == 2
|
||||
? fclt.slice(0, 2) === sggOrCity
|
||||
: fclt.slice(0, 5) === sggOrCity;
|
||||
});
|
||||
}
|
||||
}).filter(Boolean); // undefined 값을 제거합니다.
|
||||
|
||||
if(searchNm){
|
||||
|
||||
findData= findData.filter((ruse:any) => ruse.ruseUtztnFcltNm.includes(searchNm))
|
||||
let url = `/prcsFclt/ruseInfo/1/${filteredFclt.length + 1}/A/${sggOrCity}/0/1/SW`;
|
||||
if (searchTxt && searchTxt?.length > 0) {
|
||||
url += `/${searchTxt}`;
|
||||
}
|
||||
const rainRes = await postFectch(url, filteredFclt, fetchType.COMMON);
|
||||
|
||||
return {data:findData, count:findData.length};
|
||||
const checkRuseFcltList =
|
||||
searchTxt && searchTxt?.length > 0
|
||||
? rainRes.data.map((item) => item.bscFctCd)
|
||||
: filteredFclt;
|
||||
|
||||
const pubRuseList = await postFectch(
|
||||
`/reuseFc/pubDetailList/${year}/${sggOrCity}/${page}/${prfRegPageSize}`,
|
||||
checkRuseFcltList,
|
||||
fetchType.WR
|
||||
);
|
||||
const rusePrfList = pubRuseList.data
|
||||
.map((item: FcPrfType) => {
|
||||
const findData = rainRes.data?.find(
|
||||
(fclt: pubHasuType) =>
|
||||
item.pbnstRuseFcltId.substring(0, 11) === fclt?.bscFctCd
|
||||
);
|
||||
if (findData !== undefined) {
|
||||
return {
|
||||
sido: findData.sido,
|
||||
gugun: findData.gugun,
|
||||
bscFctNm: findData.bscFctNm,
|
||||
bscFctCd: findData.bscFctCd,
|
||||
ruseUtztnFcltNm: item.ruseUtztnFcltNm,
|
||||
pbnstRuseFcltId: item.pbnstRuseFcltId,
|
||||
prfList: item.prfList,
|
||||
};
|
||||
}
|
||||
})
|
||||
.filter(Boolean); // undefined 값을 제거합니다.
|
||||
|
||||
return { data: rusePrfList, count: pubRuseList.count };
|
||||
};
|
||||
export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
|
||||
set: any
|
||||
) => {
|
||||
return {
|
||||
prfmncHasuInit: async (page: number, sggOrCity: string,year:string) => {
|
||||
getPrfFmcRes: async () => {
|
||||
try {
|
||||
const prfmncRes = await hasuListFetch(page, sggOrCity, year);
|
||||
const pbnPrfRes = await getFetch(fetchType.WR, "/reuseFc/pubFc");
|
||||
console.log("pbnPrfRes ", pbnPrfRes);
|
||||
set((state: pbnstPrfmncState) => ({
|
||||
...state,
|
||||
prfmnc: {
|
||||
...state.prfmnc,
|
||||
prfPbnFclts: pbnPrfRes,
|
||||
},
|
||||
}));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
prfmncHasuInit: async (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
year: string,
|
||||
prfPbnFclts: string[]
|
||||
) => {
|
||||
try {
|
||||
console.log("prfPbnFclts ", prfPbnFclts);
|
||||
const prfmncRes = await hasuListFetch(
|
||||
page,
|
||||
sggOrCity,
|
||||
year,
|
||||
prfPbnFclts
|
||||
);
|
||||
return set((state: pbnstPrfmncState) => ({
|
||||
...state,
|
||||
prfmnc: {
|
||||
@@ -101,9 +160,21 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
|
||||
console.log(errorHasu);
|
||||
}
|
||||
},
|
||||
prfmncHasuNmSearch: async (page: number, sggOrCity: string,fcltNm:string ,year:string)=> {
|
||||
prfmncHasuNmSearch: async (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
year: string,
|
||||
searchTxt: string,
|
||||
prfPbnFclts: string[]
|
||||
) => {
|
||||
try {
|
||||
const prfmncRes = await hasuListFetch(page, sggOrCity,fcltNm ,year);
|
||||
const prfmncRes = await hasuListFetch(
|
||||
page,
|
||||
sggOrCity,
|
||||
year,
|
||||
prfPbnFclts,
|
||||
searchTxt
|
||||
);
|
||||
return set((state: pbnstPrfmncState) => ({
|
||||
...state,
|
||||
prfmnc: {
|
||||
@@ -117,7 +188,13 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
|
||||
console.log(errorHasu);
|
||||
}
|
||||
},
|
||||
prfmnRegData: async (page:number,sggOrCity:string,data: PrfType,year:string) => {
|
||||
prfmnRegData: async (
|
||||
page: number,
|
||||
sggOrCity: string,
|
||||
data: PrfType,
|
||||
year: string,
|
||||
prfPbnFclts: string[]
|
||||
) => {
|
||||
try {
|
||||
const ressponse = await postFectch(
|
||||
"/reuseFc/pubFcPrf",
|
||||
@@ -125,11 +202,14 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
|
||||
fetchType.WR
|
||||
);
|
||||
|
||||
|
||||
if (ressponse.status === 200) {
|
||||
toast.success("하수재이용 시설 실적 등록이 완료되었습니다.");
|
||||
const prfmncRes = await hasuListFetch(page, sggOrCity,year) ;
|
||||
|
||||
const prfmncRes = await hasuListFetch(
|
||||
page,
|
||||
sggOrCity,
|
||||
year,
|
||||
prfPbnFclts
|
||||
);
|
||||
|
||||
return set((state: pbnstPrfmncState) => ({
|
||||
...state,
|
||||
@@ -138,10 +218,9 @@ export const pbnstPrfmncActionsExport: (set: any) => pbnstPrfmncActions = (
|
||||
prfmncRes: prfmncRes.data,
|
||||
prfmncResCount: prfmncRes.count,
|
||||
isInit: false,
|
||||
pageKey: state.prfmnc.pageKey + 1
|
||||
pageKey: state.prfmnc.pageKey + 1,
|
||||
},
|
||||
}));
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
@@ -50,42 +50,56 @@ const hasuListFetch = async (
|
||||
page: number,
|
||||
returnType: ReturnType,
|
||||
searchNm: string | undefined,
|
||||
year: string,
|
||||
fromDate: string,
|
||||
toDate: string,
|
||||
flcts: string[]
|
||||
) => {
|
||||
let url = `/prcsFclt/ruseInfo/`;
|
||||
let url = '';
|
||||
let filteredFclt = flcts;
|
||||
const filterData = returnType.sigunValue !== '0' ? returnType.sigunValue : returnType.sidoValue
|
||||
|
||||
if (filterData !== '0')
|
||||
filteredFclt = flcts.filter((fclt: string) => {
|
||||
return filterData.length == 2 ? fclt.slice(0, 2) === filterData : fclt.slice(0, 5) === filterData
|
||||
})
|
||||
if (returnType.partValue === "A") {
|
||||
url += `${page}/5/${returnType.partValue}/${
|
||||
url += `${returnType.partValue}/${
|
||||
// returnType.sidoValue ? returnType.sidoValue : returnType.sigunValue
|
||||
returnType.sigunValue !== '0' ? returnType.sigunValue : returnType.sidoValue
|
||||
}/0/1/SW`
|
||||
|
||||
if (filterData !== '0')
|
||||
filteredFclt = flcts.filter((fclt: string) => {
|
||||
return filterData.length == 2 ? fclt.slice(0, 2) === filterData : fclt.slice(0, 5) === filterData
|
||||
})
|
||||
} else if (returnType.partValue === "R") {
|
||||
url += `${page}/5/${returnType.partValue}/${returnType.regionValue
|
||||
url += `${returnType.partValue}/${returnType.regionValue
|
||||
? returnType.regionValue
|
||||
: returnType.unitWaterShedValue
|
||||
? returnType.unitWaterShedValue
|
||||
: returnType.middleRegionValue
|
||||
}/0/1/SW`
|
||||
} else if (returnType.partValue === 'G') {
|
||||
url += `${page}/5/${returnType.envPartValue}/${returnType.sigunValue !== '0' ? returnType.sigunValue : returnType.sidoValue}/0/1/SW`
|
||||
|
||||
url += `${returnType.envPartValue}/${returnType.sigunValue !== '0' ? returnType.sigunValue : returnType.sidoValue}/0/1/SW`
|
||||
if (filterData !== '0')
|
||||
filteredFclt = flcts.filter((fclt: string) => {
|
||||
return filterData.length == 2 ? fclt.slice(0, 2) === filterData : fclt.slice(0, 5) === filterData
|
||||
})
|
||||
} else {
|
||||
url += `1/2/A/0/0/1/SW`
|
||||
url += `A/0/0/1/SW`
|
||||
}
|
||||
|
||||
if (searchNm && searchNm?.length > 0) {
|
||||
url += "/" + searchNm
|
||||
}
|
||||
|
||||
const pbnList = await postFectch(url, flcts, fetchType.COMMON);
|
||||
const pbnList = await postFectch(`/prcsFclt/ruseInfo/1/${filteredFclt.length}/` + url, filteredFclt, fetchType.COMMON);
|
||||
const checkRuseFcltList = searchNm && searchNm?.length > 0 ? pbnList.data.map((item) => item.bscFctCd) : filteredFclt
|
||||
const getRuseList = await postFectch(
|
||||
`/reuseFc/pubDetailList/${year}`,
|
||||
flcts,
|
||||
`/reuseFc/pubDetailPrfList/${fromDate}/${toDate}/${filterData}/${page}/5`,
|
||||
checkRuseFcltList,
|
||||
fetchType.WR
|
||||
);
|
||||
let count = 0;
|
||||
const checkWrRegListRes = getRuseList.data;
|
||||
|
||||
const data: WaterReuseFacility[] = checkWrRegListRes.map(
|
||||
(item: FcPrfType) => {
|
||||
if (!item.prfList || item.prfList.length === 0) {
|
||||
@@ -96,7 +110,6 @@ const hasuListFetch = async (
|
||||
fclt.bscFctCd === item.pbnstRuseFcltId.substring(0, 11)
|
||||
);
|
||||
if (findData) {
|
||||
count++;
|
||||
return {
|
||||
sido: findData?.sido || '-',
|
||||
gugun: findData?.gugun || '-',
|
||||
@@ -104,12 +117,12 @@ const hasuListFetch = async (
|
||||
ruseUtztnFcltNm: item?.ruseUtztnFcltNm || '-',
|
||||
pbnstRuseFcltId: item?.pbnstRuseFcltId || '-',
|
||||
bscFctCd: findData?.bscFctCd || '-',
|
||||
count
|
||||
prfList: item.prfList,
|
||||
}
|
||||
}
|
||||
}
|
||||
).filter(Boolean);
|
||||
return data;
|
||||
return {data: data, count: getRuseList.count};
|
||||
}
|
||||
|
||||
export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions = (
|
||||
@@ -175,29 +188,17 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
|
||||
page,
|
||||
returnType,
|
||||
fcltNm,
|
||||
fromDate,
|
||||
toDate,
|
||||
fclts);
|
||||
// const bscFctCdList = prfmncRes.map((item: any) => {
|
||||
// return item.bscFctCd;
|
||||
// })
|
||||
const bscFctCdList = prfmncRes
|
||||
.map((item: any) => item.bscFctCd)
|
||||
.filter((value, index, self) => self.indexOf(value) === index);
|
||||
// const bscFctCdList = [...new Set(prfmncRes.map((item: any) => item.bscFctCd))];
|
||||
|
||||
|
||||
const res = await postFectch(
|
||||
`/reuseFc/pubDetailList/${fromDate}/${toDate}`,
|
||||
bscFctCdList,
|
||||
`wr`,
|
||||
)
|
||||
let inUsageSum = 0;
|
||||
let outUsageSum = 0;
|
||||
let year = "";
|
||||
const yearsData = [] as any
|
||||
|
||||
res.data.forEach((item: any) => {
|
||||
if (item.prfList.length === 0) {
|
||||
prfmncRes.data.forEach((item: any) => {
|
||||
if (!item.prfList || item.prfList.length === 0) {
|
||||
const year: string = ""; // 연도 정보가 없으면 빈 문자열, 필요시 item에서 추출.
|
||||
const yearVal: { [key: string]: any } = { year: year, pbnstRuseFcltId: item.pbnstRuseFcltId ?? "", ruseUtztnFcltNm: item.ruseUtztnFcltNm ?? "" };
|
||||
yearVal[`${year}inUsage`] = 0;
|
||||
@@ -205,7 +206,7 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
|
||||
yearVal[`${year}total`] = 0;
|
||||
yearsData.push(yearVal);
|
||||
}
|
||||
item.prfList.forEach((acc) => {
|
||||
item.prfList?.forEach((acc: any) => {
|
||||
year = acc.ym?.substring(0, 4) ?? "";
|
||||
inUsageSum =
|
||||
(acc.wshwtr ?? 0) + //조경용수
|
||||
@@ -273,7 +274,7 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
|
||||
|
||||
// prfmncRes 정보 merge
|
||||
const resData = Object.values(mergedMap).map((item: any) => {
|
||||
const match = prfmncRes.find((res) => res.pbnstRuseFcltId === item.pbnstRuseFcltId);
|
||||
const match = prfmncRes.data.find((res) => res.pbnstRuseFcltId === item.pbnstRuseFcltId);
|
||||
return match ? { ...item, ...match } : item;
|
||||
});
|
||||
|
||||
@@ -282,10 +283,10 @@ export const pbnstPrfmncSttnActionsExport: (set: any) => pbnstPrfmncSttnActions
|
||||
pbnstPrfmncSttn: {
|
||||
...state.pbnstPrfmncSttn,
|
||||
// prfmncRes: prfmncRes,
|
||||
prfmncResCount: fclts.length - 5,
|
||||
prfmncResCount: prfmncRes.count,
|
||||
isInit: false,
|
||||
prfmncRes: resData,
|
||||
rawData: res.data
|
||||
rawData: prfmncRes.data
|
||||
},
|
||||
}));
|
||||
} catch (errorHasu) {
|
||||
|
||||
@@ -95,43 +95,59 @@ const hasuListFetch = async (
|
||||
year: string,
|
||||
flcts: string[]
|
||||
) => {
|
||||
let url = `/prcsFclt/ruseInfo/`;
|
||||
let url = ``;
|
||||
let filteredFclt = flcts;
|
||||
const filterData = reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue
|
||||
|
||||
|
||||
if(filterData !== '0')
|
||||
filteredFclt= flcts.filter((fclt: string) => {
|
||||
return filterData.length==2 ?fclt.slice(0, 2) === filterData:fclt.slice(0, 5) === filterData
|
||||
})
|
||||
if (reurnValue.partValue === "A") {
|
||||
url += `${page}/${total}/${reurnValue.partValue}/${
|
||||
url += `${reurnValue.partValue}/${
|
||||
// reurnValue.sidoValue ? reurnValue.sidoValue : reurnValue.sigunValue
|
||||
reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue
|
||||
}/0/1/SW`
|
||||
|
||||
if(filterData !== '0')
|
||||
filteredFclt= flcts.filter((fclt: string) => {
|
||||
return filterData.length==2 ?fclt.slice(0, 2) === filterData:fclt.slice(0, 5) === filterData
|
||||
})
|
||||
} else if (reurnValue.partValue === "R") {
|
||||
url += `${page}/${total}/${reurnValue.partValue}/${reurnValue.regionValue
|
||||
url += `${reurnValue.partValue}/${reurnValue.regionValue
|
||||
? reurnValue.regionValue
|
||||
: reurnValue.unitWaterShedValue
|
||||
? reurnValue.unitWaterShedValue
|
||||
: reurnValue.middleRegionValue
|
||||
}/0/1/SW`
|
||||
} else if (reurnValue.partValue === 'G') {
|
||||
|
||||
|
||||
url += `${page}/${total}/${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW`
|
||||
url += `${reurnValue.envPartValue}/${reurnValue.sigunValue !== '0' ? reurnValue.sigunValue : reurnValue.sidoValue}/0/1/SW`
|
||||
if(filterData !== '0')
|
||||
filteredFclt= flcts.filter((fclt: string) => {
|
||||
return filterData.length==2 ?fclt.slice(0, 2) === filterData:fclt.slice(0, 5) === filterData
|
||||
})
|
||||
|
||||
} else {
|
||||
url += `1/2/A/0/0/1/SW`
|
||||
url += `A/0/0/1/SW`
|
||||
}
|
||||
|
||||
if (searchNm && searchNm?.length > 0) {
|
||||
url += "/" + searchNm
|
||||
}
|
||||
|
||||
const pbnList = await postFectch(url, flcts, fetchType.COMMON);
|
||||
const pbnList = await postFectch( `/prcsFclt/ruseInfo/1/${filteredFclt.length}/`+url, filteredFclt, fetchType.COMMON);
|
||||
|
||||
|
||||
const checkRuseFcltList = searchNm && searchNm?.length > 0?pbnList.data.map((item)=> item.bscFctCd ):filteredFclt
|
||||
const getRuseList = await postFectch(
|
||||
`/reuseFc/pubDetailList/${year}`,
|
||||
flcts,
|
||||
`/reuseFc/pubDetailList/${year}/${filterData}/${page}/${total}`,
|
||||
checkRuseFcltList,
|
||||
fetchType.WR
|
||||
);
|
||||
const checkWrRegListRes = getRuseList.data;
|
||||
|
||||
|
||||
|
||||
const data: WaterReuseFacility[] = checkWrRegListRes.map(
|
||||
(item: FcPrfType) => {
|
||||
const findData = pbnList.data.find(
|
||||
@@ -140,7 +156,6 @@ const hasuListFetch = async (
|
||||
);
|
||||
|
||||
if (findData) {
|
||||
|
||||
const usage = item.prfList.reduce(
|
||||
(acc, cur) => {
|
||||
acc.inUsage +=
|
||||
@@ -197,7 +212,11 @@ const hasuListFetch = async (
|
||||
|
||||
}
|
||||
).filter(Boolean);
|
||||
return data;
|
||||
|
||||
|
||||
|
||||
|
||||
return {data:data, count:getRuseList.count};
|
||||
};
|
||||
|
||||
export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
@@ -238,7 +257,6 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
) => {
|
||||
try {
|
||||
|
||||
|
||||
const pbnstSttnRes = await hasuListFetch(
|
||||
page,
|
||||
total,
|
||||
@@ -250,7 +268,7 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
|
||||
// if (Number(total) > 9000) {
|
||||
if (isExcel) {
|
||||
const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes);
|
||||
const pbnstExcel = excelPbnstSttnParsing(pbnstSttnRes.data);
|
||||
set((state: pbnstSttnState) => {
|
||||
return {
|
||||
...state,
|
||||
@@ -267,8 +285,8 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
...state,
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
pbnstSttnRes: pbnstSttnRes,
|
||||
pbnstSttnResCount: pbnstSttnRes.length
|
||||
pbnstSttnRes: pbnstSttnRes.data,
|
||||
pbnstSttnResCount: pbnstSttnRes.count
|
||||
// isInit: false,
|
||||
},
|
||||
};
|
||||
@@ -295,13 +313,14 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
fclts
|
||||
);
|
||||
|
||||
|
||||
set((state: pbnstSttnState) => {
|
||||
return {
|
||||
...state,
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
pbnstSttnRes: pbnstSttnRes,
|
||||
pbnstSttnResCount: pbnstSttnRes.length,
|
||||
pbnstSttnRes: pbnstSttnRes.data,
|
||||
pbnstSttnResCount: pbnstSttnRes.count,
|
||||
isInit: false,
|
||||
pbnstDetail: {} as customPbnst
|
||||
},
|
||||
@@ -365,8 +384,8 @@ export const pbnstSttnActionsExport: (set: any) => pbnstSttnActions = (
|
||||
...state,
|
||||
pbnstSttn: {
|
||||
...state.pbnstSttn,
|
||||
pbnstSearchData: pbnstSttnRes,
|
||||
pbnstSttnResCount: pbnstSttnRes.length,
|
||||
pbnstSearchData: pbnstSttnRes.data,
|
||||
pbnstSttnResCount: pbnstSttnRes.count,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -488,16 +488,6 @@ export function PbnstBuseForm({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* <MngRegFormDetail
|
||||
formList={ruseWaterQulityList}
|
||||
h1Title={`하수처리수 재이용시설 보증수질 `}
|
||||
subTitle="※재처리시설이 있는 경우만 작성"
|
||||
form={form}
|
||||
moClass="grid grid-cols-12 gap-4"
|
||||
sonClass="col-span-4"
|
||||
indexMng={indexMng}
|
||||
indexBiz={indexBiz}
|
||||
/> */}
|
||||
<div>
|
||||
|
||||
<BuseWaterQulity
|
||||
|
||||
@@ -17,7 +17,6 @@ export class LoginApiService implements LoginService {
|
||||
|
||||
public async login(payload: ILogin): Promise<void> {
|
||||
try {
|
||||
console.log(' ENDPOINT.USER_SERVICE.LOGIN ', ENDPOINT.USER_SERVICE.LOGIN)
|
||||
const response = await fetch( PROXY_HOST+ ENDPOINT.USER_SERVICE.LOGIN, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
|
||||
@@ -98,7 +98,8 @@ function Gis({
|
||||
detailView: DetailView,
|
||||
onFeatureSelect,
|
||||
setIsSearchModalOpen,
|
||||
onCheckedLayersChange
|
||||
onCheckedLayersChange,
|
||||
searchBar: SearchBar
|
||||
}) {
|
||||
const mapRef = useRef();
|
||||
const [mapObject, setMapObject] = useState({});
|
||||
@@ -127,102 +128,7 @@ function Gis({
|
||||
|
||||
// Feature Click Event
|
||||
const handleFeatureSelect = useCallback((data) => {
|
||||
console.log(data);
|
||||
// gisMap = mapInstanceRef.current;
|
||||
// gisMap = mapInstanceRef.current;
|
||||
|
||||
// if (!gisMap) {
|
||||
// console.warn('지도가 초기화되지 않았습니다.');
|
||||
// return;
|
||||
// }
|
||||
// if (!gisMap) {
|
||||
// console.warn('지도가 초기화되지 않았습니다.');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 항상 같은 select 객체 사용
|
||||
// const select = GisApp.Module.select;
|
||||
// if (!select) return;
|
||||
// // 항상 같은 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 인스턴스를 찾아서 사용
|
||||
// let featureId = data.fid;
|
||||
// const layerName = layerNmRef.current
|
||||
// if (layerName === '하수재이용시설') {
|
||||
// featureId = data.searchPk;
|
||||
// } else if (layerName === '빗물이용시설' || layerName == '중수도시설') {
|
||||
// featureId = data.bdstInfoSn;
|
||||
// } else if (layerName === '하수처리시설') {
|
||||
// featureId = data.bscFctCd;
|
||||
// } else if (layerName === '온배수시설') {
|
||||
// featureId = data.bdstRuseFcltSn;
|
||||
// } else if(layerName == '수요처'){
|
||||
// featureId = data.dmdInfoId.replaceAll('-','')
|
||||
// }
|
||||
// else {
|
||||
// console.warn('해당 레이어에 대한 featureId 매핑 없음', layerNm);
|
||||
// featureId = data.fid || data.id || data.ftrIdn;
|
||||
// }
|
||||
// // gisMap.getLayers().getArray().forEach(layer => {
|
||||
// // const source = layer.getSource?.();
|
||||
// // if (source?.getFeatureById) {
|
||||
// // const feature = source.getFeatureById(String(featureId).trim());
|
||||
// // if (feature) foundFeature = feature;
|
||||
// // }
|
||||
// // });
|
||||
// // const [layerType, id] = String(featureId).split('.');
|
||||
// gisMap.getLayers().getArray().forEach(layer => {
|
||||
// const source = layer.getSource?.();
|
||||
// if (source?.getFeatures) {
|
||||
// const allFeatures = source.getFeatures();
|
||||
// for (const f of allFeatures) {
|
||||
// const id = String(f.getId());
|
||||
// // console.log('id', id, featureId)
|
||||
// if (id && id.split('.')[1] === String(featureId)) {
|
||||
// foundFeature = f;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 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);
|
||||
|
||||
onFeatureSelect?.(data); // 선택된 피쳐 데이터 콜백 호출
|
||||
console.log(data)
|
||||
}, [mapInstanceRef]);
|
||||
|
||||
// 지도 생성 및 초기화
|
||||
@@ -347,7 +253,7 @@ function Gis({
|
||||
<>
|
||||
<GisContext.Provider value={{ gisCore, gisMap: mapInstanceRef.current, treeData, checkedLayerIds }}>
|
||||
<div className="h-[calc(100vh-10rem)] flex relative">
|
||||
<div ref={mapRef} className="gis-map flex-1 relative" style={{ height: '100%', padding: 0 }} />
|
||||
<div ref={mapRef} className="gis-map flex-1 relative" style={{ height: '100%', padding: 0 }} >
|
||||
<GisTree
|
||||
visible={tabVisible}
|
||||
setVisible={setTabVisible}
|
||||
@@ -362,8 +268,6 @@ function Gis({
|
||||
imageVisible={imgVisble}
|
||||
/>
|
||||
|
||||
{/* <GisContent onFeatureSelect={handleFeatureSelect} isSearch={isSearch} isSearchModalOpen={isSearchModalOpen} setIsSearchModalOpen={setIsSearchModalOpen} /> */}
|
||||
|
||||
{/* DetailView가 존재할 때만 렌더링 isSearchModalOpen이 true면 visible=false로 팝업 숨김 */}
|
||||
{isOpen && !isSearchModalOpen && (
|
||||
<DetailView
|
||||
@@ -381,11 +285,17 @@ function Gis({
|
||||
onFeatureSelect={handleFeatureSelect}
|
||||
/>
|
||||
)}
|
||||
{/* <GisLonLat /> */}
|
||||
{/* 시도/시군구 조회 영역 */}
|
||||
{SearchBar && (
|
||||
<div className="absolute top-4 left-1/2 -translate-x-1/2 z-30 bg-gray-300 rounded " style={{ maxWidth: 'calc(100% - 2rem)' }}>
|
||||
<SearchBar/>
|
||||
</div>
|
||||
)}
|
||||
<GisToolBar />
|
||||
<GisMapToggle />
|
||||
<GisSelect onFeatureSelect={handleFeatureSelect} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isSearch && (
|
||||
<div className="absolute right-8 top-[305px] z-20">
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
import { Search } from 'lucide-react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useGisContext } from './Gis';
|
||||
import './lib/css/gis.edit.css';
|
||||
import GisApp from './lib/gis.core';
|
||||
import { Search } from "lucide-react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useGisContext } from "./Gis";
|
||||
import "./lib/css/gis.edit.css";
|
||||
import GisApp from "./lib/gis.core";
|
||||
|
||||
export default function GisContent({ edit = false, onFeatureSelect, isSearch, setIsSearchModalOpen }) {
|
||||
export default function GisContent({
|
||||
edit = false,
|
||||
onFeatureSelect,
|
||||
isSearch,
|
||||
setIsSearchModalOpen,
|
||||
}) {
|
||||
const { gisMap, gisCore } = useGisContext();
|
||||
const [visibleComponents, setVisibleComponents] = useState({});
|
||||
const addressResultLayer = useRef(null);
|
||||
const [playShow, setPlayShow] = useState({ show: false });
|
||||
|
||||
//셀렉트 버튼 이벤트
|
||||
// const clickFeature = useCallback(feature => {
|
||||
// if (feature) {
|
||||
// const layer = feature.getLayer();
|
||||
// setVisibleComponents(prevState => ({
|
||||
// ...prevState,
|
||||
// }));
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
const selectRslt = useCallback(feature => {
|
||||
const selectRslt = useCallback((feature) => {
|
||||
GisApp.Module.layer.highLightFeature(
|
||||
[feature],
|
||||
{
|
||||
@@ -29,14 +22,14 @@ export default function GisContent({ edit = false, onFeatureSelect, isSearch, se
|
||||
opacity: 1,
|
||||
selectable: true,
|
||||
},
|
||||
{ width: 30 }
|
||||
{ width: 30 },
|
||||
);
|
||||
clickFeature(feature);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (gisMap) {
|
||||
setVisibleComponents(prevState => ({
|
||||
setVisibleComponents((prevState) => ({
|
||||
...prevState,
|
||||
}));
|
||||
}
|
||||
@@ -46,24 +39,18 @@ export default function GisContent({ edit = false, onFeatureSelect, isSearch, se
|
||||
|
||||
return (
|
||||
<>
|
||||
{/*<GisTree />*/}
|
||||
{/* <GisMapToggle />
|
||||
<GisTree />
|
||||
<GisMapToggle />
|
||||
<GisLonLat />
|
||||
<GisToolBar /> */}
|
||||
{/* <GisSelect onFeatureSelect={onFeatureSelect} /> */}
|
||||
<GisToolBar />
|
||||
<GisSelect onFeatureSelect={onFeatureSelect} />
|
||||
|
||||
{/* 검색 모달 */}
|
||||
{isSearch && (
|
||||
<div className="absolute right-8 top-[254px] z-20">
|
||||
<button
|
||||
onClick={() => setIsSearchModalOpen(true)}
|
||||
className="overflow-hidden w-[40px] h-[40px] bg-white
|
||||
border border-[#9aa7b8]
|
||||
rounded
|
||||
shadow-[0_0_5px_#999]
|
||||
flex items-center justify-center
|
||||
p-0
|
||||
"
|
||||
className="flex h-[40px] w-[40px] items-center justify-center overflow-hidden rounded border border-[#9aa7b8] bg-white p-0 shadow-[0_0_5px_#999]"
|
||||
>
|
||||
<Search size={24} className="text-gray-700" />
|
||||
</button>
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
// import React, { useState } from 'react';
|
||||
// import { Tabs, TabsList, TabsTrigger } from '@common/components/ui/tabs';
|
||||
// import GisTree from './GisTree';
|
||||
// import GisSearch from './GisSearch';
|
||||
// import { ChevronLeft, ChevronRight, Search } from 'lucide-react';
|
||||
// import SearchModal from '@/map/SearchModal';
|
||||
|
||||
|
||||
// function GisTab({ visible, setVisible, isSearch, isSearchModalOpen, setIsSearchModalOpen, onFeatureSelect }) {
|
||||
// const [activeTab, setActiveTab] = useState('layers');
|
||||
|
||||
// return (
|
||||
// <>
|
||||
// <div
|
||||
// className={`absolute top-0 left-0 w-[250px] h-[calc(100vh-10rem)] bg-white border-r border-gray-300 flex flex-col overflow-hidden transition-all duration-300 z-40
|
||||
// ${visible ? 'translate-x-0 opacity-100' : '-translate-x-full opacity-0 pointer-events-none'}`}
|
||||
// >
|
||||
// <Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 flex flex-col overflow-hidden">
|
||||
// <TabsList className="flex-none mt-4 border-none rounded-none">
|
||||
// <TabsTrigger value="layers" className="flex-1 h-10">레이어</TabsTrigger>
|
||||
// {/* {isSearch && (
|
||||
// <button
|
||||
// onClick={() => setIsSearchModalOpen(true)}
|
||||
// className="h-10 w-10 flex items-center justify-center px-0"
|
||||
// >
|
||||
// <Search size={18} className="text-gray-700" />
|
||||
// </button>
|
||||
// // <TabsTrigger value="search" className="flex-1 h-10 flex items-center justify-center">
|
||||
// // <Search size={18} />
|
||||
// // </TabsTrigger>
|
||||
// )} */}
|
||||
// </TabsList>
|
||||
|
||||
// {/* GisTree는 항상 마운트되며, 탭 상태에 따라 보여주기만 함 */}
|
||||
// <div
|
||||
// className={`grow overflow-y-auto p-2 pt-0 border-none shadow-none ${activeTab === 'layers' ? 'block' : 'hidden'
|
||||
// }`}
|
||||
// >
|
||||
// <GisTree />
|
||||
// </div>
|
||||
|
||||
// {/* GisSearch도 동일하게 처리 */}
|
||||
// {/* {isSearch && (
|
||||
// <div
|
||||
// className={`grow overflow-y-auto p-2 pt-0 border-none shadow-none ${
|
||||
// activeTab === 'search' ? 'block' : 'hidden'
|
||||
// }`}
|
||||
// >
|
||||
// <GisSearch />
|
||||
// </div>
|
||||
// )} */}
|
||||
|
||||
|
||||
// {/* 🔍 검색 모달 */}
|
||||
// {/* <SearchModal
|
||||
// open={isSearchModalOpen}
|
||||
// onOpenChange={setIsSearchModalOpen}
|
||||
// onFeatureSelect={onFeatureSelect}
|
||||
// /> */}
|
||||
// </Tabs>
|
||||
|
||||
// {/* 접기 버튼 */}
|
||||
// <button
|
||||
// onClick={() => setVisible(false)}
|
||||
// className="absolute top-1/2 right-[-3px] transform -translate-y-1/2 z-50 bg-white border border-l border-gray-300 rounded-l-none rounded-r px-1 py-2 shadow-sm"
|
||||
// >
|
||||
// <ChevronLeft size={16} />
|
||||
// </button>
|
||||
// </div>
|
||||
|
||||
// {/* 열기 버튼 */}
|
||||
// {!visible && (
|
||||
// <button
|
||||
// onClick={() => setVisible(true)}
|
||||
// className="absolute top-1/2 left-[-3px] transform -translate-y-1/2 z-50 bg-white border border-r border-gray-300 rounded-r px-1 py-2 shadow-sm"
|
||||
// >
|
||||
// <ChevronRight size={16} />
|
||||
// </button>
|
||||
// )}
|
||||
// </>
|
||||
// );
|
||||
// }
|
||||
|
||||
// export default React.memo(GisTab);
|
||||
@@ -189,7 +189,7 @@ export default React.memo(function GisTree({ checkedNodes = [], setCheckedNodes
|
||||
};
|
||||
const handleLayerImgClick = (nodeNm, nodeId, layerNm) => {
|
||||
if(!checked.includes(nodeId)) alert('시설을 선택해주세요')
|
||||
else onLayerIconClick(layerNm)
|
||||
else onLayerIconClick(nodeNm)
|
||||
}
|
||||
if (!treeData || treeData.length === 0) return null;
|
||||
|
||||
|
||||
@@ -130,8 +130,6 @@ GisOlLayer.prototype = {
|
||||
strategy: all,
|
||||
});
|
||||
return source;
|
||||
|
||||
return source;
|
||||
},
|
||||
/**
|
||||
* [사용]WFS 레이어 생성
|
||||
|
||||
Reference in New Issue
Block a user