wr: 수요처 매칭 검토 천단위 , 건수 10건

This commit is contained in:
2026-06-17 16:29:28 +09:00
parent 34358400e8
commit 823ce262bb
5 changed files with 133 additions and 35 deletions
@@ -30,6 +30,19 @@ const formatValue = (value: string | number | null | undefined) => {
return String(value);
};
const formatNumberWithComma = (value: string | number | null | undefined) => {
if (value === null || value === undefined || value === "") return "-";
const normalized =
typeof value === "string" ? Number(value.replace(/,/g, "")) : Number(value);
if (Number.isNaN(normalized)) {
return String(value);
}
return normalized.toLocaleString("ko-KR");
};
const formatBelow = (value: string | number | null | undefined) => {
if (value === null || value === undefined || value === "") return "-";
if (Number(value) === -1) return "불검출";
@@ -234,9 +247,9 @@ export default function DemandStatusPage() {
return [
{ label: "요구시기", key: "dmndTmng", value: formatDate(selectedSdmInfoStatus.dmndTmng), required: true },
{ label: "요구수량(㎥/d)", key: "dmndQty", value: formatValue(selectedSdmInfoStatus.dmndQty) },
{ label: "요구수량(㎥/d)", key: "dmndQty", value: formatNumberWithComma(selectedSdmInfoStatus.dmndQty) },
{ label: "사용용도", key: "useUsgCd", value: formatValue(selectedSdmInfoStatus.useUsgCd) },
{ label: "희망단가(원/㎥)", key: "wntUntprc", value: formatValue(selectedSdmInfoStatus.wntUntprc) },
{ label: "희망단가(원/㎥)", key: "wntUntprc", value: formatNumberWithComma(selectedSdmInfoStatus.wntUntprc) },
];
}, [selectedSdmInfoStatus]);
@@ -520,7 +533,7 @@ export default function DemandStatusPage() {
{!selectedSdmInfoStatus ? (
<div className="mt-3 border border-neutral-200 px-6 py-10 text-center text-sm text-slate-400">
상세 정보를 표시할 신청건이 없습니다.
조회된 결과가 없습니다.
</div>
) : (
<div className="mt-3 border border-neutral-200">
@@ -14,6 +14,7 @@ import {
type DmdCoReqType,
type DmdMatTableType,
} from "@/app/store/matDmd/coMatRvw/type";
import { DEFAULT_LIST_SIZE } from "@/src/shared/config";
import { formH1Class } from "@/components/lib/class/comClass";
import {
formatPhoneNumber,
@@ -46,6 +47,50 @@ import { useEffect, useRef, useState } from "react";
import { useForm, useWatch } from "react-hook-form";
import { z } from "zod";
const formatNumberWithComma = (value: string | number | null | undefined) => {
if (value === null || value === undefined || value === "") return "";
const normalized =
typeof value === "string" ? Number(value.replace(/,/g, "")) : Number(value);
if (Number.isNaN(normalized)) {
return String(value);
}
return normalized.toLocaleString("ko-KR");
};
const EMPTY_DETAIL_FORM: Partial<DmdCoReqType> = {
dmdInfoSn: 0,
dmdInfoId: "",
dmndQty: undefined,
wntUntprc: undefined,
useUsgCd: "",
dmndTmng: undefined,
grssClfg: undefined,
combResdch: undefined,
trbt: undefined,
blgcOxygDmndQnt: undefined,
smll: undefined,
crmty: undefined,
tn: undefined,
tph: undefined,
ph: undefined,
clIonQnt: undefined,
cdtnv: undefined,
rmrk: undefined,
ruseUtztnFcltNm: "",
splyCndtList: [],
totalConstCost: 0,
demandCst: {
usgPrcsProcs: "",
cstrnCst: 0,
fcltSbsdCstrnCst: 0,
prcsFcltCpctCstrnCst: 0,
},
demandMatching: undefined,
demandCo: undefined,
};
export default function CoMatRvw() {
const readOnlyInputClass = "bg-slate-50 text-gray-700";
@@ -75,6 +120,8 @@ export default function CoMatRvw() {
const [toDate, setToDate] = useState<string>(
String(new Date().getFullYear())
);
const [selectedRowIndex, setSelectedRowIndex] = useState<number>(-1);
const [resetSelection, setResetSelection] = useState(false);
const [selectData, setSelectData] = useState<DmdCoReqType | null>(null); // selectData를 null로 초기화
const [selectionVersion, setSelectionVersion] = useState(0);
const bottomRef = useRef<HTMLDivElement | null>(null);
@@ -100,14 +147,14 @@ export default function CoMatRvw() {
if (dmdCoNm.length > 0) {
coMatRvwSearch(
pageNo,
13,
DEFAULT_LIST_SIZE,
String(startYear),
String(endYear),
sggCd,
dmdCoNm
);
} else {
coMatRvwInqua(pageNo, 13, String(startYear), String(endYear), sggCd);
coMatRvwInqua(pageNo, DEFAULT_LIST_SIZE, String(startYear), String(endYear), sggCd);
}
};
@@ -119,11 +166,22 @@ export default function CoMatRvw() {
const TableCellClick = (index: number) => {
if (coMatRvwRes && coMatRvwRes[index]) {
setSelectedRowIndex(index);
setResetSelection(false);
setSelectData(coMatRvwRes[index]);
setSelectionVersion((v) => v + 1); // 행을 클릭할 때마다 버전을 1씩 증가
bottomRef.current?.scrollIntoView({ behavior: "smooth" }); // 화면 스크롤 처리
}
};
const resetDetailSections = () => {
setSelectedRowIndex(-1);
setResetSelection(true);
setSelectData(null);
form.reset(EMPTY_DETAIL_FORM);
setSelectionVersion((v) => v + 1);
};
const useUsgCdWatch = useWatch({ control: form.control, name: "useUsgCd" });
const useUsgCdText =
code.sewageOutFclttUse?.find((item) => item.val === useUsgCdWatch)?.text ??
@@ -166,6 +224,9 @@ export default function CoMatRvw() {
};
});
setDmdMtaData(tableData(data, { code }));
} else {
setDmdMtaData([]);
setSelectData(null);
}
}, [coMatRvwRes]);
@@ -185,7 +246,7 @@ export default function CoMatRvw() {
useEffect(() => {
if (!initRef.current) {
coMatRvwInit(1, 13, fromDate, toDate);
coMatRvwInit(1, DEFAULT_LIST_SIZE, fromDate, toDate);
//setMounted(true);
initRef.current = true;
}
@@ -295,6 +356,7 @@ export default function CoMatRvw() {
);
} else {
const con = getCurrentRegionCode();
resetDetailSections();
//setPageNatiion(1);
getSearch(1, fromNum, toNum, con, dmdCoNm);
}
@@ -321,8 +383,10 @@ export default function CoMatRvw() {
tableData={dmdMatData || []}
headlist={coRvwHeadList}
widthFixed={true}
pageSize={13}
pageSize={DEFAULT_LIST_SIZE}
total={coMatRvwCount}
resetSelection={resetSelection}
index={selectedRowIndex}
cellClick={(index: number | undefined) => {
if (index !== undefined && index >= 0) {
TableCellClick(index);
@@ -330,6 +394,7 @@ export default function CoMatRvw() {
}}
onPageChange={(val) => {
const con = getCurrentRegionCode();
resetDetailSections();
//setPageNatiion(val);
getSearch(val, Number(fromDate), Number(toDate), con, dmdCoNm);
}}
@@ -377,12 +442,11 @@ export default function CoMatRvw() {
<FormUi label="요구수량(m³/일)">
<Input
placeholder=""
type="number"
step="0.1"
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
className={readOnlyInputClass}
/>
@@ -416,15 +480,14 @@ export default function CoMatRvw() {
control={form.control}
name="wntUntprc"
render={({ field }) => (
<FormUi label="희망단가(원/m3)">
<FormUi label="희망단가(원/m³)">
<Input
placeholder=""
type="number"
step="0.1"
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
className={readOnlyInputClass}
/>
@@ -448,9 +511,13 @@ export default function CoMatRvw() {
className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`}
placeholder=""
value={
field.value != -1 ||field.value != undefined
? `${field.value}`
: "불검출"
field.value === null ||
field.value === undefined ||
field.value === ""
? ""
: field.value === -1
? "불검출"
: formatNumberWithComma(field.value)
}
readOnly
/>
@@ -480,7 +547,7 @@ export default function CoMatRvw() {
type="text"
className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`}
placeholder=""
value={field.value ?? ""}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -504,7 +571,7 @@ export default function CoMatRvw() {
placeholder=""
className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`}
type="text"
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className=" text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -532,7 +599,7 @@ export default function CoMatRvw() {
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? ""}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -574,7 +641,7 @@ export default function CoMatRvw() {
className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`}
type="text"
step="0.1"
value={field.value ?? ""}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -601,7 +668,7 @@ export default function CoMatRvw() {
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -628,7 +695,7 @@ export default function CoMatRvw() {
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -655,7 +722,7 @@ export default function CoMatRvw() {
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
/>
</div>
@@ -679,7 +746,7 @@ export default function CoMatRvw() {
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
@@ -701,12 +768,12 @@ export default function CoMatRvw() {
<div className="relative flex-1 min-w-0">
<Input
placeholder=""
className="w-full pr-16 border py-2 text-right rounded-md"
className={`w-full pr-16 border py-2 text-right rounded-md ${readOnlyInputClass}`}
type="text"
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
+3 -1
View File
@@ -1,4 +1,5 @@
import { fetchType, getFetchWithCount, putFectch } from "@/components/lib/api";
import { DEFAULT_LIST_SIZE } from "@/src/shared/config";
import type { CommonTableProps } from "../../common/type/header";
import {
constCostHeadListExport,
@@ -12,6 +13,7 @@ const coRvwHeadList = coRvwHeadListExport;
const coRvwNodeList = coRvwNodeListExport;
const rateFeeHeadList = rateFeeHeadListExport;
const constCostHeadList = constCostHeadListExport;
export type coRvwState = {
coRvw: {
isInit: boolean;
@@ -118,7 +120,7 @@ export const coRvwActionsExport: (set: any) => coRvwActions = (set: any) => {
const coMatRvwRes = await coMatInit(
1,
10,
DEFAULT_LIST_SIZE,
new Date().getFullYear().toString(),
new Date().getFullYear().toString()
);
+1 -1
View File
@@ -75,7 +75,7 @@ export const DmdCoReqSchema = z.object({
dmndTmng: z.coerce.date().nullish(), // 요구시기
dmndQty: z.number().nullish(), // 요구수량(m³/일)
blgcOxygDmndQnt: z.number().nullish(), // 생물학적 산소요구량(BOD)(mg/L)
wntUntprc: z.number().nullish(), // 희망단가(원/m3)
wntUntprc: z.number().nullish(), // 희망단가(원/m³)
grssClfg: z.number().nullish(), // 총대장균군수(개/100mL)
combResdch: z.number().nullish(), // 결합잔류염소(mg/L)
trbt: z.number().nullish(), // 탁도(NTU)
@@ -28,6 +28,19 @@ import PopoverUi from "@common/business_components/ui/popover_ui";
import { Button, Checkbox, Input, Label } from "@common/components/ui";
import { useCallback, useEffect, useRef, useState } from "react";
import { useForm, type UseFormReturn } from "react-hook-form";
const formatNumberWithComma = (value: string | number | null | undefined) => {
if (value === null || value === undefined || value === "") return "";
const normalized =
typeof value === "string" ? Number(value.replace(/,/g, "")) : Number(value);
if (Number.isNaN(normalized)) {
return String(value);
}
return normalized.toLocaleString("ko-KR");
};
/**
* ConCostForm
* 호출: (with-layout)/matMng/coMat/coMatRvw
@@ -456,12 +469,16 @@ export default function ConCostForm({
<FormUi label="요구수량(m³/일)">
<Input
placeholder=""
type="number"
step="0.1"
type={isSim ? "number" : "text"}
step={isSim ? "0.1" : undefined}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
value={field.value ?? 0}
value={
isSim
? field.value ?? 0
: formatNumberWithComma(field.value)
}
readOnly={!isSim}
className={!isSim ? readOnlyInputClass : ""}
/>
@@ -524,14 +541,13 @@ export default function ConCostForm({
<FormUi label="처리시설용량(m³/일)">
<Input
placeholder=""
type="number"
step="0.001"
type="text"
onChange={(e) => {
console.log("dmndQty ", e);
//field.onChange(Number(e.target.value) * 365 );
}}
// value={Number(field.value) * 365 || 0}
value={Number(field.value) || 0}
value={formatNumberWithComma(Number(field.value) || 0)}
readOnly
className={readOnlyInputClass}
/>