Phase 2 ScreenManagementService 전환 완료
This commit is contained in:
@@ -127,16 +127,19 @@ export class ScreenManagementService {
|
||||
const total = parseInt(totalResult[0]?.count || "0", 10);
|
||||
|
||||
// 테이블 라벨 정보를 한 번에 조회 (Raw Query)
|
||||
const tableNames = [
|
||||
...new Set(screens.map((s: any) => s.table_name).filter(Boolean)),
|
||||
];
|
||||
const tableNames = Array.from(
|
||||
new Set(screens.map((s: any) => s.table_name).filter(Boolean))
|
||||
);
|
||||
|
||||
let tableLabelMap = new Map<string, string>();
|
||||
|
||||
if (tableNames.length > 0) {
|
||||
try {
|
||||
const placeholders = tableNames.map((_, i) => `$${i + 1}`).join(", ");
|
||||
const tableLabels = await query<{ table_name: string; table_label: string | null }>(
|
||||
const tableLabels = await query<{
|
||||
table_name: string;
|
||||
table_label: string | null;
|
||||
}>(
|
||||
`SELECT table_name, table_label FROM table_labels
|
||||
WHERE table_name IN (${placeholders})`,
|
||||
tableNames
|
||||
@@ -339,7 +342,9 @@ export class ScreenManagementService {
|
||||
const params: any[] = [];
|
||||
|
||||
if (userCompanyCode !== "*") {
|
||||
whereConditions.push(`sd.company_code IN ($${params.length + 1}, $${params.length + 2})`);
|
||||
whereConditions.push(
|
||||
`sd.company_code IN ($${params.length + 1}, $${params.length + 2})`
|
||||
);
|
||||
params.push(userCompanyCode, "*");
|
||||
}
|
||||
|
||||
@@ -371,13 +376,9 @@ export class ScreenManagementService {
|
||||
if (screen.screen_id === screenId) continue; // 자기 자신은 제외
|
||||
|
||||
try {
|
||||
// screen_layouts 테이블에서 버튼 컴포넌트 확인
|
||||
const buttonLayouts = screen.layouts.filter(
|
||||
(layout) => layout.component_type === "widget"
|
||||
);
|
||||
|
||||
for (const layout of buttonLayouts) {
|
||||
const properties = layout.properties as any;
|
||||
// screen_layouts 테이블에서 버튼 컴포넌트 확인 (위젯 타입만)
|
||||
if (screen.component_type === "widget") {
|
||||
const properties = screen.properties as any;
|
||||
|
||||
// 버튼 컴포넌트인지 확인
|
||||
if (properties?.widgetType === "button") {
|
||||
@@ -393,7 +394,7 @@ export class ScreenManagementService {
|
||||
screenId: screen.screen_id,
|
||||
screenName: screen.screen_name,
|
||||
screenCode: screen.screen_code,
|
||||
componentId: layout.component_id,
|
||||
componentId: screen.component_id,
|
||||
componentType: "button",
|
||||
referenceType: "popup",
|
||||
});
|
||||
@@ -408,7 +409,7 @@ export class ScreenManagementService {
|
||||
screenId: screen.screen_id,
|
||||
screenName: screen.screen_name,
|
||||
screenCode: screen.screen_code,
|
||||
componentId: layout.component_id,
|
||||
componentId: screen.component_id,
|
||||
componentType: "button",
|
||||
referenceType: "navigate",
|
||||
});
|
||||
@@ -423,7 +424,7 @@ export class ScreenManagementService {
|
||||
screenId: screen.screen_id,
|
||||
screenName: screen.screen_name,
|
||||
screenCode: screen.screen_code,
|
||||
componentId: layout.component_id,
|
||||
componentId: screen.component_id,
|
||||
componentType: "button",
|
||||
referenceType: "url",
|
||||
});
|
||||
@@ -431,67 +432,8 @@ export class ScreenManagementService {
|
||||
}
|
||||
}
|
||||
|
||||
// 기존 layout_metadata도 확인 (하위 호환성)
|
||||
const layoutMetadata = screen.layout_metadata as any;
|
||||
if (layoutMetadata?.components) {
|
||||
const components = layoutMetadata.components;
|
||||
|
||||
for (const component of components) {
|
||||
// 버튼 컴포넌트인지 확인
|
||||
if (
|
||||
component.type === "widget" &&
|
||||
component.widgetType === "button"
|
||||
) {
|
||||
const config = component.webTypeConfig;
|
||||
if (!config) continue;
|
||||
|
||||
// popup 액션에서 targetScreenId 확인
|
||||
if (
|
||||
config.actionType === "popup" &&
|
||||
config.targetScreenId === screenId
|
||||
) {
|
||||
dependencies.push({
|
||||
screenId: screen.screen_id,
|
||||
screenName: screen.screen_name,
|
||||
screenCode: screen.screen_code,
|
||||
componentId: component.id,
|
||||
componentType: "button",
|
||||
referenceType: "popup",
|
||||
});
|
||||
}
|
||||
|
||||
// navigate 액션에서 targetScreenId 확인
|
||||
if (
|
||||
config.actionType === "navigate" &&
|
||||
config.targetScreenId === screenId
|
||||
) {
|
||||
dependencies.push({
|
||||
screenId: screen.screen_id,
|
||||
screenName: screen.screen_name,
|
||||
screenCode: screen.screen_code,
|
||||
componentId: component.id,
|
||||
componentType: "button",
|
||||
referenceType: "navigate",
|
||||
});
|
||||
}
|
||||
|
||||
// navigateUrl에서 화면 ID 패턴 확인 (예: /screens/123)
|
||||
if (
|
||||
config.navigateUrl &&
|
||||
config.navigateUrl.includes(`/screens/${screenId}`)
|
||||
) {
|
||||
dependencies.push({
|
||||
screenId: screen.screen_id,
|
||||
screenName: screen.screen_name,
|
||||
screenCode: screen.screen_code,
|
||||
componentId: component.id,
|
||||
componentType: "button",
|
||||
referenceType: "url",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 기존 layout_metadata도 확인 (하위 호환성) - 현재는 사용하지 않음
|
||||
// 실제 데이터는 screen_layouts 테이블에서 개별적으로 조회해야 함
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`화면 ${screen.screen_id}의 레이아웃 분석 중 오류:`,
|
||||
@@ -501,31 +443,35 @@ export class ScreenManagementService {
|
||||
}
|
||||
}
|
||||
|
||||
// 메뉴 할당 확인
|
||||
// 메뉴에 할당된 화면인지 확인 (임시 주석 처리)
|
||||
/*
|
||||
const menuAssignments = await prisma.screen_menu_assignments.findMany({
|
||||
where: {
|
||||
screen_id: screenId,
|
||||
is_active: "Y",
|
||||
},
|
||||
include: {
|
||||
menu_info: true, // 메뉴 정보도 함께 조회
|
||||
},
|
||||
});
|
||||
// 메뉴 할당 확인 (Raw Query)
|
||||
try {
|
||||
const menuAssignments = await query<{
|
||||
assignment_id: number;
|
||||
menu_objid: number;
|
||||
menu_name_kor?: string;
|
||||
}>(
|
||||
`SELECT sma.assignment_id, sma.menu_objid, mi.menu_name_kor
|
||||
FROM screen_menu_assignments sma
|
||||
LEFT JOIN menu_info mi ON sma.menu_objid = mi.objid
|
||||
WHERE sma.screen_id = $1 AND sma.is_active = 'Y'`,
|
||||
[screenId]
|
||||
);
|
||||
|
||||
// 메뉴에 할당된 경우 의존성에 추가
|
||||
for (const assignment of menuAssignments) {
|
||||
dependencies.push({
|
||||
screenId: 0, // 메뉴는 화면이 아니므로 0으로 설정
|
||||
screenName: assignment.menu_info?.menu_name_kor || "알 수 없는 메뉴",
|
||||
screenCode: `MENU_${assignment.menu_objid}`,
|
||||
componentId: `menu_${assignment.assignment_id}`,
|
||||
componentType: "menu",
|
||||
referenceType: "menu_assignment",
|
||||
});
|
||||
// 메뉴에 할당된 경우 의존성에 추가
|
||||
for (const assignment of menuAssignments) {
|
||||
dependencies.push({
|
||||
screenId: 0, // 메뉴는 화면이 아니므로 0으로 설정
|
||||
screenName: assignment.menu_name_kor || "알 수 없는 메뉴",
|
||||
screenCode: `MENU_${assignment.menu_objid}`,
|
||||
componentId: `menu_${assignment.assignment_id}`,
|
||||
componentType: "menu",
|
||||
referenceType: "menu_assignment",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("메뉴 할당 확인 중 오류:", error);
|
||||
// 메뉴 할당 확인 실패해도 다른 의존성 체크는 계속 진행
|
||||
}
|
||||
*/
|
||||
|
||||
return {
|
||||
hasDependencies: dependencies.length > 0,
|
||||
@@ -544,7 +490,10 @@ export class ScreenManagementService {
|
||||
force: boolean = false
|
||||
): Promise<void> {
|
||||
// 권한 확인 (Raw Query)
|
||||
const existingResult = await query<{ company_code: string | null; is_active: string }>(
|
||||
const existingResult = await query<{
|
||||
company_code: string | null;
|
||||
is_active: string;
|
||||
}>(
|
||||
`SELECT company_code, is_active FROM screen_definitions WHERE screen_id = $1 LIMIT 1`,
|
||||
[screenId]
|
||||
);
|
||||
@@ -593,7 +542,14 @@ export class ScreenManagementService {
|
||||
updated_date = $4,
|
||||
updated_by = $5
|
||||
WHERE screen_id = $6`,
|
||||
[new Date(), deletedBy, deleteReason || null, new Date(), deletedBy, screenId]
|
||||
[
|
||||
new Date(),
|
||||
deletedBy,
|
||||
deleteReason || null,
|
||||
new Date(),
|
||||
deletedBy,
|
||||
screenId,
|
||||
]
|
||||
);
|
||||
|
||||
// 메뉴 할당도 비활성화
|
||||
@@ -607,7 +563,7 @@ export class ScreenManagementService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 화면 복원 (휴지통에서 복원)
|
||||
* 화면 복원 (휴지통에서 복원) (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async restoreScreen(
|
||||
screenId: number,
|
||||
@@ -615,14 +571,21 @@ export class ScreenManagementService {
|
||||
restoredBy: string
|
||||
): Promise<void> {
|
||||
// 권한 확인
|
||||
const existingScreen = await prisma.screen_definitions.findUnique({
|
||||
where: { screen_id: screenId },
|
||||
});
|
||||
const screens = await query<{
|
||||
company_code: string | null;
|
||||
is_active: string;
|
||||
screen_code: string;
|
||||
}>(
|
||||
`SELECT company_code, is_active, screen_code FROM screen_definitions WHERE screen_id = $1 LIMIT 1`,
|
||||
[screenId]
|
||||
);
|
||||
|
||||
if (!existingScreen) {
|
||||
if (screens.length === 0) {
|
||||
throw new Error("화면을 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
const existingScreen = screens[0];
|
||||
|
||||
if (
|
||||
userCompanyCode !== "*" &&
|
||||
existingScreen.company_code !== userCompanyCode
|
||||
@@ -704,7 +667,10 @@ export class ScreenManagementService {
|
||||
userCompanyCode: string
|
||||
): Promise<void> {
|
||||
// 권한 확인
|
||||
const screens = await query<{ company_code: string | null; is_active: string }>(
|
||||
const screens = await query<{
|
||||
company_code: string | null;
|
||||
is_active: string;
|
||||
}>(
|
||||
`SELECT company_code, is_active FROM screen_definitions WHERE screen_id = $1 LIMIT 1`,
|
||||
[screenId]
|
||||
);
|
||||
@@ -729,9 +695,17 @@ export class ScreenManagementService {
|
||||
|
||||
// 물리적 삭제 (수동으로 관련 데이터 삭제)
|
||||
await transaction(async (client) => {
|
||||
await client.query(`DELETE FROM screen_layouts WHERE screen_id = $1`, [screenId]);
|
||||
await client.query(`DELETE FROM screen_menu_assignments WHERE screen_id = $1`, [screenId]);
|
||||
await client.query(`DELETE FROM screen_definitions WHERE screen_id = $1`, [screenId]);
|
||||
await client.query(`DELETE FROM screen_layouts WHERE screen_id = $1`, [
|
||||
screenId,
|
||||
]);
|
||||
await client.query(
|
||||
`DELETE FROM screen_menu_assignments WHERE screen_id = $1`,
|
||||
[screenId]
|
||||
);
|
||||
await client.query(
|
||||
`DELETE FROM screen_definitions WHERE screen_id = $1`,
|
||||
[screenId]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -779,21 +753,27 @@ export class ScreenManagementService {
|
||||
const total = parseInt(totalResult[0]?.count || "0", 10);
|
||||
|
||||
// 테이블 라벨 정보를 한 번에 조회
|
||||
const tableNames = [
|
||||
...new Set(screens.map((s: any) => s.table_name).filter(Boolean)),
|
||||
];
|
||||
const tableNames = Array.from(
|
||||
new Set(screens.map((s: any) => s.table_name).filter(Boolean))
|
||||
);
|
||||
|
||||
let tableLabelMap = new Map<string, string>();
|
||||
|
||||
if (tableNames.length > 0) {
|
||||
const placeholders = tableNames.map((_, i) => `$${i + 1}`).join(", ");
|
||||
const tableLabels = await query<{ table_name: string; table_label: string | null }>(
|
||||
const tableLabels = await query<{
|
||||
table_name: string;
|
||||
table_label: string | null;
|
||||
}>(
|
||||
`SELECT table_name, table_label FROM table_labels WHERE table_name IN (${placeholders})`,
|
||||
tableNames
|
||||
);
|
||||
|
||||
tableLabelMap = new Map(
|
||||
tableLabels.map((tl: any) => [tl.table_name, tl.table_label || tl.table_name])
|
||||
tableLabels.map((tl: any) => [
|
||||
tl.table_name,
|
||||
tl.table_label || tl.table_name,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -918,18 +898,19 @@ export class ScreenManagementService {
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* 테이블 목록 조회 (모든 테이블)
|
||||
* 테이블 목록 조회 (모든 테이블) (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async getTables(companyCode: string): Promise<TableInfo[]> {
|
||||
try {
|
||||
// PostgreSQL에서 사용 가능한 테이블 목록 조회
|
||||
const tables = await prisma.$queryRaw<Array<{ table_name: string }>>`
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_type = 'BASE TABLE'
|
||||
ORDER BY table_name
|
||||
`;
|
||||
const tables = await query<{ table_name: string }>(
|
||||
`SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_type = 'BASE TABLE'
|
||||
ORDER BY table_name`,
|
||||
[]
|
||||
);
|
||||
|
||||
// 각 테이블의 컬럼 정보도 함께 조회
|
||||
const tableInfos: TableInfo[] = [];
|
||||
@@ -966,13 +947,14 @@ export class ScreenManagementService {
|
||||
console.log(`=== 단일 테이블 조회 시작: ${tableName} ===`);
|
||||
|
||||
// 테이블 존재 여부 확인
|
||||
const tableExists = await prisma.$queryRaw<Array<{ table_name: string }>>`
|
||||
SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_type = 'BASE TABLE'
|
||||
AND table_name = ${tableName}
|
||||
`;
|
||||
const tableExists = await query<{ table_name: string }>(
|
||||
`SELECT table_name
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = 'public'
|
||||
AND table_type = 'BASE TABLE'
|
||||
AND table_name = $1`,
|
||||
[tableName]
|
||||
);
|
||||
|
||||
if (tableExists.length === 0) {
|
||||
console.log(`테이블 ${tableName}이 존재하지 않습니다.`);
|
||||
@@ -1004,7 +986,7 @@ export class ScreenManagementService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 테이블 컬럼 정보 조회
|
||||
* 테이블 컬럼 정보 조회 (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async getTableColumns(
|
||||
tableName: string,
|
||||
@@ -1012,18 +994,16 @@ export class ScreenManagementService {
|
||||
): Promise<ColumnInfo[]> {
|
||||
try {
|
||||
// 테이블 컬럼 정보 조회
|
||||
const columns = await prisma.$queryRaw<
|
||||
Array<{
|
||||
column_name: string;
|
||||
data_type: string;
|
||||
is_nullable: string;
|
||||
column_default: string | null;
|
||||
character_maximum_length: number | null;
|
||||
numeric_precision: number | null;
|
||||
numeric_scale: number | null;
|
||||
}>
|
||||
>`
|
||||
SELECT
|
||||
const columns = await query<{
|
||||
column_name: string;
|
||||
data_type: string;
|
||||
is_nullable: string;
|
||||
column_default: string | null;
|
||||
character_maximum_length: number | null;
|
||||
numeric_precision: number | null;
|
||||
numeric_scale: number | null;
|
||||
}>(
|
||||
`SELECT
|
||||
column_name,
|
||||
data_type,
|
||||
is_nullable,
|
||||
@@ -1031,25 +1011,28 @@ export class ScreenManagementService {
|
||||
character_maximum_length,
|
||||
numeric_precision,
|
||||
numeric_scale
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = ${tableName}
|
||||
ORDER BY ordinal_position
|
||||
`;
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = $1
|
||||
ORDER BY ordinal_position`,
|
||||
[tableName]
|
||||
);
|
||||
|
||||
// column_labels 테이블에서 웹타입 정보 조회 (있는 경우)
|
||||
const webTypeInfo = await prisma.column_labels.findMany({
|
||||
where: { table_name: tableName },
|
||||
select: {
|
||||
column_name: true,
|
||||
web_type: true,
|
||||
column_label: true,
|
||||
detail_settings: true,
|
||||
},
|
||||
});
|
||||
const webTypeInfo = await query<{
|
||||
column_name: string;
|
||||
web_type: string | null;
|
||||
column_label: string | null;
|
||||
detail_settings: any;
|
||||
}>(
|
||||
`SELECT column_name, web_type, column_label, detail_settings
|
||||
FROM column_labels
|
||||
WHERE table_name = $1`,
|
||||
[tableName]
|
||||
);
|
||||
|
||||
// 컬럼 정보 매핑
|
||||
return columns.map((column) => {
|
||||
return columns.map((column: any) => {
|
||||
const webTypeData = webTypeInfo.find(
|
||||
(wt) => wt.column_name === column.column_name
|
||||
);
|
||||
@@ -1189,10 +1172,7 @@ export class ScreenManagementService {
|
||||
}
|
||||
|
||||
// 기존 레이아웃 삭제 (컴포넌트와 메타데이터 모두)
|
||||
await query(
|
||||
`DELETE FROM screen_layouts WHERE screen_id = $1`,
|
||||
[screenId]
|
||||
);
|
||||
await query(`DELETE FROM screen_layouts WHERE screen_id = $1`, [screenId]);
|
||||
|
||||
// 1. 메타데이터 저장 (격자 설정과 해상도 정보)
|
||||
if (layoutData.gridSettings || layoutData.screenResolution) {
|
||||
@@ -1260,10 +1240,10 @@ export class ScreenManagementService {
|
||||
component.type,
|
||||
component.id,
|
||||
component.parentId || null,
|
||||
component.position.x,
|
||||
component.position.y,
|
||||
component.size.width,
|
||||
component.size.height,
|
||||
Math.round(component.position.x), // 정수로 반올림
|
||||
Math.round(component.position.y), // 정수로 반올림
|
||||
Math.round(component.size.width), // 정수로 반올림
|
||||
Math.round(component.size.height), // 정수로 반올림
|
||||
JSON.stringify(properties),
|
||||
]
|
||||
);
|
||||
@@ -1414,7 +1394,10 @@ export class ScreenManagementService {
|
||||
params.push(isPublic);
|
||||
}
|
||||
|
||||
const whereSQL = whereConditions.length > 0 ? `WHERE ${whereConditions.join(" AND ")}` : "";
|
||||
const whereSQL =
|
||||
whereConditions.length > 0
|
||||
? `WHERE ${whereConditions.join(" AND ")}`
|
||||
: "";
|
||||
|
||||
const templates = await query<any>(
|
||||
`SELECT * FROM screen_templates
|
||||
@@ -1531,11 +1514,11 @@ export class ScreenManagementService {
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* 컬럼 정보 조회 (웹 타입 포함)
|
||||
* 컬럼 정보 조회 (웹 타입 포함) (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async getColumnInfo(tableName: string): Promise<ColumnInfo[]> {
|
||||
const columns = await prisma.$queryRaw`
|
||||
SELECT
|
||||
const columns = await query<any>(
|
||||
`SELECT
|
||||
c.column_name,
|
||||
COALESCE(cl.column_label, c.column_name) as column_label,
|
||||
c.data_type,
|
||||
@@ -1553,18 +1536,19 @@ export class ScreenManagementService {
|
||||
cl.is_visible,
|
||||
cl.display_order,
|
||||
cl.description
|
||||
FROM information_schema.columns c
|
||||
LEFT JOIN column_labels cl ON c.table_name = cl.table_name
|
||||
AND c.column_name = cl.column_name
|
||||
WHERE c.table_name = ${tableName}
|
||||
ORDER BY COALESCE(cl.display_order, c.ordinal_position)
|
||||
`;
|
||||
FROM information_schema.columns c
|
||||
LEFT JOIN column_labels cl ON c.table_name = cl.table_name
|
||||
AND c.column_name = cl.column_name
|
||||
WHERE c.table_name = $1
|
||||
ORDER BY COALESCE(cl.display_order, c.ordinal_position)`,
|
||||
[tableName]
|
||||
);
|
||||
|
||||
return columns as ColumnInfo[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 웹 타입 설정
|
||||
* 웹 타입 설정 (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async setColumnWebType(
|
||||
tableName: string,
|
||||
@@ -1572,44 +1556,45 @@ export class ScreenManagementService {
|
||||
webType: WebType,
|
||||
additionalSettings?: Partial<ColumnWebTypeSetting>
|
||||
): Promise<void> {
|
||||
await prisma.column_labels.upsert({
|
||||
where: {
|
||||
table_name_column_name: {
|
||||
table_name: tableName,
|
||||
column_name: columnName,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
web_type: webType,
|
||||
column_label: additionalSettings?.columnLabel,
|
||||
detail_settings: additionalSettings?.detailSettings
|
||||
// UPSERT를 INSERT ... ON CONFLICT로 변환
|
||||
await query(
|
||||
`INSERT INTO column_labels (
|
||||
table_name, column_name, column_label, web_type, detail_settings,
|
||||
code_category, reference_table, reference_column, display_column,
|
||||
is_visible, display_order, description, created_date, updated_date
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||
ON CONFLICT (table_name, column_name)
|
||||
DO UPDATE SET
|
||||
web_type = $4,
|
||||
column_label = $3,
|
||||
detail_settings = $5,
|
||||
code_category = $6,
|
||||
reference_table = $7,
|
||||
reference_column = $8,
|
||||
display_column = $9,
|
||||
is_visible = $10,
|
||||
display_order = $11,
|
||||
description = $12,
|
||||
updated_date = $14`,
|
||||
[
|
||||
tableName,
|
||||
columnName,
|
||||
additionalSettings?.columnLabel || null,
|
||||
webType,
|
||||
additionalSettings?.detailSettings
|
||||
? JSON.stringify(additionalSettings.detailSettings)
|
||||
: null,
|
||||
code_category: additionalSettings?.codeCategory,
|
||||
reference_table: additionalSettings?.referenceTable,
|
||||
reference_column: additionalSettings?.referenceColumn,
|
||||
is_visible: additionalSettings?.isVisible ?? true,
|
||||
display_order: additionalSettings?.displayOrder ?? 0,
|
||||
description: additionalSettings?.description,
|
||||
updated_date: new Date(),
|
||||
},
|
||||
create: {
|
||||
table_name: tableName,
|
||||
column_name: columnName,
|
||||
column_label: additionalSettings?.columnLabel,
|
||||
web_type: webType,
|
||||
detail_settings: additionalSettings?.detailSettings
|
||||
? JSON.stringify(additionalSettings.detailSettings)
|
||||
: null,
|
||||
code_category: additionalSettings?.codeCategory,
|
||||
reference_table: additionalSettings?.referenceTable,
|
||||
reference_column: additionalSettings?.referenceColumn,
|
||||
is_visible: additionalSettings?.isVisible ?? true,
|
||||
display_order: additionalSettings?.displayOrder ?? 0,
|
||||
description: additionalSettings?.description,
|
||||
created_date: new Date(),
|
||||
},
|
||||
});
|
||||
additionalSettings?.codeCategory || null,
|
||||
additionalSettings?.referenceTable || null,
|
||||
additionalSettings?.referenceColumn || null,
|
||||
(additionalSettings as any)?.displayColumn || null,
|
||||
additionalSettings?.isVisible ?? true,
|
||||
additionalSettings?.displayOrder ?? 0,
|
||||
additionalSettings?.description || null,
|
||||
new Date(),
|
||||
new Date(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1767,20 +1752,16 @@ export class ScreenManagementService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 화면 코드 자동 생성 (회사코드 + '_' + 순번)
|
||||
* 화면 코드 자동 생성 (회사코드 + '_' + 순번) (✅ Raw Query 전환 완료)
|
||||
*/
|
||||
async generateScreenCode(companyCode: string): Promise<string> {
|
||||
// 해당 회사의 기존 화면 코드들 조회
|
||||
const existingScreens = await prisma.screen_definitions.findMany({
|
||||
where: {
|
||||
company_code: companyCode,
|
||||
screen_code: {
|
||||
startsWith: companyCode,
|
||||
},
|
||||
},
|
||||
select: { screen_code: true },
|
||||
orderBy: { screen_code: "desc" },
|
||||
});
|
||||
// 해당 회사의 기존 화면 코드들 조회 (Raw Query)
|
||||
const existingScreens = await query<{ screen_code: string }>(
|
||||
`SELECT screen_code FROM screen_definitions
|
||||
WHERE company_code = $1 AND screen_code LIKE $2
|
||||
ORDER BY screen_code DESC`,
|
||||
[companyCode, `${companyCode}%`]
|
||||
);
|
||||
|
||||
// 회사 코드 뒤의 숫자 부분 추출하여 최대값 찾기
|
||||
let maxNumber = 0;
|
||||
@@ -1902,11 +1883,11 @@ export class ScreenManagementService {
|
||||
sourceLayout.component_type,
|
||||
newComponentId,
|
||||
newParentId,
|
||||
sourceLayout.position_x,
|
||||
sourceLayout.position_y,
|
||||
sourceLayout.width,
|
||||
sourceLayout.height,
|
||||
typeof sourceLayout.properties === 'string'
|
||||
Math.round(sourceLayout.position_x), // 정수로 반올림
|
||||
Math.round(sourceLayout.position_y), // 정수로 반올림
|
||||
Math.round(sourceLayout.width), // 정수로 반올림
|
||||
Math.round(sourceLayout.height), // 정수로 반올림
|
||||
typeof sourceLayout.properties === "string"
|
||||
? sourceLayout.properties
|
||||
: JSON.stringify(sourceLayout.properties),
|
||||
sourceLayout.display_order,
|
||||
|
||||
Reference in New Issue
Block a user