283 lines
6.3 KiB
TypeScript
283 lines
6.3 KiB
TypeScript
|
|
/**
|
||
|
|
* 품목기준관리 타입 정의
|
||
|
|
*
|
||
|
|
* 동적 페이지 구성, 버전 관리, 멀티테넌시 지원
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { ItemType } from './item';
|
||
|
|
|
||
|
|
// ===== 페이지 타입 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지 유형
|
||
|
|
* - item-master: 품목기준정보
|
||
|
|
* - quotation: 견적
|
||
|
|
* - sales-order: 수주
|
||
|
|
* - formula: 계산식
|
||
|
|
* - pricing: 단가
|
||
|
|
*/
|
||
|
|
export type PageType = 'item-master' | 'quotation' | 'sales-order' | 'formula' | 'pricing';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필드 입력 타입
|
||
|
|
*/
|
||
|
|
export type FieldInputType =
|
||
|
|
| 'textbox'
|
||
|
|
| 'dropdown'
|
||
|
|
| 'checkbox'
|
||
|
|
| 'number'
|
||
|
|
| 'date'
|
||
|
|
| 'textarea'
|
||
|
|
| 'file'
|
||
|
|
| 'multi-column';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 섹션 타입
|
||
|
|
*/
|
||
|
|
export type SectionType = 'fields' | 'bom' | 'table';
|
||
|
|
|
||
|
|
// ===== 필드 설정 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필드 표시 조건
|
||
|
|
*/
|
||
|
|
export interface FieldDisplayCondition {
|
||
|
|
dependsOn: string; // 의존하는 필드 키
|
||
|
|
showWhen?: string | string[]; // 표시 조건 값
|
||
|
|
hideWhen?: string | string[]; // 숨김 조건 값
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필드 유효성 검사 규칙
|
||
|
|
*/
|
||
|
|
export interface FieldValidationRule {
|
||
|
|
type: 'required' | 'min' | 'max' | 'pattern' | 'custom';
|
||
|
|
value?: any;
|
||
|
|
message: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필드 속성
|
||
|
|
*/
|
||
|
|
export interface FieldProperty {
|
||
|
|
inputType: FieldInputType;
|
||
|
|
required: boolean;
|
||
|
|
row: number; // 그리드 행 번호
|
||
|
|
col: number; // 그리드 열 번호
|
||
|
|
options?: string[]; // 드롭다운 옵션
|
||
|
|
defaultValue?: any;
|
||
|
|
placeholder?: string;
|
||
|
|
|
||
|
|
// 멀티컬럼 필드 관련
|
||
|
|
multiColumn?: boolean;
|
||
|
|
columnCount?: number;
|
||
|
|
columnNames?: string[];
|
||
|
|
|
||
|
|
// 유효성 검사
|
||
|
|
validation?: FieldValidationRule[];
|
||
|
|
|
||
|
|
// 표시 조건
|
||
|
|
displayCondition?: FieldDisplayCondition;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필드 정의
|
||
|
|
*/
|
||
|
|
export interface FieldConfig {
|
||
|
|
id: string;
|
||
|
|
name: string; // 필드 라벨
|
||
|
|
fieldKey: string; // 데이터 키
|
||
|
|
property: FieldProperty;
|
||
|
|
helpText?: string; // 도움말 텍스트
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 섹션 설정 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 섹션 정의
|
||
|
|
*/
|
||
|
|
export interface SectionConfig {
|
||
|
|
id: string;
|
||
|
|
title: string; // 섹션 제목
|
||
|
|
description?: string;
|
||
|
|
type: SectionType;
|
||
|
|
fields: FieldConfig[];
|
||
|
|
order: number; // 섹션 순서
|
||
|
|
isCollapsible: boolean; // 접기/펼치기 가능 여부
|
||
|
|
isCollapsed: boolean; // 기본 접힘 상태
|
||
|
|
|
||
|
|
// 조건부 표시
|
||
|
|
category?: string[]; // 특정 카테고리에서만 표시
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 페이지 설정 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지 구성 정보
|
||
|
|
*/
|
||
|
|
export interface PageConfig {
|
||
|
|
id: string;
|
||
|
|
pageName: string; // 페이지명
|
||
|
|
pageType: PageType; // 페이지 유형
|
||
|
|
itemType?: ItemType; // 연결된 품목 유형 (optional)
|
||
|
|
sections: SectionConfig[]; // 섹션 목록
|
||
|
|
isActive: boolean; // 사용 여부
|
||
|
|
|
||
|
|
// 버전 관리
|
||
|
|
version: number; // 현재 버전
|
||
|
|
isFinal: boolean; // 최종 확정 여부
|
||
|
|
|
||
|
|
// 멀티테넌시
|
||
|
|
tenantId: string; // 테넌트 ID
|
||
|
|
|
||
|
|
// 메타데이터
|
||
|
|
createdAt: string;
|
||
|
|
updatedAt: string;
|
||
|
|
createdBy: string;
|
||
|
|
updatedBy?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 버전 관리 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지 구성 변경 이력
|
||
|
|
*/
|
||
|
|
export interface PageConfigRevision {
|
||
|
|
id: string;
|
||
|
|
pageConfigId: string;
|
||
|
|
version: number; // 버전 번호
|
||
|
|
previousVersion: number; // 이전 버전
|
||
|
|
changes: PageConfigChange[]; // 변경 내역
|
||
|
|
snapshot: PageConfig; // 전체 스냅샷
|
||
|
|
|
||
|
|
// 변경 정보
|
||
|
|
changedAt: string;
|
||
|
|
changedBy: string;
|
||
|
|
changeReason?: string;
|
||
|
|
|
||
|
|
// 승인 정보
|
||
|
|
isApproved: boolean;
|
||
|
|
approvedAt?: string;
|
||
|
|
approvedBy?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지 구성 변경 상세
|
||
|
|
*/
|
||
|
|
export interface PageConfigChange {
|
||
|
|
type: 'field_added' | 'field_removed' | 'field_modified' | 'section_added' | 'section_removed' | 'section_modified';
|
||
|
|
targetId: string; // 변경된 필드/섹션 ID
|
||
|
|
fieldName?: string; // 변경된 항목명
|
||
|
|
oldValue?: any;
|
||
|
|
newValue?: any;
|
||
|
|
description: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 데이터 입력 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 동적 폼 데이터
|
||
|
|
*/
|
||
|
|
export interface DynamicFormData {
|
||
|
|
id?: string;
|
||
|
|
pageConfigId: string;
|
||
|
|
pageType: PageType;
|
||
|
|
tenantId: string;
|
||
|
|
|
||
|
|
// 동적 필드 데이터 (key-value)
|
||
|
|
fieldData: Record<string, any>;
|
||
|
|
|
||
|
|
// 버전 관리
|
||
|
|
version: number;
|
||
|
|
isFinal: boolean;
|
||
|
|
|
||
|
|
// 메타데이터
|
||
|
|
createdAt?: string;
|
||
|
|
updatedAt?: string;
|
||
|
|
createdBy?: string;
|
||
|
|
updatedBy?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== API 응답 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* API 응답 기본 구조
|
||
|
|
*/
|
||
|
|
export interface MasterDataApiResponse<T> {
|
||
|
|
success: boolean;
|
||
|
|
data: T;
|
||
|
|
message?: string;
|
||
|
|
errors?: Record<string, string[]>;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지네이션 응답
|
||
|
|
*/
|
||
|
|
export interface MasterDataPaginatedResponse<T> {
|
||
|
|
data: T[];
|
||
|
|
current_page: number;
|
||
|
|
last_page: number;
|
||
|
|
per_page: number;
|
||
|
|
total: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지 구성 조회 파라미터
|
||
|
|
*/
|
||
|
|
export interface FetchPageConfigParams {
|
||
|
|
pageType?: PageType;
|
||
|
|
itemType?: ItemType;
|
||
|
|
isActive?: boolean;
|
||
|
|
version?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 버전 비교 결과
|
||
|
|
*/
|
||
|
|
export interface VersionComparisonResult {
|
||
|
|
version1: number;
|
||
|
|
version2: number;
|
||
|
|
changes: PageConfigChange[];
|
||
|
|
addedFields: FieldConfig[];
|
||
|
|
removedFields: FieldConfig[];
|
||
|
|
modifiedFields: Array<{
|
||
|
|
field: FieldConfig;
|
||
|
|
changes: Record<string, { old: any; new: any }>;
|
||
|
|
}>;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ===== 유틸리티 타입 =====
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 페이지 타입 라벨
|
||
|
|
*/
|
||
|
|
export const PAGE_TYPE_LABELS: Record<PageType, string> = {
|
||
|
|
'item-master': '품목기준정보',
|
||
|
|
'quotation': '견적',
|
||
|
|
'sales-order': '수주',
|
||
|
|
'formula': '계산식',
|
||
|
|
'pricing': '단가',
|
||
|
|
} as const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 섹션 타입 라벨
|
||
|
|
*/
|
||
|
|
export const SECTION_TYPE_LABELS: Record<SectionType, string> = {
|
||
|
|
'fields': '입력 필드',
|
||
|
|
'bom': '부품구성표',
|
||
|
|
'table': '테이블',
|
||
|
|
} as const;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필드 입력 타입 라벨
|
||
|
|
*/
|
||
|
|
export const FIELD_INPUT_TYPE_LABELS: Record<FieldInputType, string> = {
|
||
|
|
'textbox': '텍스트 입력',
|
||
|
|
'dropdown': '드롭다운',
|
||
|
|
'checkbox': '체크박스',
|
||
|
|
'number': '숫자 입력',
|
||
|
|
'date': '날짜',
|
||
|
|
'textarea': '텍스트 영역',
|
||
|
|
'file': '파일',
|
||
|
|
'multi-column': '다중 컬럼',
|
||
|
|
} as const;
|