[as] feat: 증감액, 증감률 서버 데이터 매핑(사업규모, 총사업비, 재원분담)

This commit is contained in:
2026-08-21 11:38:43 +09:00
parent 3333f1c8e6
commit e0715ce177
9 changed files with 59 additions and 54 deletions
@@ -6,7 +6,8 @@ export const FNRS_SHAR_SE_SAVE_MODE = {
DELETE: "D",
} as const;
export type FnrsSharSeSaveMode = (typeof FNRS_SHAR_SE_SAVE_MODE)[keyof typeof FNRS_SHAR_SE_SAVE_MODE];
export type FnrsSharSeSaveMode =
(typeof FNRS_SHAR_SE_SAVE_MODE)[keyof typeof FNRS_SHAR_SE_SAVE_MODE];
/** 백엔드 FnrsSharSeMngResponseDto */
export interface FnrsSharSeMngResponseDto {
@@ -69,6 +70,8 @@ export interface FnrsSharBizCstTreeDto {
ajmtAmt?: number;
rmrkCn?: string;
envoRmrkCn?: string;
chgAmt: number;
chgRt: number;
}
/** Controller public 메서드명·시그니처와 동일 */
@@ -33,10 +33,6 @@ function BusinessScaleSection({ bizSclList }: BusinessScaleSectionProps) {
) : (
bizSclList.map((node) => {
const pl = indentPx(node.indCnstpSeCdNm);
const bscPlanQty = Number(node.bscPlanQty) || 0;
const budgetReflct = Number(node.bgtRfltQty) || 0;
const tstmDesignQty = Number(node.tstmDesignQty) || 0;
const diff = tstmDesignQty - budgetReflct;
return (
<TableRow key={node.cnstpSeCd}>
@@ -44,17 +40,17 @@ function BusinessScaleSection({ bizSclList }: BusinessScaleSectionProps) {
{node.cnstpSeCdNm}
</TableHead>
<TableCell>
<div className="text-right">{fmtNumber(bscPlanQty)}</div>
<div className="text-right">{fmtNumber(node.bscPlanQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.bgtRfltQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(tstmDesignQty)}</div>
<div className="text-right">{fmtNumber(node.tstmDesignQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">
{diff > 0 ? `+${fmtNumber(diff)}` : fmtNumber(diff)}
{node.chgQty > 0 ? `+${fmtNumber(node.chgQty)}` : fmtNumber(node.chgQty)}
</div>
</TableCell>
</TableRow>
@@ -4,7 +4,7 @@ import { useMemo } from "react";
import { SectionCollapsible } from "@/shared/ui";
import type { BizCstTreeDto } from "@/entities/fnrs-cnsltn";
import { calcDiffPercent, fmtNumber, indentPx } from "@/widgets/pbadms-sprt";
import { fmtNumber, indentPx } from "@/widgets/pbadms-sprt";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components";
import { sortBizCstListByTreePath } from "../../lib/business-cost-utils";
@@ -46,10 +46,6 @@ function BusinessCostSection({ bizCstList }: BusinessCostSectionProps) {
) : (
sortedBizCstList.map((node) => {
const pl = indentPx(node.indAcntgSeCdNm);
const bscPlanAmt = Number(node.bscPlanAmt) || 0;
const budgetReflct = Number(node.bgtRfltAmt) || 0;
const tstmDesignAmt = Number(node.tstmDesignAmt) || 0;
const diff = tstmDesignAmt - budgetReflct;
const showSubIcon = node.treeLevel >= 3;
return (
@@ -63,21 +59,21 @@ function BusinessCostSection({ bizCstList }: BusinessCostSectionProps) {
</TableHead>
)}
<TableCell>
<div className="text-right">{fmtNumber(bscPlanAmt)}</div>
<div className="text-right">{fmtNumber(node.bgtRfltAmt)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.bscPlanAmt)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(tstmDesignAmt)}</div>
<div className="text-right">{fmtNumber(node.tstmDesignAmt)}</div>
</TableCell>
<TableCell>
<div className="text-right">
{diff > 0 ? `+${fmtNumber(diff)}` : fmtNumber(diff)}
{node.chgAmt > 0 ? `+${fmtNumber(node.chgAmt)}` : fmtNumber(node.chgAmt)}
</div>
</TableCell>
<TableCell>
<div className="text-right">{calcDiffPercent(diff, budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.chgRt)}%</div>
</TableCell>
</TableRow>
);
@@ -33,10 +33,6 @@ function BusinessScaleSection({ bizSclList }: BusinessScaleSectionProps) {
) : (
bizSclList.map((node) => {
const pl = indentPx(node.indCnstpSeCdNm);
const bscPlanQty = Number(node.bscPlanQty) || 0;
const budgetReflct = Number(node.bgtRfltQty) || 0;
const tstmDesignQty = Number(node.tstmDesignQty) || 0;
const diff = tstmDesignQty - budgetReflct;
return (
<TableRow key={node.cnstpSeCd}>
@@ -44,17 +40,17 @@ function BusinessScaleSection({ bizSclList }: BusinessScaleSectionProps) {
{node.cnstpSeCdNm}
</TableHead>
<TableCell>
<div className="text-right">{fmtNumber(bscPlanQty)}</div>
<div className="text-right">{fmtNumber(node.bscPlanQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.bgtRfltQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(tstmDesignQty)}</div>
<div className="text-right">{fmtNumber(node.tstmDesignQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">
{diff > 0 ? `+${fmtNumber(diff)}` : fmtNumber(diff)}
{node.chgQty > 0 ? `+${fmtNumber(node.chgQty)}` : fmtNumber(node.chgQty)}
</div>
</TableCell>
</TableRow>
@@ -61,8 +61,14 @@ function FnrsSharSection({ fnrsSharList }: FnrsSharSectionProps) {
<TableCell>
<div className="text-right">{fmtNumber(node.chgRqtAmt)}</div>
</TableCell>
<TableCell />
<TableCell />
<TableCell>
<div className="text-right">
{node.chgAmt > 0 ? `+${fmtNumber(node.chgAmt)}` : fmtNumber(node.chgAmt)}
</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(node.chgRt)}%</div>
</TableCell>
<TableCell>{node.rmrkCn ?? ""}</TableCell>
</TableRow>
);
@@ -4,7 +4,7 @@ import { useMemo } from "react";
import { SectionCollapsible } from "@/shared/ui";
import type { BizCstTreeDto } from "@/entities/instl-sncn";
import { calcDiffPercent, fmtNumber, indentPx } from "@/widgets/pbadms-sprt";
import { fmtNumber, indentPx } from "@/widgets/pbadms-sprt";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components";
import { sortBizCstListByTreePath } from "../../lib/business-cost-utils";
@@ -46,10 +46,6 @@ function BusinessCostSection({ bizCstList }: BusinessCostSectionProps) {
) : (
sortedBizCstList.map((node) => {
const pl = indentPx(node.indAcntgSeCdNm);
const bscPlanAmt = Number(node.bscPlanAmt) || 0;
const budgetReflct = Number(node.bgtRfltAmt) || 0;
const tstmDesignAmt = Number(node.tstmDesignAmt) || 0;
const diff = tstmDesignAmt - budgetReflct;
const showSubIcon = node.treeLevel >= 3;
return (
@@ -63,21 +59,21 @@ function BusinessCostSection({ bizCstList }: BusinessCostSectionProps) {
</TableHead>
)}
<TableCell>
<div className="text-right">{fmtNumber(bscPlanAmt)}</div>
<div className="text-right">{fmtNumber(node.bgtRfltAmt)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.bscPlanAmt)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(tstmDesignAmt)}</div>
<div className="text-right">{fmtNumber(node.tstmDesignAmt)}</div>
</TableCell>
<TableCell>
<div className="text-right">
{diff > 0 ? `+${fmtNumber(diff)}` : fmtNumber(diff)}
{node.chgAmt > 0 ? `+${fmtNumber(node.chgAmt)}` : fmtNumber(node.chgAmt)}
</div>
</TableCell>
<TableCell>
<div className="text-right">{calcDiffPercent(diff, budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.chgRt)}%</div>
</TableCell>
</TableRow>
);
@@ -33,10 +33,6 @@ function BusinessScaleSection({ bizSclList }: BusinessScaleSectionProps) {
) : (
bizSclList.map((node) => {
const pl = indentPx(node.indCnstpSeCdNm);
const bscPlanQty = Number(node.bscPlanQty) || 0;
const budgetReflct = Number(node.bgtRfltQty) || 0;
const tstmDesignQty = Number(node.tstmDesignQty) || 0;
const diff = tstmDesignQty - budgetReflct;
return (
<TableRow key={node.cnstpSeCd}>
@@ -44,17 +40,17 @@ function BusinessScaleSection({ bizSclList }: BusinessScaleSectionProps) {
{node.cnstpSeCdNm}
</TableHead>
<TableCell>
<div className="text-right">{fmtNumber(bscPlanQty)}</div>
<div className="text-right">{fmtNumber(node.bscPlanQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(budgetReflct)}</div>
<div className="text-right">{fmtNumber(node.bgtRfltQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">{fmtNumber(tstmDesignQty)}</div>
<div className="text-right">{fmtNumber(node.tstmDesignQty)}</div>
</TableCell>
<TableCell>
<div className="text-right">
{diff > 0 ? `+${fmtNumber(diff)}` : fmtNumber(diff)}
{node.chgQty > 0 ? `+${fmtNumber(node.chgQty)}` : fmtNumber(node.chgQty)}
</div>
</TableCell>
</TableRow>
+12 -4
View File
@@ -28,6 +28,10 @@ export interface BizSclTreeDto {
bgtRfltQty: number;
/** 금회설계수량 */
tstmDesignQty: number;
/** 증감수량(금회설계수량 - 예산반영수량, C-B) */
chgQty: number;
/** 증감율 % ((증감수량 / 기본계획수량) * 100) */
chgRt: number;
}
/** 회계구분 트리와 사업비용 조합 DTO */
@@ -44,12 +48,16 @@ export interface BizCstTreeDto {
treeLevel: number;
/** 트리 경로 표시용 문자열 */
treePath: string;
/** 기본계획금액 */
bscPlanAmt: number;
/** 예산반영금액 */
/** 예산반영금액(A) */
bgtRfltAmt: number;
/** 금회설계금액 */
/** 표준사업비(B) */
bscPlanAmt: number;
/** 금회설계금액(C) */
tstmDesignAmt: number;
/** 증감금액(금회설계금액 - 표준사업비, C-B) */
chgAmt: number;
/** 증감율 % ((증감금액 / 표준사업비) * 100) */
chgRt: number;
}
/** 점검표 검토결과 트리 DTO */
@@ -1,6 +1,14 @@
export function fmtNumber(value: number | null | undefined): string {
if (typeof value === "number") return value.toLocaleString();
if (value === null || value === undefined) return "";
export function fmtNumber(value: number | string | null | undefined): string {
if (typeof value === "number") {
return value.toLocaleString();
}
if (value === null || value === undefined) {
return "";
}
const num = Number(value);
if (!isNaN(num)) {
return num.toLocaleString();
}
return String(value);
}