feat: EditModal에서 채번 규칙 할당 로직 병렬 처리 최적화
- allocateCode 호출 시 Promise.all을 사용하여 여러 채번 필드를 병렬로 처리하도록 개선하였습니다. - 채번 규칙 할당 실패 시 사용자에게 명확한 오류 메시지를 제공하도록 로깅을 강화하였습니다. - 코드 할당 결과를 보다 효율적으로 처리하여 성능을 향상시켰습니다.
This commit is contained in:
parent
77fcf1a35a
commit
d28e703cd2
|
|
@ -767,46 +767,51 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
|||
}
|
||||
}
|
||||
|
||||
// 채번 규칙이 있는 필드에 대해 allocateCode 호출
|
||||
// 채번 규칙이 있는 필드에 대해 allocateCode 호출 (🚀 병렬 처리로 최적화)
|
||||
if (Object.keys(fieldsWithNumbering).length > 0) {
|
||||
console.log("🎯 [EditModal] 채번 규칙 할당 시작, formData:", {
|
||||
material: formData.material, // 재질 값 로깅
|
||||
material: formData.material,
|
||||
allKeys: Object.keys(formData),
|
||||
});
|
||||
const { allocateNumberingCode } = await import("@/lib/api/numberingRule");
|
||||
|
||||
let hasAllocationFailure = false;
|
||||
const failedFields: string[] = [];
|
||||
|
||||
for (const [fieldName, ruleId] of Object.entries(fieldsWithNumbering)) {
|
||||
try {
|
||||
// 🆕 사용자가 편집한 값을 전달 (수동 입력 부분 추출용)
|
||||
// 🚀 Promise.all로 병렬 처리 (여러 채번 필드가 있을 경우 성능 향상)
|
||||
const allocationPromises = Object.entries(fieldsWithNumbering).map(
|
||||
async ([fieldName, ruleId]) => {
|
||||
const userInputCode = dataToSave[fieldName] as string;
|
||||
console.log(`🔄 [EditModal] ${fieldName} 필드에 대해 allocateCode 호출: ${ruleId}, 사용자입력: ${userInputCode}`);
|
||||
const allocateResult = await allocateNumberingCode(ruleId, userInputCode, formData);
|
||||
|
||||
if (allocateResult.success && allocateResult.data?.generatedCode) {
|
||||
const newCode = allocateResult.data.generatedCode;
|
||||
console.log(`✅ [EditModal] ${fieldName} 새 코드 할당: ${userInputCode} → ${newCode}`);
|
||||
dataToSave[fieldName] = newCode;
|
||||
} else {
|
||||
console.warn(`⚠️ [EditModal] ${fieldName} 코드 할당 실패:`, allocateResult.error);
|
||||
if (!dataToSave[fieldName] || dataToSave[fieldName] === "") {
|
||||
hasAllocationFailure = true;
|
||||
failedFields.push(fieldName);
|
||||
console.log(`🔄 [EditModal] ${fieldName} 필드에 대해 allocateCode 호출: ${ruleId}`);
|
||||
|
||||
try {
|
||||
const allocateResult = await allocateNumberingCode(ruleId, userInputCode, formData);
|
||||
|
||||
if (allocateResult.success && allocateResult.data?.generatedCode) {
|
||||
return { fieldName, success: true, code: allocateResult.data.generatedCode };
|
||||
} else {
|
||||
console.warn(`⚠️ [EditModal] ${fieldName} 코드 할당 실패:`, allocateResult.error);
|
||||
return { fieldName, success: false, hasExistingValue: !!(dataToSave[fieldName]) };
|
||||
}
|
||||
} catch (allocateError) {
|
||||
console.error(`❌ [EditModal] ${fieldName} 코드 할당 오류:`, allocateError);
|
||||
return { fieldName, success: false, hasExistingValue: !!(dataToSave[fieldName]) };
|
||||
}
|
||||
} catch (allocateError) {
|
||||
console.error(`❌ [EditModal] ${fieldName} 코드 할당 오류:`, allocateError);
|
||||
if (!dataToSave[fieldName] || dataToSave[fieldName] === "") {
|
||||
hasAllocationFailure = true;
|
||||
failedFields.push(fieldName);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const allocationResults = await Promise.all(allocationPromises);
|
||||
|
||||
// 결과 처리
|
||||
const failedFields: string[] = [];
|
||||
for (const result of allocationResults) {
|
||||
if (result.success && result.code) {
|
||||
console.log(`✅ [EditModal] ${result.fieldName} 새 코드 할당: ${result.code}`);
|
||||
dataToSave[result.fieldName] = result.code;
|
||||
} else if (!result.hasExistingValue) {
|
||||
failedFields.push(result.fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
// 채번 규칙 할당 실패 시 저장 중단
|
||||
if (hasAllocationFailure) {
|
||||
if (failedFields.length > 0) {
|
||||
const fieldNames = failedFields.join(", ");
|
||||
toast.error(`채번 규칙 할당에 실패했습니다 (${fieldNames}). 화면 설정에서 채번 규칙을 확인해주세요.`);
|
||||
console.error(`❌ [EditModal] 채번 규칙 할당 실패로 저장 중단. 실패 필드: ${fieldNames}`);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useMemo, useRef } from "react";
|
||||
import { ConditionalConfig, CascadingConfig } from "@/types/v2-components";
|
||||
import { ConditionalConfig, CascadingConfig, LayerConfig, LayerCondition } from "@/types/v2-components";
|
||||
import { ValidationRule } from "@/types/v2-core";
|
||||
import type {
|
||||
FormStatus,
|
||||
|
|
@ -89,6 +89,12 @@ export interface V2FormContextValue {
|
|||
addRepeaterRow: (fieldName: string, row: Record<string, unknown>) => void;
|
||||
updateRepeaterRow: (fieldName: string, index: number, row: Record<string, unknown>) => void;
|
||||
deleteRepeaterRow: (fieldName: string, index: number) => void;
|
||||
|
||||
// 조건부 레이어 시스템
|
||||
layers: LayerConfig[];
|
||||
setLayers: (layers: LayerConfig[]) => void;
|
||||
evaluateLayer: (layer: LayerConfig) => boolean;
|
||||
isComponentVisible: (componentId: string) => boolean;
|
||||
}
|
||||
|
||||
// ===== Context 생성 =====
|
||||
|
|
|
|||
|
|
@ -544,3 +544,28 @@ export const LEGACY_TO_V2_MAP: Record<string, V2ComponentType> = {
|
|||
// Button (Input의 버튼 모드)
|
||||
"button-primary": "V2Input",
|
||||
};
|
||||
|
||||
// ===== 조건부 레이어 시스템 =====
|
||||
|
||||
/**
|
||||
* 레이어 조건 설정
|
||||
* 특정 필드값에 따라 레이어 활성화 여부를 결정
|
||||
*/
|
||||
export interface LayerCondition {
|
||||
field: string; // 트리거 필드 (columnName 또는 탭ID)
|
||||
operator: "=" | "!=" | "in" | "notIn" | "isEmpty" | "isNotEmpty";
|
||||
value: string | string[]; // 비교값
|
||||
}
|
||||
|
||||
/**
|
||||
* 레이어 설정
|
||||
* 특정 조건이 충족될 때 표시되는 컴포넌트들의 그룹
|
||||
*/
|
||||
export interface LayerConfig {
|
||||
layerId: string; // 고유 ID
|
||||
layerName: string; // 표시명 (설정용)
|
||||
conditions: LayerCondition[]; // 조건 목록
|
||||
conditionLogic?: "AND" | "OR"; // 조건 조합 방식 (기본: AND)
|
||||
targetComponents: string[]; // 표시할 컴포넌트 ID 목록
|
||||
alwaysVisible?: boolean; // 항상 표시 (조건 무시)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue