필터 기본값 수정

This commit is contained in:
2025-12-15 18:47:26 +09:00
parent c2b81c19c5
commit 3d022a1305
6 changed files with 28 additions and 87 deletions

View File

@@ -1,61 +0,0 @@
/**
* 소 용도 분류 설정
*
* @description
* 소의 용도를 결정하는 비즈니스 로직 임계값 정의
* - 도태 (Culling): 낮은 수태율, 번식 능력 부족
* - 인공수정 (Artificial Insemination): 높은 수태율 + 우수 등급
* - 공란우 (Donor): 중간 수태율 + 우수 등급
* - 수란우 (Recipient): 높은 수태율 + 낮은 등급
*/
export const COW_PURPOSE_CONFIG = {
/**
* 수태율 기반 임계값 (%)
*/
CONCEPTION_RATE_THRESHOLDS: {
/**
* 도태 대상 최대 수태율 (30% 미만)
* 수태율이 이 값보다 낮으면 번식 능력이 부족하여 도태 대상
*/
CULLING_MAX: 30,
/**
* 공란우 최대 수태율 (50% 미만)
* 수태율이 낮지만 우수한 유전자 보유 시 수정란 공급
*/
DONOR_MAX: 50,
/**
* 수란우 최소 수태율 (65% 이상)
* 높은 수태율을 가진 소에게 우수 수정란 이식
*/
RECIPIENT_MIN: 65,
/**
* 인공수정 최소 수태율 (65% 이상)
* 높은 수태율 + 우수 등급 → 일반 인공수정 대상
*/
INSEMINATION_MIN: 65,
},
/**
* 나이 기반 임계값 (년)
*/
AGE_THRESHOLDS: {
/**
* 노령우 기준 (10년 이상)
* 이 나이 이상이면 도태 고려 대상
*/
OLD_AGE_YEARS: 10,
/**
* 번식 적정 최소 나이 (2년)
*/
BREEDING_MIN_AGE: 2,
/**
* 번식 적정 최대 나이 (8년)
*/
BREEDING_MAX_AGE: 8,
},
} as const;

View File

@@ -1810,8 +1810,8 @@ export class GenomeService {
];
// inputTraitConditions가 있으면 사용, 없으면 35개 형질 기본값 사용
const traitConditions = inputTraitConditions && inputTraitConditions.length > 0
? inputTraitConditions
: ALL_TRAITS.map(traitNm => ({ traitNm, weight: 1 }));
? inputTraitConditions // 프론트에서 보낸 형질사용
: ALL_TRAITS.map(traitNm => ({ traitNm, weight: 1 })); // 기본값 사용
console.log('[getFarmRegionRanking] traitConditions:', traitConditions.length, 'traits');

View File

