- Enhanced the `previewCode` endpoint to accept a new `manualInputValue` parameter, allowing for dynamic sequence generation based on user input. - Updated the `NumberingRuleService` to skip legacy sequence lookups when manual input is not provided, ensuring accurate initial sequence display. - Integrated debounce functionality in the `V2Input` component to optimize API calls for real-time suffix updates as users type. - Refactored category resolution logic into a helper function to reduce code duplication and improve maintainability. These changes significantly improve the user experience by providing immediate feedback on numbering sequences based on manual inputs.
290 lines
9.2 KiB
TypeScript
290 lines
9.2 KiB
TypeScript
/**
|
|
* 채번 규칙 관리 API 클라이언트
|
|
*/
|
|
|
|
import { apiClient } from "./client";
|
|
import { NumberingRuleConfig } from "@/types/numbering-rule";
|
|
|
|
export interface ApiResponse<T> {
|
|
success: boolean;
|
|
data?: T;
|
|
error?: string;
|
|
message?: string;
|
|
}
|
|
|
|
export async function getNumberingRules(): Promise<ApiResponse<NumberingRuleConfig[]>> {
|
|
try {
|
|
const response = await apiClient.get("/numbering-rules");
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "규칙 목록 조회 실패" };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 메뉴별 사용 가능한 채번 규칙 조회 (기존 방식, 하위 호환성 유지)
|
|
* @param menuObjid 현재 메뉴의 objid (선택)
|
|
* @returns 사용 가능한 채번 규칙 목록
|
|
*/
|
|
export async function getAvailableNumberingRules(menuObjid?: number): Promise<ApiResponse<NumberingRuleConfig[]>> {
|
|
try {
|
|
const url = menuObjid ? `/numbering-rules/available/${menuObjid}` : "/numbering-rules/available";
|
|
const response = await apiClient.get(url);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "사용 가능한 규칙 조회 실패" };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 화면용 채번 규칙 조회 (테이블 기반 필터링 - 간소화)
|
|
* @param tableName 화면의 테이블명 (필수)
|
|
* @returns 해당 테이블의 채번 규칙 목록
|
|
*/
|
|
export async function getAvailableNumberingRulesForScreen(
|
|
tableName: string,
|
|
): Promise<ApiResponse<NumberingRuleConfig[]>> {
|
|
try {
|
|
const response = await apiClient.get("/numbering-rules/available-for-screen", {
|
|
params: { tableName },
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: error.message || "화면용 규칙 조회 실패",
|
|
};
|
|
}
|
|
}
|
|
|
|
export async function getNumberingRuleById(ruleId: string): Promise<ApiResponse<NumberingRuleConfig>> {
|
|
try {
|
|
const response = await apiClient.get(`/numbering-rules/${ruleId}`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "규칙 조회 실패" };
|
|
}
|
|
}
|
|
|
|
export async function createNumberingRule(config: NumberingRuleConfig): Promise<ApiResponse<NumberingRuleConfig>> {
|
|
try {
|
|
const response = await apiClient.post("/numbering-rules", config);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "규칙 생성 실패" };
|
|
}
|
|
}
|
|
|
|
export async function updateNumberingRule(
|
|
ruleId: string,
|
|
config: Partial<NumberingRuleConfig>,
|
|
): Promise<ApiResponse<NumberingRuleConfig>> {
|
|
try {
|
|
const response = await apiClient.put(`/numbering-rules/${ruleId}`, config);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "규칙 수정 실패" };
|
|
}
|
|
}
|
|
|
|
export async function deleteNumberingRule(ruleId: string): Promise<ApiResponse<void>> {
|
|
try {
|
|
const response = await apiClient.delete(`/numbering-rules/${ruleId}`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "규칙 삭제 실패" };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 코드 미리보기 (순번 증가 없음)
|
|
* 화면 표시용으로 사용
|
|
* @param ruleId 채번 규칙 ID
|
|
* @param formData 폼 데이터 (카테고리 기반 채번 시 사용)
|
|
*/
|
|
export async function previewNumberingCode(
|
|
ruleId: string,
|
|
formData?: Record<string, unknown>,
|
|
manualInputValue?: string,
|
|
): Promise<ApiResponse<{ generatedCode: string }>> {
|
|
// ruleId 유효성 검사
|
|
if (!ruleId || ruleId === "undefined" || ruleId === "null") {
|
|
return { success: false, error: "채번 규칙 ID가 설정되지 않았습니다" };
|
|
}
|
|
|
|
try {
|
|
const response = await apiClient.post(`/numbering-rules/${ruleId}/preview`, {
|
|
formData: formData || {},
|
|
manualInputValue,
|
|
});
|
|
if (!response.data) {
|
|
return { success: false, error: "서버 응답이 비어있습니다" };
|
|
}
|
|
return response.data;
|
|
} catch (error: unknown) {
|
|
const err = error as { response?: { data?: { error?: string; message?: string } }; message?: string };
|
|
const errorMessage =
|
|
err.response?.data?.error || err.response?.data?.message || err.message || "코드 미리보기 실패";
|
|
return { success: false, error: errorMessage };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 코드 할당 (저장 시점에 실제 순번 증가)
|
|
* 실제 저장할 때만 호출
|
|
* @param ruleId 채번 규칙 ID
|
|
* @param userInputCode 사용자가 편집한 최종 코드 (수동 입력 부분 추출용)
|
|
* @param formData 폼 데이터 (카테고리/날짜 기반 채번용)
|
|
*/
|
|
export async function allocateNumberingCode(
|
|
ruleId: string,
|
|
userInputCode?: string,
|
|
formData?: Record<string, any>,
|
|
): Promise<ApiResponse<{ generatedCode: string }>> {
|
|
try {
|
|
const response = await apiClient.post(`/numbering-rules/${ruleId}/allocate`, {
|
|
userInputCode,
|
|
formData,
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "코드 할당 실패" };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @deprecated 기존 generateNumberingCode는 previewNumberingCode를 사용하세요
|
|
*/
|
|
export async function generateNumberingCode(ruleId: string): Promise<ApiResponse<{ generatedCode: string }>> {
|
|
console.warn("generateNumberingCode는 deprecated. previewNumberingCode 사용 권장");
|
|
return previewNumberingCode(ruleId);
|
|
}
|
|
|
|
// 하위 호환성을 위한 별칭
|
|
export const generateCode = generateNumberingCode;
|
|
|
|
export async function resetSequence(ruleId: string): Promise<ApiResponse<void>> {
|
|
try {
|
|
const response = await apiClient.post(`/numbering-rules/${ruleId}/reset`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message || "시퀀스 초기화 실패" };
|
|
}
|
|
}
|
|
|
|
// ====== 테스트용 API (numbering_rules 테이블 사용) ======
|
|
|
|
/**
|
|
* [테스트] 테스트 테이블에서 채번규칙 목록 조회
|
|
* numbering_rules 테이블 사용
|
|
* @param menuObjid 메뉴 OBJID (선택) - 필터링용
|
|
*/
|
|
export async function getNumberingRulesFromTest(menuObjid?: number): Promise<ApiResponse<NumberingRuleConfig[]>> {
|
|
try {
|
|
const url = menuObjid ? `/numbering-rules/test/list/${menuObjid}` : "/numbering-rules/test/list";
|
|
const response = await apiClient.get(url);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: error.response?.data?.error || error.message || "테스트 규칙 목록 조회 실패",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* [테스트] 테이블+컬럼 기반 채번규칙 조회
|
|
* numbering_rules 테이블 사용
|
|
*/
|
|
export async function getNumberingRuleByColumn(
|
|
tableName: string,
|
|
columnName: string,
|
|
): Promise<ApiResponse<NumberingRuleConfig>> {
|
|
try {
|
|
const response = await apiClient.get("/numbering-rules/test/by-column", {
|
|
params: { tableName, columnName },
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: error.response?.data?.error || error.message || "테이블+컬럼 기반 규칙 조회 실패",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* [테스트] 테스트 테이블에 채번규칙 저장
|
|
* numbering_rules 테이블 사용
|
|
*/
|
|
export async function saveNumberingRuleToTest(config: NumberingRuleConfig): Promise<ApiResponse<NumberingRuleConfig>> {
|
|
try {
|
|
const response = await apiClient.post("/numbering-rules/test/save", config);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: error.response?.data?.error || error.message || "테스트 규칙 저장 실패",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* [테스트] 테스트 테이블에서 채번규칙 삭제
|
|
* numbering_rules 테이블 사용
|
|
*/
|
|
export async function deleteNumberingRuleFromTest(ruleId: string): Promise<ApiResponse<void>> {
|
|
try {
|
|
const response = await apiClient.delete(`/numbering-rules/test/${ruleId}`);
|
|
return response.data;
|
|
} catch (error: unknown) {
|
|
const err = error as { response?: { data?: { error?: string } }; message?: string };
|
|
return {
|
|
success: false,
|
|
error: err.response?.data?.error || err.message || "테스트 규칙 삭제 실패",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* [테스트] 카테고리 조건 포함 채번규칙 조회
|
|
*/
|
|
export async function getNumberingRuleByColumnWithCategory(
|
|
tableName: string,
|
|
columnName: string,
|
|
categoryColumn?: string,
|
|
categoryValueId?: number,
|
|
): Promise<ApiResponse<NumberingRuleConfig>> {
|
|
try {
|
|
const response = await apiClient.get("/numbering-rules/test/by-column-with-category", {
|
|
params: { tableName, columnName, categoryColumn, categoryValueId },
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: error.response?.data?.error || error.message || "카테고리 조건 규칙 조회 실패",
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* [테스트] 테이블.컬럼별 모든 채번규칙 조회 (카테고리 조건별)
|
|
*/
|
|
export async function getRulesByTableColumn(
|
|
tableName: string,
|
|
columnName: string,
|
|
): Promise<ApiResponse<NumberingRuleConfig[]>> {
|
|
try {
|
|
const response = await apiClient.get("/numbering-rules/test/rules-by-table-column", {
|
|
params: { tableName, columnName },
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: error.response?.data?.error || error.message || "테이블.컬럼별 규칙 목록 조회 실패",
|
|
};
|
|
}
|
|
}
|