2025-09-02 11:30:19 +09:00
|
|
|
import { PrismaClient } from "@prisma/client";
|
|
|
|
|
import { logger } from "../utils/logger";
|
|
|
|
|
|
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
|
|
|
|
|
|
export interface CodeCategory {
|
|
|
|
|
category_code: string;
|
|
|
|
|
category_name: string;
|
|
|
|
|
category_name_eng?: string | null;
|
|
|
|
|
description?: string | null;
|
|
|
|
|
sort_order: number;
|
|
|
|
|
is_active: string;
|
|
|
|
|
created_date?: Date | null;
|
|
|
|
|
created_by?: string | null;
|
|
|
|
|
updated_date?: Date | null;
|
|
|
|
|
updated_by?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CodeInfo {
|
|
|
|
|
code_category: string;
|
|
|
|
|
code_value: string;
|
|
|
|
|
code_name: string;
|
|
|
|
|
code_name_eng?: string | null;
|
|
|
|
|
description?: string | null;
|
|
|
|
|
sort_order: number;
|
|
|
|
|
is_active: string;
|
|
|
|
|
created_date?: Date | null;
|
|
|
|
|
created_by?: string | null;
|
|
|
|
|
updated_date?: Date | null;
|
|
|
|
|
updated_by?: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface GetCategoriesParams {
|
|
|
|
|
search?: string;
|
|
|
|
|
isActive?: boolean;
|
|
|
|
|
page?: number;
|
|
|
|
|
size?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface GetCodesParams {
|
|
|
|
|
search?: string;
|
|
|
|
|
isActive?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateCategoryData {
|
|
|
|
|
categoryCode: string;
|
|
|
|
|
categoryName: string;
|
|
|
|
|
categoryNameEng?: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
sortOrder?: number;
|
2025-09-02 18:25:44 +09:00
|
|
|
isActive?: string;
|
2025-09-02 11:30:19 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CreateCodeData {
|
|
|
|
|
codeValue: string;
|
|
|
|
|
codeName: string;
|
|
|
|
|
codeNameEng?: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
sortOrder?: number;
|
2025-09-02 18:25:44 +09:00
|
|
|
isActive?: string;
|
2025-09-02 11:30:19 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class CommonCodeService {
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리 목록 조회
|
|
|
|
|
*/
|
|
|
|
|
async getCategories(params: GetCategoriesParams) {
|
|
|
|
|
try {
|
|
|
|
|
const { search, isActive, page = 1, size = 20 } = params;
|
|
|
|
|
|
|
|
|
|
let whereClause: any = {};
|
|
|
|
|
|
|
|
|
|
if (search) {
|
|
|
|
|
whereClause.OR = [
|
|
|
|
|
{ category_name: { contains: search, mode: "insensitive" } },
|
|
|
|
|
{ category_code: { contains: search, mode: "insensitive" } },
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isActive !== undefined) {
|
|
|
|
|
whereClause.is_active = isActive ? "Y" : "N";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const offset = (page - 1) * size;
|
|
|
|
|
|
|
|
|
|
const [categories, total] = await Promise.all([
|
|
|
|
|
prisma.code_category.findMany({
|
|
|
|
|
where: whereClause,
|
|
|
|
|
orderBy: [{ sort_order: "asc" }, { category_code: "asc" }],
|
|
|
|
|
skip: offset,
|
|
|
|
|
take: size,
|
|
|
|
|
}),
|
|
|
|
|
prisma.code_category.count({ where: whereClause }),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
|
`카테고리 조회 완료: ${categories.length}개, 전체: ${total}개`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
data: categories,
|
|
|
|
|
total,
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error("카테고리 조회 중 오류:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리별 코드 목록 조회
|
|
|
|
|
*/
|
|
|
|
|
async getCodes(categoryCode: string, params: GetCodesParams) {
|
|
|
|
|
try {
|
|
|
|
|
const { search, isActive } = params;
|
|
|
|
|
|
|
|
|
|
let whereClause: any = {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (search) {
|
|
|
|
|
whereClause.OR = [
|
|
|
|
|
{ code_name: { contains: search, mode: "insensitive" } },
|
|
|
|
|
{ code_value: { contains: search, mode: "insensitive" } },
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isActive !== undefined) {
|
|
|
|
|
whereClause.is_active = isActive ? "Y" : "N";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const codes = await prisma.code_info.findMany({
|
|
|
|
|
where: whereClause,
|
|
|
|
|
orderBy: [{ sort_order: "asc" }, { code_value: "asc" }],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`코드 조회 완료: ${categoryCode} - ${codes.length}개`);
|
|
|
|
|
|
|
|
|
|
return codes;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`코드 조회 중 오류 (${categoryCode}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리 생성
|
|
|
|
|
*/
|
|
|
|
|
async createCategory(data: CreateCategoryData, createdBy: string) {
|
|
|
|
|
try {
|
|
|
|
|
const category = await prisma.code_category.create({
|
|
|
|
|
data: {
|
|
|
|
|
category_code: data.categoryCode,
|
|
|
|
|
category_name: data.categoryName,
|
|
|
|
|
category_name_eng: data.categoryNameEng,
|
|
|
|
|
description: data.description,
|
|
|
|
|
sort_order: data.sortOrder || 0,
|
|
|
|
|
is_active: "Y",
|
|
|
|
|
created_by: createdBy,
|
|
|
|
|
updated_by: createdBy,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`카테고리 생성 완료: ${data.categoryCode}`);
|
|
|
|
|
return category;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error("카테고리 생성 중 오류:", error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리 수정
|
|
|
|
|
*/
|
|
|
|
|
async updateCategory(
|
|
|
|
|
categoryCode: string,
|
|
|
|
|
data: Partial<CreateCategoryData>,
|
|
|
|
|
updatedBy: string
|
|
|
|
|
) {
|
|
|
|
|
try {
|
2025-09-02 18:25:44 +09:00
|
|
|
// 디버깅: 받은 데이터 로그
|
|
|
|
|
logger.info(`카테고리 수정 데이터:`, { categoryCode, data });
|
2025-09-02 11:30:19 +09:00
|
|
|
const category = await prisma.code_category.update({
|
|
|
|
|
where: { category_code: categoryCode },
|
|
|
|
|
data: {
|
|
|
|
|
category_name: data.categoryName,
|
|
|
|
|
category_name_eng: data.categoryNameEng,
|
|
|
|
|
description: data.description,
|
|
|
|
|
sort_order: data.sortOrder,
|
2025-09-02 18:25:44 +09:00
|
|
|
is_active:
|
|
|
|
|
typeof data.isActive === "boolean"
|
|
|
|
|
? data.isActive
|
|
|
|
|
? "Y"
|
|
|
|
|
: "N"
|
|
|
|
|
: data.isActive, // boolean이면 "Y"/"N"으로 변환
|
2025-09-02 11:30:19 +09:00
|
|
|
updated_by: updatedBy,
|
|
|
|
|
updated_date: new Date(),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`카테고리 수정 완료: ${categoryCode}`);
|
|
|
|
|
return category;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`카테고리 수정 중 오류 (${categoryCode}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리 삭제
|
|
|
|
|
*/
|
|
|
|
|
async deleteCategory(categoryCode: string) {
|
|
|
|
|
try {
|
|
|
|
|
await prisma.code_category.delete({
|
|
|
|
|
where: { category_code: categoryCode },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`카테고리 삭제 완료: ${categoryCode}`);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`카테고리 삭제 중 오류 (${categoryCode}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 코드 생성
|
|
|
|
|
*/
|
|
|
|
|
async createCode(
|
|
|
|
|
categoryCode: string,
|
|
|
|
|
data: CreateCodeData,
|
|
|
|
|
createdBy: string
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
const code = await prisma.code_info.create({
|
|
|
|
|
data: {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
code_value: data.codeValue,
|
|
|
|
|
code_name: data.codeName,
|
|
|
|
|
code_name_eng: data.codeNameEng,
|
|
|
|
|
description: data.description,
|
|
|
|
|
sort_order: data.sortOrder || 0,
|
|
|
|
|
is_active: "Y",
|
|
|
|
|
created_by: createdBy,
|
|
|
|
|
updated_by: createdBy,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`코드 생성 완료: ${categoryCode}.${data.codeValue}`);
|
|
|
|
|
return code;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(
|
|
|
|
|
`코드 생성 중 오류 (${categoryCode}.${data.codeValue}):`,
|
|
|
|
|
error
|
|
|
|
|
);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 코드 수정
|
|
|
|
|
*/
|
|
|
|
|
async updateCode(
|
|
|
|
|
categoryCode: string,
|
|
|
|
|
codeValue: string,
|
|
|
|
|
data: Partial<CreateCodeData>,
|
|
|
|
|
updatedBy: string
|
|
|
|
|
) {
|
|
|
|
|
try {
|
2025-09-02 18:25:44 +09:00
|
|
|
// 디버깅: 받은 데이터 로그
|
|
|
|
|
logger.info(`코드 수정 데이터:`, { categoryCode, codeValue, data });
|
2025-09-02 11:30:19 +09:00
|
|
|
const code = await prisma.code_info.update({
|
|
|
|
|
where: {
|
|
|
|
|
code_category_code_value: {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
code_value: codeValue,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
data: {
|
|
|
|
|
code_name: data.codeName,
|
|
|
|
|
code_name_eng: data.codeNameEng,
|
|
|
|
|
description: data.description,
|
|
|
|
|
sort_order: data.sortOrder,
|
2025-09-02 18:25:44 +09:00
|
|
|
is_active:
|
|
|
|
|
typeof data.isActive === "boolean"
|
|
|
|
|
? data.isActive
|
|
|
|
|
? "Y"
|
|
|
|
|
: "N"
|
|
|
|
|
: data.isActive, // boolean이면 "Y"/"N"으로 변환
|
2025-09-02 11:30:19 +09:00
|
|
|
updated_by: updatedBy,
|
|
|
|
|
updated_date: new Date(),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`코드 수정 완료: ${categoryCode}.${codeValue}`);
|
|
|
|
|
return code;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`코드 수정 중 오류 (${categoryCode}.${codeValue}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 코드 삭제
|
|
|
|
|
*/
|
|
|
|
|
async deleteCode(categoryCode: string, codeValue: string) {
|
|
|
|
|
try {
|
|
|
|
|
await prisma.code_info.delete({
|
|
|
|
|
where: {
|
|
|
|
|
code_category_code_value: {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
code_value: codeValue,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
logger.info(`코드 삭제 완료: ${categoryCode}.${codeValue}`);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`코드 삭제 중 오류 (${categoryCode}.${codeValue}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리별 옵션 조회 (화면관리용)
|
|
|
|
|
*/
|
|
|
|
|
async getCodeOptions(categoryCode: string) {
|
|
|
|
|
try {
|
|
|
|
|
const codes = await prisma.code_info.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
is_active: "Y",
|
|
|
|
|
},
|
|
|
|
|
select: {
|
|
|
|
|
code_value: true,
|
|
|
|
|
code_name: true,
|
|
|
|
|
code_name_eng: true,
|
|
|
|
|
sort_order: true,
|
|
|
|
|
},
|
|
|
|
|
orderBy: [{ sort_order: "asc" }, { code_value: "asc" }],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const options = codes.map((code) => ({
|
|
|
|
|
value: code.code_value,
|
|
|
|
|
label: code.code_name,
|
|
|
|
|
labelEng: code.code_name_eng,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
logger.info(`코드 옵션 조회 완료: ${categoryCode} - ${options.length}개`);
|
|
|
|
|
return options;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`코드 옵션 조회 중 오류 (${categoryCode}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 코드 순서 변경
|
|
|
|
|
*/
|
|
|
|
|
async reorderCodes(
|
|
|
|
|
categoryCode: string,
|
|
|
|
|
codes: Array<{ codeValue: string; sortOrder: number }>,
|
|
|
|
|
updatedBy: string
|
|
|
|
|
) {
|
|
|
|
|
try {
|
2025-09-02 13:57:53 +09:00
|
|
|
// 먼저 존재하는 코드들을 확인
|
|
|
|
|
const existingCodes = await prisma.code_info.findMany({
|
|
|
|
|
where: {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
code_value: { in: codes.map((c) => c.codeValue) },
|
|
|
|
|
},
|
|
|
|
|
select: { code_value: true },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const existingCodeValues = existingCodes.map((c) => c.code_value);
|
|
|
|
|
const validCodes = codes.filter((c) =>
|
|
|
|
|
existingCodeValues.includes(c.codeValue)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (validCodes.length === 0) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
`카테고리 ${categoryCode}에 순서를 변경할 유효한 코드가 없습니다.`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const updatePromises = validCodes.map(({ codeValue, sortOrder }) =>
|
2025-09-02 11:30:19 +09:00
|
|
|
prisma.code_info.update({
|
|
|
|
|
where: {
|
|
|
|
|
code_category_code_value: {
|
|
|
|
|
code_category: categoryCode,
|
|
|
|
|
code_value: codeValue,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
data: {
|
|
|
|
|
sort_order: sortOrder,
|
|
|
|
|
updated_by: updatedBy,
|
|
|
|
|
updated_date: new Date(),
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await Promise.all(updatePromises);
|
2025-09-02 13:57:53 +09:00
|
|
|
|
|
|
|
|
const skippedCodes = codes.filter(
|
|
|
|
|
(c) => !existingCodeValues.includes(c.codeValue)
|
|
|
|
|
);
|
|
|
|
|
if (skippedCodes.length > 0) {
|
|
|
|
|
logger.warn(
|
|
|
|
|
`코드 순서 변경 시 존재하지 않는 코드들을 건너뜀: ${skippedCodes.map((c) => c.codeValue).join(", ")}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
|
`코드 순서 변경 완료: ${categoryCode} - ${validCodes.length}개 (전체 ${codes.length}개 중)`
|
|
|
|
|
);
|
2025-09-02 11:30:19 +09:00
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`코드 순서 변경 중 오류 (${categoryCode}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-03 11:20:43 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 카테고리 중복 검사
|
|
|
|
|
*/
|
|
|
|
|
async checkCategoryDuplicate(
|
|
|
|
|
field: 'categoryCode' | 'categoryName' | 'categoryNameEng',
|
|
|
|
|
value: string,
|
|
|
|
|
excludeCategoryCode?: string
|
|
|
|
|
): Promise<{ isDuplicate: boolean; message: string }> {
|
|
|
|
|
try {
|
|
|
|
|
if (!value || !value.trim()) {
|
|
|
|
|
return {
|
|
|
|
|
isDuplicate: false,
|
|
|
|
|
message: "값을 입력해주세요."
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const trimmedValue = value.trim();
|
|
|
|
|
let whereCondition: any = {};
|
|
|
|
|
|
|
|
|
|
// 필드별 검색 조건 설정
|
|
|
|
|
switch (field) {
|
|
|
|
|
case 'categoryCode':
|
|
|
|
|
whereCondition.category_code = trimmedValue;
|
|
|
|
|
break;
|
|
|
|
|
case 'categoryName':
|
|
|
|
|
whereCondition.category_name = trimmedValue;
|
|
|
|
|
break;
|
|
|
|
|
case 'categoryNameEng':
|
|
|
|
|
whereCondition.category_name_eng = trimmedValue;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 수정 시 자기 자신 제외
|
|
|
|
|
if (excludeCategoryCode) {
|
|
|
|
|
whereCondition.category_code = {
|
|
|
|
|
...whereCondition.category_code,
|
|
|
|
|
not: excludeCategoryCode
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const existingCategory = await prisma.code_category.findFirst({
|
|
|
|
|
where: whereCondition,
|
|
|
|
|
select: { category_code: true }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const isDuplicate = !!existingCategory;
|
|
|
|
|
const fieldNames = {
|
|
|
|
|
categoryCode: '카테고리 코드',
|
|
|
|
|
categoryName: '카테고리명',
|
|
|
|
|
categoryNameEng: '카테고리 영문명'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
isDuplicate,
|
|
|
|
|
message: isDuplicate
|
|
|
|
|
? `이미 사용 중인 ${fieldNames[field]}입니다.`
|
|
|
|
|
: `사용 가능한 ${fieldNames[field]}입니다.`
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`카테고리 중복 검사 중 오류 (${field}: ${value}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 코드 중복 검사
|
|
|
|
|
*/
|
|
|
|
|
async checkCodeDuplicate(
|
|
|
|
|
categoryCode: string,
|
|
|
|
|
field: 'codeValue' | 'codeName' | 'codeNameEng',
|
|
|
|
|
value: string,
|
|
|
|
|
excludeCodeValue?: string
|
|
|
|
|
): Promise<{ isDuplicate: boolean; message: string }> {
|
|
|
|
|
try {
|
|
|
|
|
if (!value || !value.trim()) {
|
|
|
|
|
return {
|
|
|
|
|
isDuplicate: false,
|
|
|
|
|
message: "값을 입력해주세요."
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const trimmedValue = value.trim();
|
|
|
|
|
let whereCondition: any = {
|
|
|
|
|
code_category: categoryCode
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 필드별 검색 조건 설정
|
|
|
|
|
switch (field) {
|
|
|
|
|
case 'codeValue':
|
|
|
|
|
whereCondition.code_value = trimmedValue;
|
|
|
|
|
break;
|
|
|
|
|
case 'codeName':
|
|
|
|
|
whereCondition.code_name = trimmedValue;
|
|
|
|
|
break;
|
|
|
|
|
case 'codeNameEng':
|
|
|
|
|
whereCondition.code_name_eng = trimmedValue;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 수정 시 자기 자신 제외
|
|
|
|
|
if (excludeCodeValue) {
|
|
|
|
|
whereCondition.code_value = {
|
|
|
|
|
...whereCondition.code_value,
|
|
|
|
|
not: excludeCodeValue
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const existingCode = await prisma.code_info.findFirst({
|
|
|
|
|
where: whereCondition,
|
|
|
|
|
select: { code_value: true }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const isDuplicate = !!existingCode;
|
|
|
|
|
const fieldNames = {
|
|
|
|
|
codeValue: '코드값',
|
|
|
|
|
codeName: '코드명',
|
|
|
|
|
codeNameEng: '코드 영문명'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
isDuplicate,
|
|
|
|
|
message: isDuplicate
|
|
|
|
|
? `이미 사용 중인 ${fieldNames[field]}입니다.`
|
|
|
|
|
: `사용 가능한 ${fieldNames[field]}입니다.`
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`코드 중복 검사 중 오류 (${categoryCode}, ${field}: ${value}):`, error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-02 11:30:19 +09:00
|
|
|
}
|