버튼 삭제 수정기능 구현

This commit is contained in:
kjs
2025-09-18 18:49:30 +09:00
parent 87f3959036
commit 004bf28d17
14 changed files with 1637 additions and 134 deletions

View File

@@ -14,6 +14,12 @@ export interface FormDataResult {
updatedBy: string;
}
export interface PartialUpdateResult {
success: boolean;
data: any;
message: string;
}
export interface PaginatedFormData {
content: FormDataResult[];
totalElements: number;
@@ -128,9 +134,9 @@ export class DynamicFormService {
}
/**
* 테이블의 Primary Key 컬럼 조회
* 테이블의 Primary Key 컬럼 조회 (공개 메서드로 변경)
*/
private async getTablePrimaryKeys(tableName: string): Promise<string[]> {
async getTablePrimaryKeys(tableName: string): Promise<string[]> {
try {
const result = (await prisma.$queryRawUnsafe(`
SELECT kcu.column_name
@@ -385,6 +391,118 @@ export class DynamicFormService {
}
}
/**
* 폼 데이터 부분 업데이트 (변경된 필드만 업데이트)
*/
async updateFormDataPartial(
id: number,
tableName: string,
originalData: Record<string, any>,
newData: Record<string, any>
): Promise<PartialUpdateResult> {
try {
console.log("🔄 서비스: 부분 업데이트 시작:", {
id,
tableName,
originalData,
newData,
});
// 테이블의 실제 컬럼 정보 조회
const tableColumns = await this.getTableColumnNames(tableName);
console.log(`📋 테이블 ${tableName}의 컬럼:`, tableColumns);
// 변경된 필드만 찾기
const changedFields: Record<string, any> = {};
for (const [key, value] of Object.entries(newData)) {
// 메타데이터 필드 제외
if (
["created_by", "updated_by", "company_code", "screen_id"].includes(
key
)
) {
continue;
}
// 테이블에 존재하지 않는 컬럼 제외
if (!tableColumns.includes(key)) {
console.log(
`⚠️ 컬럼 ${key}는 테이블 ${tableName}에 존재하지 않아 제외됨`
);
continue;
}
// 값이 실제로 변경된 경우만 포함
if (originalData[key] !== value) {
changedFields[key] = value;
console.log(
`📝 변경된 필드: ${key} = "${originalData[key]}" → "${value}"`
);
}
}
// 변경된 필드가 없으면 업데이트 건너뛰기
if (Object.keys(changedFields).length === 0) {
console.log("📋 변경된 필드가 없습니다. 업데이트를 건너뜁니다.");
return {
success: true,
data: originalData,
message: "변경사항이 없어 업데이트하지 않았습니다.",
};
}
// 업데이트 관련 필드 추가 (변경사항이 있는 경우에만)
if (tableColumns.includes("updated_at")) {
changedFields.updated_at = new Date();
}
console.log("🎯 실제 업데이트할 필드들:", changedFields);
// 동적으로 기본키 조회
const primaryKeys = await this.getTablePrimaryKeys(tableName);
if (!primaryKeys || primaryKeys.length === 0) {
throw new Error(`테이블 ${tableName}의 기본키를 찾을 수 없습니다.`);
}
const primaryKeyColumn = primaryKeys[0];
console.log(`🔑 테이블 ${tableName}의 기본키: ${primaryKeyColumn}`);
// 동적 UPDATE SQL 생성 (변경된 필드만)
const setClause = Object.keys(changedFields)
.map((key, index) => `${key} = $${index + 1}`)
.join(", ");
const values: any[] = Object.values(changedFields);
values.push(id); // WHERE 조건용 ID 추가
const updateQuery = `
UPDATE ${tableName}
SET ${setClause}
WHERE ${primaryKeyColumn} = $${values.length}
RETURNING *
`;
console.log("📝 실행할 부분 UPDATE SQL:", updateQuery);
console.log("📊 SQL 파라미터:", values);
const result = await prisma.$queryRawUnsafe(updateQuery, ...values);
console.log("✅ 서비스: 부분 업데이트 성공:", result);
const updatedRecord = Array.isArray(result) ? result[0] : result;
return {
success: true,
data: updatedRecord,
message: "데이터가 성공적으로 업데이트되었습니다.",
};
} catch (error: any) {
console.error("❌ 서비스: 부분 업데이트 실패:", error);
throw new Error(`부분 업데이트 실패: ${error}`);
}
}
/**
* 폼 데이터 업데이트 (실제 테이블에서 직접 업데이트)
*/
@@ -448,11 +566,19 @@ export class DynamicFormService {
const values: any[] = Object.values(dataToUpdate);
values.push(id); // WHERE 조건용 ID 추가
// ID 또는 objid로 찾기 시도
// 동적으로 기본키 조회
const primaryKeys = await this.getTablePrimaryKeys(tableName);
if (!primaryKeys || primaryKeys.length === 0) {
throw new Error(`테이블 ${tableName}의 기본키를 찾을 수 없습니다.`);
}
const primaryKeyColumn = primaryKeys[0]; // 첫 번째 기본키 사용
console.log(`🔑 테이블 ${tableName}의 기본키: ${primaryKeyColumn}`);
const updateQuery = `
UPDATE ${tableName}
SET ${setClause}
WHERE (id = $${values.length} OR objid = $${values.length})
WHERE ${primaryKeyColumn} = $${values.length}
RETURNING *
`;
@@ -524,10 +650,40 @@ export class DynamicFormService {
tableName,
});
// 동적 DELETE SQL 생성
// 1. 먼저 테이블의 기본키 컬럼명을 동적으로 조회
const primaryKeyQuery = `
SELECT kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.table_name = $1
AND tc.constraint_type = 'PRIMARY KEY'
LIMIT 1
`;
console.log("🔍 기본키 조회 SQL:", primaryKeyQuery);
console.log("🔍 테이블명:", tableName);
const primaryKeyResult = await prisma.$queryRawUnsafe(
primaryKeyQuery,
tableName
);
if (
!primaryKeyResult ||
!Array.isArray(primaryKeyResult) ||
primaryKeyResult.length === 0
) {
throw new Error(`테이블 ${tableName}의 기본키를 찾을 수 없습니다.`);
}
const primaryKeyColumn = (primaryKeyResult[0] as any).column_name;
console.log("🔑 발견된 기본키 컬럼:", primaryKeyColumn);
// 2. 동적으로 발견된 기본키를 사용한 DELETE SQL 생성
const deleteQuery = `
DELETE FROM ${tableName}
WHERE (id = $1 OR objid = $1)
WHERE ${primaryKeyColumn} = $1
RETURNING *
`;