2025-12-10 15:59:04 +09:00
|
|
|
/**
|
|
|
|
|
* 자동 입력 (Auto-Fill) 커스텀 훅
|
|
|
|
|
* 마스터 선택 시 여러 필드를 자동으로 입력하는 기능
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { useState, useCallback, useEffect } from "react";
|
|
|
|
|
import {
|
|
|
|
|
cascadingAutoFillApi,
|
|
|
|
|
AutoFillGroup,
|
|
|
|
|
AutoFillOption,
|
|
|
|
|
} from "@/lib/api/cascadingAutoFill";
|
|
|
|
|
|
|
|
|
|
interface AutoFillMapping {
|
|
|
|
|
targetField: string;
|
|
|
|
|
targetLabel: string;
|
|
|
|
|
value: any;
|
|
|
|
|
isEditable: boolean;
|
|
|
|
|
isRequired: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface UseAutoFillProps {
|
|
|
|
|
/** 자동 입력 그룹 코드 */
|
|
|
|
|
groupCode: string;
|
|
|
|
|
/** 자동 입력 데이터가 로드되었을 때 호출되는 콜백 */
|
|
|
|
|
onAutoFill?: (data: Record<string, any>, mappings: AutoFillMapping[]) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface UseAutoFillResult {
|
|
|
|
|
/** 마스터 옵션 목록 */
|
|
|
|
|
masterOptions: AutoFillOption[];
|
|
|
|
|
/** 현재 선택된 마스터 값 */
|
|
|
|
|
selectedMasterValue: string | null;
|
|
|
|
|
/** 자동 입력된 데이터 */
|
|
|
|
|
autoFilledData: Record<string, any>;
|
|
|
|
|
/** 매핑 정보 */
|
|
|
|
|
mappings: AutoFillMapping[];
|
|
|
|
|
/** 그룹 정보 */
|
|
|
|
|
groupInfo: AutoFillGroup | null;
|
|
|
|
|
/** 로딩 상태 */
|
|
|
|
|
isLoading: boolean;
|
|
|
|
|
/** 에러 메시지 */
|
|
|
|
|
error: string | null;
|
|
|
|
|
/** 마스터 값 선택 핸들러 */
|
|
|
|
|
selectMasterValue: (value: string) => Promise<void>;
|
|
|
|
|
/** 마스터 옵션 새로고침 */
|
|
|
|
|
refreshOptions: () => Promise<void>;
|
|
|
|
|
/** 자동 입력 데이터 초기화 */
|
|
|
|
|
clearAutoFill: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useAutoFill({
|
|
|
|
|
groupCode,
|
|
|
|
|
onAutoFill,
|
|
|
|
|
}: UseAutoFillProps): UseAutoFillResult {
|
|
|
|
|
// 상태
|
|
|
|
|
const [masterOptions, setMasterOptions] = useState<AutoFillOption[]>([]);
|
|
|
|
|
const [selectedMasterValue, setSelectedMasterValue] = useState<string | null>(null);
|
|
|
|
|
const [autoFilledData, setAutoFilledData] = useState<Record<string, any>>({});
|
|
|
|
|
const [mappings, setMappings] = useState<AutoFillMapping[]>([]);
|
|
|
|
|
const [groupInfo, setGroupInfo] = useState<AutoFillGroup | null>(null);
|
|
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
// 마스터 옵션 로드
|
|
|
|
|
const loadMasterOptions = useCallback(async () => {
|
|
|
|
|
if (!groupCode) return;
|
|
|
|
|
|
|
|
|
|
setIsLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 그룹 정보 로드
|
|
|
|
|
const groupResponse = await cascadingAutoFillApi.getGroupDetail(groupCode);
|
|
|
|
|
if (groupResponse.success && groupResponse.data) {
|
|
|
|
|
setGroupInfo(groupResponse.data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 마스터 옵션 로드
|
|
|
|
|
const optionsResponse = await cascadingAutoFillApi.getMasterOptions(groupCode);
|
|
|
|
|
if (optionsResponse.success && optionsResponse.data) {
|
|
|
|
|
setMasterOptions(optionsResponse.data);
|
|
|
|
|
} else {
|
|
|
|
|
setError(optionsResponse.error || "옵션 로드 실패");
|
|
|
|
|
}
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
setError(err.message || "옵션 로드 중 오류 발생");
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
}
|
|
|
|
|
}, [groupCode]);
|
|
|
|
|
|
|
|
|
|
// 마스터 값 선택 시 자동 입력 데이터 로드
|
|
|
|
|
const selectMasterValue = useCallback(
|
|
|
|
|
async (value: string) => {
|
|
|
|
|
if (!groupCode || !value) {
|
|
|
|
|
setSelectedMasterValue(null);
|
|
|
|
|
setAutoFilledData({});
|
|
|
|
|
setMappings([]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setIsLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
setSelectedMasterValue(value);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const response = await cascadingAutoFillApi.getData(groupCode, value);
|
|
|
|
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
const data = response.data || {};
|
|
|
|
|
const mappingInfo = response.mappings || [];
|
|
|
|
|
|
|
|
|
|
setAutoFilledData(data);
|
|
|
|
|
setMappings(mappingInfo);
|
|
|
|
|
|
|
|
|
|
// 콜백 호출
|
|
|
|
|
if (onAutoFill) {
|
|
|
|
|
onAutoFill(data, mappingInfo);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
setError(response.error || "데이터 로드 실패");
|
|
|
|
|
}
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
setError(err.message || "데이터 로드 중 오류 발생");
|
|
|
|
|
} finally {
|
|
|
|
|
setIsLoading(false);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[groupCode, onAutoFill]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 자동 입력 데이터 초기화
|
|
|
|
|
const clearAutoFill = useCallback(() => {
|
|
|
|
|
setSelectedMasterValue(null);
|
|
|
|
|
setAutoFilledData({});
|
|
|
|
|
setMappings([]);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
// 초기 로드
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (groupCode) {
|
|
|
|
|
loadMasterOptions();
|
|
|
|
|
}
|
|
|
|
|
}, [groupCode, loadMasterOptions]);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
masterOptions,
|
|
|
|
|
selectedMasterValue,
|
|
|
|
|
autoFilledData,
|
|
|
|
|
mappings,
|
|
|
|
|
groupInfo,
|
|
|
|
|
isLoading,
|
|
|
|
|
error,
|
|
|
|
|
selectMasterValue,
|
|
|
|
|
refreshOptions: loadMasterOptions,
|
|
|
|
|
clearAutoFill,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =====================================================
|
|
|
|
|
// 화면관리 시스템용 자동 입력 컴포넌트 설정 타입
|
|
|
|
|
// =====================================================
|
|
|
|
|
|
|
|
|
|
export interface AutoFillConfig {
|
|
|
|
|
/** 자동 입력 활성화 여부 */
|
|
|
|
|
enabled: boolean;
|
|
|
|
|
/** 자동 입력 그룹 코드 */
|
|
|
|
|
groupCode: string;
|
|
|
|
|
/** 마스터 필드명 (이 필드 선택 시 자동 입력 트리거) */
|
|
|
|
|
masterField: string;
|
|
|
|
|
/** 자동 입력 후 수정 가능 여부 (전체 설정) */
|
|
|
|
|
allowEdit?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 폼 데이터에 자동 입력 적용
|
|
|
|
|
*/
|
|
|
|
|
export function applyAutoFillToFormData(
|
|
|
|
|
formData: Record<string, any>,
|
|
|
|
|
autoFilledData: Record<string, any>,
|
|
|
|
|
mappings: AutoFillMapping[]
|
|
|
|
|
): Record<string, any> {
|
|
|
|
|
const result = { ...formData };
|
|
|
|
|
|
|
|
|
|
for (const mapping of mappings) {
|
|
|
|
|
// 수정 불가능한 필드이거나 기존 값이 없는 경우에만 자동 입력
|
|
|
|
|
if (!mapping.isEditable || !result[mapping.targetField]) {
|
|
|
|
|
result[mapping.targetField] = autoFilledData[mapping.targetField];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-12 18:28:58 +09:00
|
|
|
|
2025-12-15 14:51:41 +09:00
|
|
|
|