@@ -10,7 +10,7 @@ import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog"
import { Badge } from "@/components/ui/badge"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { useToast } from "@/hooks/use-toast"
import { ComparisonAveragesDto, TraitComparisonAveragesDto, cowApi, genomeApi, geneApi, GeneDetail, GenomeRequestDto } from "@/lib/api"
import { ComparisonAveragesDto, TraitComparisonAveragesDto, cowApi, genomeApi, geneApi, GeneDetail, GenomeRequestDto, mptApi, MptDto } from "@/lib/api"
import { CowDetail } from "@/types/cow.types"
import { GenomeTrait } from "@/types/genome.types"
import { useGlobalFilter } from "@/contexts/GlobalFilterContext"
@@ -35,6 +35,7 @@ import { TraitComparison } from "./genome/_components/genome-integrated-comparis
import { CowNumberDisplay } from "@/components/common/cow-number-display"
import { isValidGenomeAnalysis, getInvalidReason, getInvalidMessage } from "@/lib/utils/genome-analysis-config"
import { AuthGuard } from "@/components/auth/auth-guard"
import { MptTable } from "./reproduction/_components/mpt-table"
// 형질명 → 카테고리 매핑 (한우 35개 형질)
const TRAIT_CATEGORY_MAP: Record<string, string> = {
@@ -628,7 +629,7 @@ export default function CowOverviewPage() {
</Card>
{/* 친자확인 섹션 */}
<h3 className="text-lg lg:text-xl font-bold text-foreground"> </h3>
<h3 className="text-lg lg:text-xl font-bold text-foreground"></h3>
<Card className="bg-white border border-border shadow-sm rounded-2xl overflow-hidden">
<CardContent className="p-0">
@@ -997,7 +998,7 @@ export default function CowOverviewPage() {
</Card>
{/* 친자확인 섹션 */}
<h3 className="text-lg lg:text-xl font-bold text-foreground"> </h3>
<h3 className="text-lg lg:text-xl font-bold text-foreground"></h3>
<Card className="bg-white border border-border shadow-sm rounded-2xl overflow-hidden">
<CardContent className="p-0">
@@ -1258,7 +1259,7 @@ export default function CowOverviewPage() {
</Card>
{/* 친자확인 결과 섹션 (유전체 탭과 동일) */}
<h3 className="text-lg lg:text-xl font-bold text-foreground"> </h3>
<h3 className="text-lg lg:text-xl font-bold text-foreground"></h3>
<Card className="bg-white border border-border shadow-sm rounded-2xl overflow-hidden">
<CardContent className="p-0">
@@ -1674,11 +1675,15 @@ export default function CowOverviewPage() {
)}
</TabsContent>
{/* 번식능력 탭 */}
<TabsContent value="reproduction" className="mt-6 space-y-6">
{/* 혈액화학검사(MPT) 테이블 */}
<MptTable cowShortNo={cowNo?.slice(-4)} cowNo={cowNo} farmNo={cow?.fkFarmNo} cow={cow} genomeRequest={genomeRequest} />
{/* TODO: 번식능력 분석 결과 (추후 사용)
{hasReproductionData ? (
<div>
{/* TODO: 번식능력 분석 결과 표시 */}
<h3 className="text-lg lg:text-xl font-bold text-foreground">번식능력 분석 결과</h3>
</div>
) : (
@@ -1692,6 +1697,7 @@ export default function CowOverviewPage() {
</CardContent>
</Card>
)}
*/}
</TabsContent>
</Tabs>
</div>

View File

@@ -716,7 +716,7 @@ function MyCowContent() {
>
<span className="flex items-center justify-center gap-1.5 max-sm:gap-1">
<span className="w-2 h-2 rounded-full bg-slate-400"></span>
<span className="font-bold">{cows.filter(c => c.genomeScore === undefined || c.genomeScore === null).length}</span>
<span className="font-bold">{cows.filter(c => c.genomeScore === undefined || c.genomeScore === null).length}</span>
</span>
</button>
</div>

View File

@@ -504,13 +504,7 @@ export function GlobalFilterDialog({ externalOpen, onExternalOpenChange, geneCou
className="h-8 md:h-9 text-xs md:text-base font-semibold px-2 md:px-3 relative"
>
<Settings2 className="h-3 w-3 md:h-4 md:w-4 mr-1 md:mr-1.5" />
<span></span>
<Badge
variant={(geneCount > 0 || traitCount > 0) ? "default" : "outline"}
className={`ml-1.5 text-[9px] md:text-xs px-1.5 py-0 ${(geneCount > 0 || traitCount > 0) ? "bg-white text-primary" : "text-muted-foreground"}`}
>
{(geneCount > 0 || traitCount > 0) ? "활성" : "비활성"}
</Badge>
<span> ({traitCount})</span>
</Button>
</SheetTrigger>

View File

@@ -112,9 +112,10 @@ export interface GlobalFilterSettings {
}
/**
* ====================================================================================================
* 기본 필터 초기값 설정
* 사용자가 해당 형질 선택하지 않았을때 필터의 초기 값 0 세팅
*
* ====================================================================================================
* const [filterSettings, setFilterSettings] = useState(DEFAULT_FILTER_SETTINGS);
* function resetFilter() {
setFilterSettings(DEFAULT_FILTER_SETTINGS); // 초기화
@@ -134,22 +135,22 @@ export const DEFAULT_FILTER_SETTINGS: GlobalFilterSettings = {
"12개월령체중": 0,
// 경제형질 (점수: 0 ~ 10)
도체중: 0,
등심단면적: 0,
등지방두께: 0,
근내지방도: 0,
도체중: 1,
등심단면적: 1,
등지방두께: 1,
근내지방도: 1,
// 체형형질 (점수: 0 ~ 10) - DB 형질명과 일치
체고: 0,
체고: 1,
십자: 0,
체장: 0,
체장: 1,
흉심: 0,
흉폭: 0,
고장: 0,
요각폭: 0,
좌골폭: 0,
곤폭: 0,
흉위: 0,
흉위: 1,
// 부위별무게 (점수: 0 ~ 10) - DB 형질명과 일치
안심weight: 0,
@@ -177,6 +178,7 @@ export const DEFAULT_FILTER_SETTINGS: GlobalFilterSettings = {
},
inbreedingThreshold: 0, // 근친도 기본값 0
isActive: true, // 기본 7개 형질이 선택되어 있으므로 활성화
// 기본 각각 1점으로 세팅
updtDt: new Date(),
};