feat: 채번규칙 editable 옵션 수동 모드 감지 기능 구현
모달 오픈 시 채번 미리보기 원본값 저장 (numberingOriginalValues) handleFieldChange에서 원본값 비교하여 수동/자동 모드 전환 사용자 수정 시 ruleId 제거하여 저장 시 채번 스킵 원본값 복구 시 ruleId 복구하여 자동 모드 복원 handleSave에서 채번 할당 조건 분기 처리
This commit is contained in:
parent
b3ee2b50e8
commit
40fd5f9055
|
|
@ -197,6 +197,10 @@ export function UniversalFormModalComponent({
|
|||
// 로딩 상태
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
// 채번규칙 원본 값 추적 (수동 모드 감지용)
|
||||
// key: columnName, value: 자동 생성된 원본 값
|
||||
const [numberingOriginalValues, setNumberingOriginalValues] = useState<Record<string, string>>({});
|
||||
|
||||
// 🆕 수정 모드: 원본 그룹 데이터 (INSERT/UPDATE/DELETE 추적용)
|
||||
const [originalGroupedData, setOriginalGroupedData] = useState<any[]>([]);
|
||||
const groupedDataInitializedRef = useRef(false);
|
||||
|
|
@ -457,16 +461,23 @@ export function UniversalFormModalComponent({
|
|||
// generateOnOpen: 미리보기만 표시 (DB 시퀀스 증가 안 함)
|
||||
const response = await previewNumberingCode(field.numberingRule.ruleId);
|
||||
if (response.success && response.data?.generatedCode) {
|
||||
updatedData[field.columnName] = response.data.generatedCode;
|
||||
const generatedCode = response.data.generatedCode;
|
||||
updatedData[field.columnName] = generatedCode;
|
||||
|
||||
// 저장 시 실제 할당을 위해 ruleId 저장 (TextInput과 동일한 키 형식)
|
||||
const ruleIdKey = `${field.columnName}_numberingRuleId`;
|
||||
updatedData[ruleIdKey] = field.numberingRule.ruleId;
|
||||
|
||||
// 원본 채번 값 저장 (수동 모드 감지용)
|
||||
setNumberingOriginalValues((prev) => ({
|
||||
...prev,
|
||||
[field.columnName]: generatedCode,
|
||||
}));
|
||||
|
||||
hasChanges = true;
|
||||
numberingGeneratedRef.current = true; // 생성 완료 표시
|
||||
console.log(
|
||||
`[채번 미리보기 완료] ${field.columnName} = ${response.data.generatedCode} (저장 시 실제 할당)`,
|
||||
`[채번 미리보기 완료] ${field.columnName} = ${generatedCode} (저장 시 실제 할당)`,
|
||||
);
|
||||
console.log(`[채번 규칙 ID 저장] ${ruleIdKey} = ${field.numberingRule.ruleId}`);
|
||||
|
||||
|
|
@ -694,8 +705,46 @@ export function UniversalFormModalComponent({
|
|||
// 필드 값 변경 핸들러
|
||||
const handleFieldChange = useCallback(
|
||||
(columnName: string, value: any) => {
|
||||
// 채번규칙 필드의 수동 모드 감지
|
||||
const originalNumberingValue = numberingOriginalValues[columnName];
|
||||
const ruleIdKey = `${columnName}_numberingRuleId`;
|
||||
|
||||
// 해당 필드의 채번규칙 설정 찾기
|
||||
let fieldConfig: FormFieldConfig | undefined;
|
||||
for (const section of config.sections) {
|
||||
if (section.type === "table" || section.repeatable) continue;
|
||||
fieldConfig = section.fields?.find((f) => f.columnName === columnName);
|
||||
if (fieldConfig) break;
|
||||
// 옵셔널 필드 그룹에서도 찾기
|
||||
for (const group of section.optionalFieldGroups || []) {
|
||||
fieldConfig = group.fields?.find((f) => f.columnName === columnName);
|
||||
if (fieldConfig) break;
|
||||
}
|
||||
if (fieldConfig) break;
|
||||
}
|
||||
|
||||
setFormData((prev) => {
|
||||
const newData = { ...prev, [columnName]: value };
|
||||
|
||||
// 채번규칙이 활성화된 필드이고, "사용자 수정 가능"이 ON인 경우
|
||||
if (
|
||||
fieldConfig?.numberingRule?.enabled &&
|
||||
fieldConfig?.numberingRule?.editable &&
|
||||
originalNumberingValue
|
||||
) {
|
||||
// 사용자가 값을 수정했으면 (원본과 다르면) ruleId 제거 → 수동 모드
|
||||
if (value !== originalNumberingValue) {
|
||||
delete newData[ruleIdKey];
|
||||
console.log(`[채번 수동 모드] ${columnName}: 사용자가 값 수정 → ruleId 제거`);
|
||||
} else {
|
||||
// 원본 값으로 복구하면 ruleId 복구 → 자동 모드
|
||||
if (fieldConfig.numberingRule.ruleId) {
|
||||
newData[ruleIdKey] = fieldConfig.numberingRule.ruleId;
|
||||
console.log(`[채번 자동 모드] ${columnName}: 원본 값 복구 → ruleId 복구`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// onChange는 렌더링 외부에서 호출해야 함 (setTimeout 사용)
|
||||
if (onChange) {
|
||||
setTimeout(() => onChange(newData), 0);
|
||||
|
|
@ -703,7 +752,7 @@ export function UniversalFormModalComponent({
|
|||
return newData;
|
||||
});
|
||||
},
|
||||
[onChange],
|
||||
[onChange, numberingOriginalValues, config.sections],
|
||||
);
|
||||
|
||||
// 반복 섹션 필드 값 변경 핸들러
|
||||
|
|
@ -975,19 +1024,45 @@ export function UniversalFormModalComponent({
|
|||
}
|
||||
});
|
||||
|
||||
// 저장 시점 채번규칙 처리 (generateOnSave만 처리)
|
||||
// 저장 시점 채번규칙 처리
|
||||
for (const section of config.sections) {
|
||||
// 테이블 타입 섹션은 건너뛰기
|
||||
if (section.type === "table") continue;
|
||||
|
||||
for (const field of (section.fields || [])) {
|
||||
if (field.numberingRule?.enabled && field.numberingRule?.generateOnSave && field.numberingRule?.ruleId) {
|
||||
const response = await allocateNumberingCode(field.numberingRule.ruleId);
|
||||
if (response.success && response.data?.generatedCode) {
|
||||
dataToSave[field.columnName] = response.data.generatedCode;
|
||||
console.log(`[채번 할당] ${field.columnName} = ${response.data.generatedCode}`);
|
||||
if (field.numberingRule?.enabled && field.numberingRule?.ruleId) {
|
||||
const ruleIdKey = `${field.columnName}_numberingRuleId`;
|
||||
const hasRuleId = dataToSave[ruleIdKey]; // 사용자가 수정하지 않았으면 ruleId 유지됨
|
||||
|
||||
// 채번 규칙 할당 조건
|
||||
const shouldAllocate =
|
||||
// 1. generateOnSave가 ON인 경우: 항상 저장 시점에 할당
|
||||
field.numberingRule.generateOnSave ||
|
||||
// 2. editable이 OFF인 경우: 사용자 입력 무시하고 채번 규칙으로 덮어씌움
|
||||
!field.numberingRule.editable ||
|
||||
// 3. editable이 ON이고 사용자가 수정하지 않은 경우 (ruleId 유지됨): 실제 번호 할당
|
||||
(field.numberingRule.editable && hasRuleId);
|
||||
|
||||
if (shouldAllocate) {
|
||||
const response = await allocateNumberingCode(field.numberingRule.ruleId);
|
||||
if (response.success && response.data?.generatedCode) {
|
||||
dataToSave[field.columnName] = response.data.generatedCode;
|
||||
let reason = "(알 수 없음)";
|
||||
if (field.numberingRule.generateOnSave) {
|
||||
reason = "(generateOnSave)";
|
||||
} else if (!field.numberingRule.editable) {
|
||||
reason = "(editable=OFF, 강제 덮어씌움)";
|
||||
} else if (hasRuleId) {
|
||||
reason = "(editable=ON, 사용자 미수정)";
|
||||
}
|
||||
console.log(`[채번 할당] ${field.columnName} = ${response.data.generatedCode} ${reason}`);
|
||||
} else {
|
||||
console.error(`[채번 실패] ${field.columnName}:`, response.error);
|
||||
}
|
||||
} else {
|
||||
console.error(`[채번 실패] ${field.columnName}:`, response.error);
|
||||
console.log(
|
||||
`[채번 스킵] ${field.columnName}: 사용자가 직접 입력한 값 유지 = ${dataToSave[field.columnName]}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue