619 lines
17 KiB
TypeScript
619 lines
17 KiB
TypeScript
|
|
import prisma from "../config/database";
|
||
|
|
import {
|
||
|
|
ScreenDefinition,
|
||
|
|
CreateScreenRequest,
|
||
|
|
UpdateScreenRequest,
|
||
|
|
LayoutData,
|
||
|
|
SaveLayoutRequest,
|
||
|
|
ScreenTemplate,
|
||
|
|
MenuAssignmentRequest,
|
||
|
|
PaginatedResponse,
|
||
|
|
ComponentData,
|
||
|
|
ColumnInfo,
|
||
|
|
ColumnWebTypeSetting,
|
||
|
|
WebType,
|
||
|
|
WidgetData,
|
||
|
|
} from "../types/screen";
|
||
|
|
import { generateId } from "../utils/generateId";
|
||
|
|
|
||
|
|
export class ScreenManagementService {
|
||
|
|
// ========================================
|
||
|
|
// 화면 정의 관리
|
||
|
|
// ========================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면 정의 생성
|
||
|
|
*/
|
||
|
|
async createScreen(
|
||
|
|
screenData: CreateScreenRequest,
|
||
|
|
userCompanyCode: string
|
||
|
|
): Promise<ScreenDefinition> {
|
||
|
|
// 화면 코드 중복 확인
|
||
|
|
const existingScreen = await prisma.screen_definitions.findUnique({
|
||
|
|
where: { screen_code: screenData.screenCode },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (existingScreen) {
|
||
|
|
throw new Error("이미 존재하는 화면 코드입니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
const screen = await prisma.screen_definitions.create({
|
||
|
|
data: {
|
||
|
|
screen_name: screenData.screenName,
|
||
|
|
screen_code: screenData.screenCode,
|
||
|
|
table_name: screenData.tableName,
|
||
|
|
company_code: screenData.companyCode,
|
||
|
|
description: screenData.description,
|
||
|
|
created_by: screenData.createdBy,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
return this.mapToScreenDefinition(screen);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 회사별 화면 목록 조회 (페이징 지원)
|
||
|
|
*/
|
||
|
|
async getScreensByCompany(
|
||
|
|
companyCode: string,
|
||
|
|
page: number = 1,
|
||
|
|
size: number = 20
|
||
|
|
): Promise<PaginatedResponse<ScreenDefinition>> {
|
||
|
|
const whereClause =
|
||
|
|
companyCode === "*" ? {} : { company_code: companyCode };
|
||
|
|
|
||
|
|
const [screens, total] = await Promise.all([
|
||
|
|
prisma.screen_definitions.findMany({
|
||
|
|
where: whereClause,
|
||
|
|
skip: (page - 1) * size,
|
||
|
|
take: size,
|
||
|
|
orderBy: { created_date: "desc" },
|
||
|
|
}),
|
||
|
|
prisma.screen_definitions.count({ where: whereClause }),
|
||
|
|
]);
|
||
|
|
|
||
|
|
return {
|
||
|
|
data: screens.map((screen) => this.mapToScreenDefinition(screen)),
|
||
|
|
pagination: {
|
||
|
|
page,
|
||
|
|
size,
|
||
|
|
total,
|
||
|
|
totalPages: Math.ceil(total / size),
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면 정의 조회
|
||
|
|
*/
|
||
|
|
async getScreenById(screenId: number): Promise<ScreenDefinition | null> {
|
||
|
|
const screen = await prisma.screen_definitions.findUnique({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
});
|
||
|
|
|
||
|
|
return screen ? this.mapToScreenDefinition(screen) : null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면 정의 수정
|
||
|
|
*/
|
||
|
|
async updateScreen(
|
||
|
|
screenId: number,
|
||
|
|
updateData: UpdateScreenRequest,
|
||
|
|
userCompanyCode: string
|
||
|
|
): Promise<ScreenDefinition> {
|
||
|
|
// 권한 검증
|
||
|
|
const screen = await prisma.screen_definitions.findUnique({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!screen) {
|
||
|
|
throw new Error("화면을 찾을 수 없습니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (userCompanyCode !== "*" && userCompanyCode !== screen.company_code) {
|
||
|
|
throw new Error("해당 화면을 수정할 권한이 없습니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
const updatedScreen = await prisma.screen_definitions.update({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
data: {
|
||
|
|
screen_name: updateData.screenName,
|
||
|
|
description: updateData.description,
|
||
|
|
is_active: updateData.isActive,
|
||
|
|
updated_by: updateData.updatedBy,
|
||
|
|
updated_date: new Date(),
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
return this.mapToScreenDefinition(updatedScreen);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면 정의 삭제
|
||
|
|
*/
|
||
|
|
async deleteScreen(screenId: number, userCompanyCode: string): Promise<void> {
|
||
|
|
// 권한 검증
|
||
|
|
const screen = await prisma.screen_definitions.findUnique({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!screen) {
|
||
|
|
throw new Error("화면을 찾을 수 없습니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (userCompanyCode !== "*" && userCompanyCode !== screen.company_code) {
|
||
|
|
throw new Error("해당 화면을 삭제할 권한이 없습니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
// CASCADE로 인해 관련 레이아웃과 위젯도 자동 삭제됨
|
||
|
|
await prisma.screen_definitions.delete({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// ========================================
|
||
|
|
// 레이아웃 관리
|
||
|
|
// ========================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 레이아웃 저장
|
||
|
|
*/
|
||
|
|
async saveLayout(
|
||
|
|
screenId: number,
|
||
|
|
layoutData: SaveLayoutRequest
|
||
|
|
): Promise<void> {
|
||
|
|
// 화면 존재 확인
|
||
|
|
const screen = await prisma.screen_definitions.findUnique({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!screen) {
|
||
|
|
throw new Error("화면을 찾을 수 없습니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
// 기존 레이아웃 삭제
|
||
|
|
await prisma.screen_layouts.deleteMany({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
});
|
||
|
|
|
||
|
|
// 새 레이아웃 저장
|
||
|
|
const layoutPromises = layoutData.components.map((component) =>
|
||
|
|
prisma.screen_layouts.create({
|
||
|
|
data: {
|
||
|
|
screen_id: screenId,
|
||
|
|
component_type: component.type,
|
||
|
|
component_id: component.id,
|
||
|
|
parent_id: component.parentId,
|
||
|
|
position_x: component.position.x,
|
||
|
|
position_y: component.position.y,
|
||
|
|
width: component.size.width,
|
||
|
|
height: component.size.height,
|
||
|
|
properties: component.properties,
|
||
|
|
display_order: component.displayOrder || 0,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
);
|
||
|
|
|
||
|
|
await Promise.all(layoutPromises);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 레이아웃 조회
|
||
|
|
*/
|
||
|
|
async getLayout(screenId: number): Promise<LayoutData | null> {
|
||
|
|
const layouts = await prisma.screen_layouts.findMany({
|
||
|
|
where: { screen_id: screenId },
|
||
|
|
orderBy: { display_order: "asc" },
|
||
|
|
});
|
||
|
|
|
||
|
|
if (layouts.length === 0) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const components: ComponentData[] = layouts.map((layout) => {
|
||
|
|
const baseComponent = {
|
||
|
|
id: layout.component_id,
|
||
|
|
type: layout.component_type as any,
|
||
|
|
position: { x: layout.position_x, y: layout.position_y },
|
||
|
|
size: { width: layout.width, height: layout.height },
|
||
|
|
properties: layout.properties as Record<string, any>,
|
||
|
|
displayOrder: layout.display_order,
|
||
|
|
};
|
||
|
|
|
||
|
|
// 컴포넌트 타입별 추가 속성 처리
|
||
|
|
switch (layout.component_type) {
|
||
|
|
case "group":
|
||
|
|
return {
|
||
|
|
...baseComponent,
|
||
|
|
type: "group",
|
||
|
|
title: (layout.properties as any)?.title,
|
||
|
|
backgroundColor: (layout.properties as any)?.backgroundColor,
|
||
|
|
border: (layout.properties as any)?.border,
|
||
|
|
borderRadius: (layout.properties as any)?.borderRadius,
|
||
|
|
shadow: (layout.properties as any)?.shadow,
|
||
|
|
padding: (layout.properties as any)?.padding,
|
||
|
|
margin: (layout.properties as any)?.margin,
|
||
|
|
collapsible: (layout.properties as any)?.collapsible,
|
||
|
|
collapsed: (layout.properties as any)?.collapsed,
|
||
|
|
children: (layout.properties as any)?.children || [],
|
||
|
|
};
|
||
|
|
case "widget":
|
||
|
|
return {
|
||
|
|
...baseComponent,
|
||
|
|
type: "widget",
|
||
|
|
tableName: (layout.properties as any)?.tableName,
|
||
|
|
columnName: (layout.properties as any)?.columnName,
|
||
|
|
widgetType: (layout.properties as any)?.widgetType,
|
||
|
|
label: (layout.properties as any)?.label,
|
||
|
|
placeholder: (layout.properties as any)?.placeholder,
|
||
|
|
required: (layout.properties as any)?.required,
|
||
|
|
readonly: (layout.properties as any)?.readonly,
|
||
|
|
validationRules: (layout.properties as any)?.validationRules,
|
||
|
|
displayProperties: (layout.properties as any)?.displayProperties,
|
||
|
|
};
|
||
|
|
default:
|
||
|
|
return baseComponent;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return {
|
||
|
|
components,
|
||
|
|
gridSettings: {
|
||
|
|
columns: 12,
|
||
|
|
gap: 16,
|
||
|
|
padding: 16,
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// ========================================
|
||
|
|
// 템플릿 관리
|
||
|
|
// ========================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 템플릿 목록 조회 (회사별)
|
||
|
|
*/
|
||
|
|
async getTemplatesByCompany(
|
||
|
|
companyCode: string,
|
||
|
|
type?: string,
|
||
|
|
isPublic?: boolean
|
||
|
|
): Promise<ScreenTemplate[]> {
|
||
|
|
const whereClause: any = {};
|
||
|
|
|
||
|
|
if (companyCode !== "*") {
|
||
|
|
whereClause.company_code = companyCode;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (type) {
|
||
|
|
whereClause.template_type = type;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isPublic !== undefined) {
|
||
|
|
whereClause.is_public = isPublic;
|
||
|
|
}
|
||
|
|
|
||
|
|
const templates = await prisma.screen_templates.findMany({
|
||
|
|
where: whereClause,
|
||
|
|
orderBy: { created_date: "desc" },
|
||
|
|
});
|
||
|
|
|
||
|
|
return templates.map(this.mapToScreenTemplate);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 템플릿 생성
|
||
|
|
*/
|
||
|
|
async createTemplate(
|
||
|
|
templateData: Partial<ScreenTemplate>
|
||
|
|
): Promise<ScreenTemplate> {
|
||
|
|
const template = await prisma.screen_templates.create({
|
||
|
|
data: {
|
||
|
|
template_name: templateData.templateName!,
|
||
|
|
template_type: templateData.templateType!,
|
||
|
|
company_code: templateData.companyCode!,
|
||
|
|
description: templateData.description,
|
||
|
|
layout_data: templateData.layoutData
|
||
|
|
? JSON.parse(JSON.stringify(templateData.layoutData))
|
||
|
|
: null,
|
||
|
|
is_public: templateData.isPublic || false,
|
||
|
|
created_by: templateData.createdBy,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
return this.mapToScreenTemplate(template);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ========================================
|
||
|
|
// 메뉴 할당 관리
|
||
|
|
// ========================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 화면-메뉴 할당
|
||
|
|
*/
|
||
|
|
async assignScreenToMenu(
|
||
|
|
screenId: number,
|
||
|
|
assignmentData: MenuAssignmentRequest
|
||
|
|
): Promise<void> {
|
||
|
|
// 중복 할당 방지
|
||
|
|
const existingAssignment = await prisma.screen_menu_assignments.findFirst({
|
||
|
|
where: {
|
||
|
|
screen_id: screenId,
|
||
|
|
menu_objid: assignmentData.menuObjid,
|
||
|
|
company_code: assignmentData.companyCode,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
if (existingAssignment) {
|
||
|
|
throw new Error("이미 할당된 화면입니다.");
|
||
|
|
}
|
||
|
|
|
||
|
|
await prisma.screen_menu_assignments.create({
|
||
|
|
data: {
|
||
|
|
screen_id: screenId,
|
||
|
|
menu_objid: assignmentData.menuObjid,
|
||
|
|
company_code: assignmentData.companyCode,
|
||
|
|
display_order: assignmentData.displayOrder || 0,
|
||
|
|
created_by: assignmentData.createdBy,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 메뉴별 화면 목록 조회
|
||
|
|
*/
|
||
|
|
async getScreensByMenu(
|
||
|
|
menuObjid: number,
|
||
|
|
companyCode: string
|
||
|
|
): Promise<ScreenDefinition[]> {
|
||
|
|
const assignments = await prisma.screen_menu_assignments.findMany({
|
||
|
|
where: {
|
||
|
|
menu_objid: menuObjid,
|
||
|
|
company_code: companyCode,
|
||
|
|
is_active: "Y",
|
||
|
|
},
|
||
|
|
include: {
|
||
|
|
screen: true,
|
||
|
|
},
|
||
|
|
orderBy: { display_order: "asc" },
|
||
|
|
});
|
||
|
|
|
||
|
|
return assignments.map((assignment) =>
|
||
|
|
this.mapToScreenDefinition(assignment.screen)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// ========================================
|
||
|
|
// 테이블 타입 연계
|
||
|
|
// ========================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 컬럼 정보 조회 (웹 타입 포함)
|
||
|
|
*/
|
||
|
|
async getColumnInfo(tableName: string): Promise<ColumnInfo[]> {
|
||
|
|
const columns = await prisma.$queryRaw`
|
||
|
|
SELECT
|
||
|
|
c.column_name,
|
||
|
|
COALESCE(cl.column_label, c.column_name) as column_label,
|
||
|
|
c.data_type,
|
||
|
|
COALESCE(cl.web_type, 'text') as web_type,
|
||
|
|
c.is_nullable,
|
||
|
|
c.column_default,
|
||
|
|
c.character_maximum_length,
|
||
|
|
c.numeric_precision,
|
||
|
|
c.numeric_scale,
|
||
|
|
cl.detail_settings,
|
||
|
|
cl.code_category,
|
||
|
|
cl.reference_table,
|
||
|
|
cl.reference_column,
|
||
|
|
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)
|
||
|
|
`;
|
||
|
|
|
||
|
|
return columns as ColumnInfo[];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 웹 타입 설정
|
||
|
|
*/
|
||
|
|
async setColumnWebType(
|
||
|
|
tableName: string,
|
||
|
|
columnName: string,
|
||
|
|
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
|
||
|
|
? 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(),
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 웹 타입별 위젯 생성
|
||
|
|
*/
|
||
|
|
generateWidgetFromColumn(column: ColumnInfo): WidgetData {
|
||
|
|
const baseWidget = {
|
||
|
|
id: generateId(),
|
||
|
|
tableName: column.tableName,
|
||
|
|
columnName: column.columnName,
|
||
|
|
type: column.webType || "text",
|
||
|
|
label: column.columnLabel || column.columnName,
|
||
|
|
required: column.isNullable === "N",
|
||
|
|
readonly: false,
|
||
|
|
};
|
||
|
|
|
||
|
|
// detail_settings JSON 파싱
|
||
|
|
const detailSettings = column.detailSettings
|
||
|
|
? JSON.parse(column.detailSettings)
|
||
|
|
: {};
|
||
|
|
|
||
|
|
switch (column.webType) {
|
||
|
|
case "text":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
maxLength: detailSettings.maxLength || column.characterMaximumLength,
|
||
|
|
placeholder: `Enter ${column.columnLabel || column.columnName}`,
|
||
|
|
pattern: detailSettings.pattern,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "number":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
min: detailSettings.min,
|
||
|
|
max:
|
||
|
|
detailSettings.max ||
|
||
|
|
(column.numericPrecision
|
||
|
|
? Math.pow(10, column.numericPrecision) - 1
|
||
|
|
: undefined),
|
||
|
|
step:
|
||
|
|
detailSettings.step ||
|
||
|
|
(column.numericScale && column.numericScale > 0
|
||
|
|
? Math.pow(10, -column.numericScale)
|
||
|
|
: 1),
|
||
|
|
};
|
||
|
|
|
||
|
|
case "date":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
format: detailSettings.format || "YYYY-MM-DD",
|
||
|
|
minDate: detailSettings.minDate,
|
||
|
|
maxDate: detailSettings.maxDate,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "code":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
codeCategory: column.codeCategory,
|
||
|
|
multiple: detailSettings.multiple || false,
|
||
|
|
searchable: detailSettings.searchable || false,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "entity":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
referenceTable: column.referenceTable,
|
||
|
|
referenceColumn: column.referenceColumn,
|
||
|
|
searchable: detailSettings.searchable || true,
|
||
|
|
multiple: detailSettings.multiple || false,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "textarea":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
rows: detailSettings.rows || 3,
|
||
|
|
maxLength: detailSettings.maxLength || column.characterMaximumLength,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "select":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
options: detailSettings.options || [],
|
||
|
|
multiple: detailSettings.multiple || false,
|
||
|
|
searchable: detailSettings.searchable || false,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "checkbox":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
defaultChecked: detailSettings.defaultChecked || false,
|
||
|
|
label: detailSettings.label || column.columnLabel,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "radio":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
options: detailSettings.options || [],
|
||
|
|
inline: detailSettings.inline || false,
|
||
|
|
};
|
||
|
|
|
||
|
|
case "file":
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
accept: detailSettings.accept || "*/*",
|
||
|
|
maxSize: detailSettings.maxSize || 10485760, // 10MB
|
||
|
|
multiple: detailSettings.multiple || false,
|
||
|
|
};
|
||
|
|
|
||
|
|
default:
|
||
|
|
return {
|
||
|
|
...baseWidget,
|
||
|
|
type: "text",
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ========================================
|
||
|
|
// 유틸리티 메서드
|
||
|
|
// ========================================
|
||
|
|
|
||
|
|
private mapToScreenDefinition(data: any): ScreenDefinition {
|
||
|
|
return {
|
||
|
|
screenId: data.screen_id,
|
||
|
|
screenName: data.screen_name,
|
||
|
|
screenCode: data.screen_code,
|
||
|
|
tableName: data.table_name,
|
||
|
|
companyCode: data.company_code,
|
||
|
|
description: data.description,
|
||
|
|
isActive: data.is_active,
|
||
|
|
createdDate: data.created_date,
|
||
|
|
createdBy: data.created_by,
|
||
|
|
updatedDate: data.updated_date,
|
||
|
|
updatedBy: data.updated_by,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
private mapToScreenTemplate(data: any): ScreenTemplate {
|
||
|
|
return {
|
||
|
|
templateId: data.template_id,
|
||
|
|
templateName: data.template_name,
|
||
|
|
templateType: data.template_type,
|
||
|
|
companyCode: data.company_code,
|
||
|
|
description: data.description,
|
||
|
|
layoutData: data.layout_data,
|
||
|
|
isPublic: data.is_public,
|
||
|
|
createdBy: data.created_by,
|
||
|
|
createdDate: data.created_date,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|