Merge commit 'ca9f2da83cacff3756a6ef43f85affae0cd57d30' into iipbs/dm/dev
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useDmStore } from "@/app/store";
|
||||
import type { DemandCompBizType } from "@/app/store/sdmMng";
|
||||
import { sdmInfoFormSchema, type DemandCompBizType, type SdmInfoFormData } 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";
|
||||
@@ -10,48 +10,9 @@ import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
import { FormProvider, useForm, type SubmitHandler } from "react-hook-form";
|
||||
import toast, { Toaster } from "react-hot-toast";
|
||||
import * as z from "zod";
|
||||
import SdmLogin from "../sdmLogin/page";
|
||||
|
||||
const sdmInfoFormSchema = z.object({
|
||||
sdmNm: z.string().min(1, "수요처를 선택해주세요"),
|
||||
demandYmd: z.date().optional(),
|
||||
demandQnty: z
|
||||
.string()
|
||||
.min(1, "요구수량을 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "요구수량은 숫자만 입력 가능합니다"),
|
||||
usePurpose: z.string().optional(),
|
||||
money: z.string().regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"),
|
||||
/**요구수질 */
|
||||
reqWaterQlty: z.string().optional(),
|
||||
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.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({
|
||||
ruseUtztnFcltNm: z.string(),
|
||||
ruseUtztnFcltCd: z.string(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export type FormData = z.infer<typeof sdmInfoFormSchema>;
|
||||
|
||||
function SdmInfoInsertContent() {
|
||||
const searchParams = useSearchParams();
|
||||
@@ -62,7 +23,7 @@ function SdmInfoInsertContent() {
|
||||
|
||||
const [isLogin, setIsLogin] = useState(false);
|
||||
const [facilityName, setFacilityName] = useState<string>("");
|
||||
const [defaultValues, setDefaultValues] = useState<FormData>({
|
||||
const [defaultValues, setDefaultValues] = useState<SdmInfoFormData>({
|
||||
sdmNm: "",
|
||||
demandYmd: new Date(),
|
||||
demandQnty: "",
|
||||
@@ -109,10 +70,10 @@ function SdmInfoInsertContent() {
|
||||
setSubsInfo([]); // subsInfo 초기화 후보지 처음 화면 들어올때 초기화(스토어내 객체만)
|
||||
}, [setSubsInfo]);
|
||||
|
||||
const form = useForm<FormData>({
|
||||
const form = useForm<SdmInfoFormData>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues,
|
||||
mode: "onChange",
|
||||
mode: "onSubmit",
|
||||
});
|
||||
|
||||
const subsInfo = useDmStore((state) => state.map.subsInfo);
|
||||
@@ -167,7 +128,7 @@ function SdmInfoInsertContent() {
|
||||
}
|
||||
}, [ismoneyDisabled, form]);
|
||||
const router = useRouter();
|
||||
const onSubmit: SubmitHandler<FormData> = async (data) => {
|
||||
const onSubmit: SubmitHandler<SdmInfoFormData> = async (data) => {
|
||||
try {
|
||||
const dmSubsInfo = data.candidateTitle?.filter(
|
||||
(item) => item.ruseUtztnFcltNm && item.ruseUtztnFcltCd
|
||||
|
||||
@@ -3,10 +3,105 @@ 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";
|
||||
import { z } from "zod";
|
||||
|
||||
/**====================================
|
||||
* Store - 타입
|
||||
=====================================*/
|
||||
|
||||
export const sdmInfoFormSchema = z.object({
|
||||
sdmNm: z.string().min(1, "수요처를 선택해주세요"),
|
||||
demandYmd: z.date().optional(),
|
||||
demandQnty: z
|
||||
.string()
|
||||
.min(1, "요구수량을 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "요구수량은 숫자만 입력 가능합니다"),
|
||||
usePurpose: z.string().optional(),
|
||||
money: z.string().regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"),
|
||||
/**요구수질 */
|
||||
reqWaterQlty: z.string().optional(),
|
||||
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.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({
|
||||
ruseUtztnFcltNm: z.string(),
|
||||
ruseUtztnFcltCd: z.string(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
}).superRefine((data, ctx) => {
|
||||
const disabledFields = disableRules[data.usePurpose ?? ""] || [];
|
||||
// 모든 수질 관련 필드
|
||||
// 총대장균군수는 null 값을 불검출로 표시하기때문에 해당 검사에서 제외함.
|
||||
const allFields: (keyof typeof data)[] = [
|
||||
"tn", "combResdch", "tph",
|
||||
"trbt", "ph", "bod", "clIonQnt",
|
||||
"smll", "cdtnv", "crmty",
|
||||
];
|
||||
|
||||
const allFieldsName: Record<string, string> = {
|
||||
tn: "총질소(T-N)(mg/L)",
|
||||
combResdch: "결합잔류염소(mg/L)",
|
||||
tph: "총인(T-P)(mg/L)",
|
||||
trbt: "탁도(NTU)",
|
||||
ph: "수소이온농도(pH)",
|
||||
bod: "생물학적 산소요구량(BOD)(mg/L)",
|
||||
clIonQnt: "염화물(mgCL/L)",
|
||||
smll: "냄새",
|
||||
cdtnv: "전기전도도(㎲/cm)",
|
||||
crmty: "색도(도)",
|
||||
};
|
||||
allFields.forEach((field) => {
|
||||
const isDisabled = disabledFields.includes(field);
|
||||
if (!isDisabled) {
|
||||
// disabled가 아닌 필드는 반드시 값이 있어야 함
|
||||
const value = data[field];
|
||||
if (typeof value === "string") {
|
||||
if (value.trim().length === 0) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: [field],
|
||||
message: `${allFieldsName[field]} 을 입력해주세요.`,
|
||||
});
|
||||
}
|
||||
} else if (typeof value === "number") {
|
||||
if (value <= 0 || Number.isNaN(value)) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: [field],
|
||||
message: `${allFieldsName[field]} 을 입력해주세요.`,
|
||||
});
|
||||
}
|
||||
} else if (value == null) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: [field],
|
||||
message: `${allFieldsName[field]} 을 입력해주세요.`,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
export type SdmInfoFormData = z.infer<typeof sdmInfoFormSchema>;
|
||||
|
||||
|
||||
// 수요처 정보
|
||||
export type DemandCompBizType = {
|
||||
index : number | '';
|
||||
@@ -167,8 +262,8 @@ 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','tn',"clIonQnt",'cdtnv'],
|
||||
"살수": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'],
|
||||
"조경": ["combResdch", "crmty",'tph','cdtnv'],
|
||||
"농업_간접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
|
||||
"농업_직접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
|
||||
@@ -184,6 +279,7 @@ const disableRules: DisableRulesType = {
|
||||
bod: 5,
|
||||
crmty: 20,
|
||||
ph: "5.8~8.5",
|
||||
smll:'불쾌하지않을것',
|
||||
tn:null,
|
||||
tph: null,
|
||||
clIonQnt: null,
|
||||
@@ -196,6 +292,7 @@ const disableRules: DisableRulesType = {
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
crmty: 20,
|
||||
smll:'불쾌하지않을것',
|
||||
ph: "5.8~8.5",
|
||||
tn:null,
|
||||
tph: null,
|
||||
@@ -208,6 +305,7 @@ const disableRules: DisableRulesType = {
|
||||
bod: 5,
|
||||
ph: "5.8~8.5",
|
||||
combResdch:null,
|
||||
smll:'불쾌하지않을것',
|
||||
crmty:null,
|
||||
tn:null,
|
||||
tph: null,
|
||||
@@ -219,6 +317,7 @@ const disableRules: DisableRulesType = {
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
ph: "5.8~8.5",
|
||||
smll:'불쾌하지않을것',
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
tn:null,
|
||||
@@ -231,6 +330,7 @@ const disableRules: DisableRulesType = {
|
||||
trbt: 2,
|
||||
bod: 5,
|
||||
ph: "5.8~8.5",
|
||||
smll:'불쾌하지않을것',
|
||||
clIonQnt:250,
|
||||
combResdch:null,
|
||||
crmty:null,
|
||||
@@ -254,6 +354,7 @@ const disableRules: DisableRulesType = {
|
||||
grssClfg: null,
|
||||
trbt: 2,
|
||||
bod: 8,
|
||||
smll:'불쾌하지않을것',
|
||||
ph: "5.8~8.5",
|
||||
cdtnv:700,
|
||||
combResdch:null,
|
||||
@@ -267,6 +368,7 @@ const disableRules: DisableRulesType = {
|
||||
bod: 5,
|
||||
tn: 10,
|
||||
tph: 0.5,
|
||||
smll:'불쾌하지않을것',
|
||||
ph: "5.8~8.5",
|
||||
combResdch:null,
|
||||
trbt:null,
|
||||
@@ -274,13 +376,14 @@ const disableRules: DisableRulesType = {
|
||||
clIonQnt: null,
|
||||
cdtnv:null
|
||||
},
|
||||
공업:{
|
||||
'공업':{
|
||||
grssClfg: null,
|
||||
bod: null,
|
||||
tn: null,
|
||||
tph: null,
|
||||
ph: "~",
|
||||
combResdch:null,
|
||||
smll:'불쾌하지않을것',
|
||||
trbt:null,
|
||||
crmty:null,
|
||||
clIonQnt: null,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import ModalSimilarPage from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page";
|
||||
import type { FormData } from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page";
|
||||
import { useDmStore } from "@/app/store";
|
||||
import {
|
||||
CANDIDATE,
|
||||
@@ -25,15 +24,16 @@ import SearchInputText from "../common/searhDemandInput/component";
|
||||
import React from "react";
|
||||
import { sanitizeInput } from "../common/utils/utils";
|
||||
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
|
||||
import type { SdmInfoFormData } from "@/app/store/sdmMng";
|
||||
|
||||
export interface SdmInfoRegFormProps {
|
||||
form: UseFormReturn<FormData>;
|
||||
form: UseFormReturn<SdmInfoFormData>;
|
||||
onCheckboxChange?: (checked: boolean) => void;
|
||||
facilityName?: string;
|
||||
}
|
||||
|
||||
type FieldComponent = (
|
||||
field: ControllerRenderProps<FormData, keyof FormData>
|
||||
field: ControllerRenderProps<SdmInfoFormData, keyof SdmInfoFormData>
|
||||
) => JSX.Element;
|
||||
|
||||
export function SdmInfoRegForm({
|
||||
@@ -161,7 +161,7 @@ export function SdmInfoRegForm({
|
||||
|
||||
if (defaults) {
|
||||
Object.entries(defaults).forEach(([field, value]) => {
|
||||
form.setValue(field as keyof FormData, value, { shouldDirty: true });
|
||||
form.setValue(field as keyof SdmInfoFormData, value, { shouldDirty: true });
|
||||
});
|
||||
}
|
||||
}, [form.getValues("usePurpose")]);
|
||||
@@ -176,7 +176,7 @@ export function SdmInfoRegForm({
|
||||
);
|
||||
|
||||
const formFields: Array<{
|
||||
name: keyof FormData;
|
||||
name: keyof SdmInfoFormData;
|
||||
label: string;
|
||||
component: FieldComponent | undefined;
|
||||
formIndex: number;
|
||||
@@ -346,9 +346,7 @@ export function SdmInfoRegForm({
|
||||
const normalFields = formFields.filter(
|
||||
(f) => f.formIndex === 0 && f.component
|
||||
);
|
||||
// const groupFields = formFields.filter(
|
||||
// (f) => f.formIndex === 1 && f.component
|
||||
// );
|
||||
|
||||
const candidateFields = formFields.filter(
|
||||
(f) => f.formIndex === 2 && f.component
|
||||
);
|
||||
@@ -363,8 +361,13 @@ export function SdmInfoRegForm({
|
||||
name={name}
|
||||
render={({ field }) =>
|
||||
name === "money" ? (
|
||||
// component(field)
|
||||
<FormUi label={label + "*"}>{component(field)}</FormUi>
|
||||
<div>
|
||||
<Label className="text-black" >
|
||||
희망단가*
|
||||
</Label>
|
||||
{ component(field)}
|
||||
</div>
|
||||
// <FormUi label={label + "*"}>{component(field)}</FormUi>
|
||||
) : (
|
||||
<AccessibleFormField
|
||||
field={field}
|
||||
@@ -769,7 +772,7 @@ export function SdmInfoRegForm({
|
||||
onSelectValue={(val: string | number) => {
|
||||
field.onChange(val.toString());
|
||||
}}
|
||||
value={field.value || "불쾌하지않을것"}
|
||||
value={field.value }
|
||||
readOnly={isDisabled}
|
||||
onBlur={field.onBlur}
|
||||
ref={field.ref}
|
||||
|
||||
@@ -46,8 +46,8 @@ export function SdmLoginForm() {
|
||||
dmdAplyPswd: z.string().optional(),
|
||||
}), [isBznmTotNoDisabled]);
|
||||
|
||||
type FormData = z.infer<typeof sdmLoginFormSchema>;
|
||||
type FieldComponent = (field: ControllerRenderProps<FormData, keyof FormData>) => JSX.Element;
|
||||
type SdmLoginForm = z.infer<typeof sdmLoginFormSchema>;
|
||||
type FieldComponent = (field: ControllerRenderProps<SdmLoginForm, keyof SdmLoginForm>) => JSX.Element;
|
||||
|
||||
const formSchema = sdmLoginFormSchema;
|
||||
|
||||
@@ -55,7 +55,7 @@ export function SdmLoginForm() {
|
||||
initializeCommonData();
|
||||
}, [initializeCommonData]);
|
||||
|
||||
const defaultValues: FormData = {
|
||||
const defaultValues: SdmLoginForm = {
|
||||
dmdInfoId: '',
|
||||
bznmTotNo: '',
|
||||
password: '',
|
||||
@@ -63,7 +63,7 @@ export function SdmLoginForm() {
|
||||
dmdAplyPswd: '',
|
||||
};
|
||||
|
||||
const form = useForm<FormData>({
|
||||
const form = useForm<SdmLoginForm>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues,
|
||||
mode: "onChange",
|
||||
@@ -105,7 +105,7 @@ export function SdmLoginForm() {
|
||||
};
|
||||
|
||||
const formFields: Array<{
|
||||
name: keyof FormData;
|
||||
name: keyof SdmLoginForm;
|
||||
label: string;
|
||||
component: FieldComponent | undefined;
|
||||
}> = [
|
||||
|
||||
Reference in New Issue
Block a user