화면관리 설계

This commit is contained in:
kjs 2025-09-01 10:19:47 +09:00
parent b0e450a90a
commit aa969f0cb2
1 changed files with 448 additions and 82 deletions

View File

@ -19,15 +19,16 @@
### 화면관리 시스템이란?
화면관리 시스템은 실제 서비스되는 화면을 드래그앤드롭으로 설계하고 관리할 수 있는 시스템입니다. 테이블 타입관리와 연계하여 각 필드가 웹에서 어떻게 표시될지를 정의하고, 사용자가 직관적으로 화면을 구성할 수 있습니다.
화면관리 시스템은 사용자가 속한 회사에 맞춰 화면을 드래그앤드롭으로 설계하고 관리할 수 있는 시스템입니다. 테이블 타입관리와 연계하여 각 필드가 웹에서 어떻게 표시될지를 정의하고, 사용자가 직관적으로 화면을 구성할 수 있습니다.
### 주요 특징
- **회사별 화면 관리**: 사용자 회사 코드에 따른 화면 접근 제어
- **드래그앤드롭 인터페이스**: 직관적인 화면 설계
- **컨테이너 그룹화**: 컴포넌트를 깔끔하게 정렬하는 그룹 기능
- **테이블 타입 연계**: 컬럼의 웹 타입에 따른 자동 위젯 생성
- **실시간 미리보기**: 설계한 화면을 즉시 확인 가능
- **반응형 디자인**: 다양한 화면 크기에 대응
- **템플릿 시스템**: 재사용 가능한 화면 템플릿 제공
- **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인 가능
- **메뉴 연동**: 각 회사의 메뉴에 화면 할당 및 관리
### 🎯 **현재 테이블 구조와 100% 호환**
@ -42,6 +43,15 @@
**별도의 테이블 구조 변경 없이 바로 개발 가능!** 🚀
### 🏢 **회사별 화면 관리 시스템**
**사용자 권한에 따른 화면 접근 제어:**
- ✅ **일반 사용자**: 자신이 속한 회사의 화면만 제작/수정 가능
- ✅ **관리자 (회사코드 '\*')**: 모든 회사의 화면을 제어 가능
- ✅ **회사별 메뉴 할당**: 각 회사의 메뉴에만 화면 할당 가능
- ✅ **권한 격리**: 회사 간 화면 데이터 완전 분리
### 지원하는 웹 타입
테이블 타입관리에서 각 컬럼별로 설정할 수 있는 웹 타입입니다:
@ -118,6 +128,25 @@
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### 회사별 권한 관리 구조
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 사용자 │ │ 권한 검증 │ │ 화면 데이터 │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ 회사코드 │ │───▶│ │ 권한 검증 │ │───▶│ │ 회사별 │ │
│ │ (company_ │ │ │ │ 미들웨어 │ │ │ │ 화면 │ │
│ │ code) │ │ │ │ │ │ │ │ 격리 │ │
│ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ 권한 레벨 │ │ │ │ 회사별 │ │ │ │ 메뉴 할당 │ │
│ │ (admin: '*')│ │ │ │ 데이터 │ │ │ │ 제한 │ │
│ └─────────────┘ │ │ │ 필터링 │ │ │ └─────────────┘ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
### 데이터 흐름
1. **테이블 타입 정의**: 테이블 타입관리에서 컬럼의 웹 타입 설정
@ -132,28 +161,42 @@
- **드래그앤드롭 인터페이스**: 컴포넌트를 캔버스에 배치
- **그리드 시스템**: 12컬럼 그리드 기반 레이아웃
- **반응형 설정**: 화면 크기별 레이아웃 조정
- **실시간 미리보기**: 설계한 화면을 즉시 확인
- **컨테이너 그룹화**: 컴포넌트를 깔끔하게 정렬하는 그룹 기능
- **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인
### 2. 컴포넌트 라이브러리
- **입력 컴포넌트**: text, number, date, textarea 등
- **선택 컴포넌트**: select, checkbox, radio 등
- **표시 컴포넌트**: label, display, image 등
- **레이아웃 컴포넌트**: container, row, column 등
- **레이아웃 컴포넌트**: container, row, column, group 등
- **컨테이너 컴포넌트**: 컴포넌트들을 그룹으로 묶는 기능
### 3. 테이블 연계 시스템
### 3. 회사별 권한 관리
- **회사 코드 기반 접근 제어**: 사용자 회사 코드에 따른 화면 접근
- **관리자 권한**: 회사 코드 '\*'인 사용자는 모든 회사 화면 제어
- **회사별 메뉴 할당**: 각 회사의 메뉴에만 화면 할당 가능
- **데이터 격리**: 회사 간 화면 데이터 완전 분리
### 4. 테이블 연계 시스템
- **자동 위젯 생성**: 컬럼의 웹 타입에 따른 위젯 자동 생성
- **데이터 바인딩**: 컬럼과 위젯의 자동 연결
- **유효성 검증**: 컬럼 설정에 따른 자동 검증 규칙 적용
### 4. 템플릿 시스템
### 5. 템플릿 시스템
- **기본 템플릿**: CRUD, 목록, 상세 등 기본 패턴
- **사용자 정의 템플릿**: 자주 사용하는 레이아웃 저장
- **템플릿 공유**: 팀원 간 템플릿 공유 및 재사용
### 6. 메뉴 연동 시스템
- **회사별 메뉴 할당**: 각 회사의 메뉴에만 화면 할당
- **메뉴-화면 연결**: 메뉴와 화면의 1:1 또는 1:N 연결
- **권한 기반 메뉴 표시**: 사용자 권한에 따른 메뉴 표시 제어
## 🗄️ 데이터베이스 설계
### 1. 기존 테이블 구조 (테이블 타입관리)
@ -221,6 +264,7 @@ CREATE TABLE screen_definitions (
screen_name VARCHAR(100) NOT NULL,
screen_code VARCHAR(50) UNIQUE NOT NULL,
table_name VARCHAR(100) NOT NULL, -- 🎯 table_labels와 연계
company_code VARCHAR(50) NOT NULL, -- 🎯 회사 코드 (권한 관리용)
description TEXT,
is_active CHAR(1) DEFAULT 'Y',
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
@ -232,6 +276,9 @@ CREATE TABLE screen_definitions (
CONSTRAINT fk_screen_definitions_table_name
FOREIGN KEY (table_name) REFERENCES table_labels(table_name)
);
-- 회사 코드 인덱스 추가
CREATE INDEX idx_screen_definitions_company_code ON screen_definitions(company_code);
```
#### screen_layouts (화면 레이아웃)
@ -283,12 +330,43 @@ CREATE TABLE screen_templates (
template_id SERIAL PRIMARY KEY,
template_name VARCHAR(100) NOT NULL,
template_type VARCHAR(50) NOT NULL, -- CRUD, LIST, DETAIL 등
company_code VARCHAR(50) NOT NULL, -- 🎯 회사 코드 (권한 관리용)
description TEXT,
layout_data JSONB, -- 레이아웃 데이터
is_public BOOLEAN DEFAULT FALSE, -- 공개 여부
created_by VARCHAR(50),
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 회사 코드 인덱스 추가
CREATE INDEX idx_screen_templates_company_code ON screen_templates(company_code);
```
#### screen_menu_assignments (화면-메뉴 할당)
```sql
CREATE TABLE screen_menu_assignments (
assignment_id SERIAL PRIMARY KEY,
screen_id INTEGER NOT NULL,
menu_id INTEGER NOT NULL,
company_code VARCHAR(50) NOT NULL, -- 🎯 회사 코드 (권한 관리용)
display_order INTEGER DEFAULT 0,
is_active CHAR(1) DEFAULT 'Y',
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by VARCHAR(50),
-- 외래키 제약조건
CONSTRAINT fk_screen_menu_assignments_screen_id
FOREIGN KEY (screen_id) REFERENCES screen_definitions(screen_id),
CONSTRAINT fk_screen_menu_assignments_menu_id
FOREIGN KEY (menu_id) REFERENCES menu_info(menu_id),
-- 유니크 제약조건 (한 메뉴에 같은 화면 중복 할당 방지)
CONSTRAINT uk_screen_menu_company UNIQUE (screen_id, menu_id, company_code)
);
-- 회사 코드 인덱스 추가
CREATE INDEX idx_screen_menu_assignments_company_code ON screen_menu_assignments(company_code);
```
### 3. 테이블 간 연계 관계
@ -303,6 +381,8 @@ screen_definitions (화면 정의)
screen_layouts (화면 레이아웃)
↓ (1:N)
screen_widgets (화면 위젯)
↓ (1:N)
screen_menu_assignments (화면-메뉴 할당)
```
**핵심 연계 포인트:**
@ -310,6 +390,8 @@ screen_widgets (화면 위젯)
- ✅ `screen_definitions.table_name``table_labels.table_name`
- ✅ `screen_widgets.table_name, column_name``column_labels.table_name, column_name`
- ✅ `screen_widgets.widget_type``column_labels.web_type` (자동 동기화)
- ✅ `screen_definitions.company_code` ↔ 사용자 회사 코드 (권한 관리)
- ✅ `screen_menu_assignments.company_code` ↔ 메뉴 회사 코드 (메뉴 할당 제한)
## 🎨 화면 구성 요소
@ -327,6 +409,29 @@ interface ContainerProps {
margin: number;
backgroundColor?: string;
border?: string;
borderRadius?: number;
shadow?: string;
}
```
#### Group (그룹)
```typescript
interface GroupProps {
id: string;
type: "group";
title?: string;
width: number; // 1-12
height: number;
padding: number;
margin: number;
backgroundColor?: string;
border?: string;
borderRadius?: number;
shadow?: string;
collapsible?: boolean; // 접을 수 있는 그룹
collapsed?: boolean; // 접힌 상태
children: string[]; // 포함된 컴포넌트 ID 목록
}
```
@ -440,8 +545,18 @@ interface DragState {
draggedItem: ComponentData | null;
dragSource: "toolbox" | "canvas";
dropTarget: string | null;
dropZone?: DropZone; // 드롭 가능한 영역 정보
}
// 그룹화 상태 관리
interface GroupState {
isGrouping: boolean;
selectedComponents: string[];
groupTarget: string | null;
groupMode: "create" | "add" | "remove";
}
```
// 드롭 영역 정의
interface DropZone {
id: string;
@ -449,7 +564,8 @@ interface DropZone {
position: { x: number; y: number };
size: { width: number; height: number };
}
```
````
### 2. 컴포넌트 배치 로직
@ -478,7 +594,7 @@ function resizeComponent(
height: Math.max(50, newHeight),
};
}
```
````
### 3. 실시간 미리보기
@ -492,6 +608,24 @@ function generatePreview(layout: LayoutData): React.ReactElement {
);
}
// 그룹 컴포넌트 렌더링
function renderGroupComponent(
group: GroupProps,
components: ComponentData[]
): React.ReactElement {
const groupChildren = components.filter((c) => group.children.includes(c.id));
return (
<div className="component-group" style={getGroupStyles(group)}>
{group.title && <div className="group-title">{group.title}</div>}
<div className="group-content">
{groupChildren.map((component) => renderComponent(component))}
</div>
</div>
);
}
```
// 컴포넌트 렌더링
function renderComponent(component: ComponentData): React.ReactElement {
switch (component.type) {
@ -505,7 +639,8 @@ function renderComponent(component: ComponentData): React.ReactElement {
return <div>Unknown component</div>;
}
}
```
````
## 🔗 테이블 타입 연계
@ -552,7 +687,7 @@ async function getTableColumnWebTypes(
): Promise<ColumnWebTypeSetting[]> {
return api.get(`/table-management/tables/${tableName}/columns/web-types`);
}
```
````
#### 웹 타입별 추가 설정 (현재 테이블 구조 기반)
@ -798,10 +933,15 @@ function generateValidationRules(column: ColumnInfo): ValidationRule[] {
### 1. 화면 정의 API
#### 화면 목록 조회
#### 화면 목록 조회 (회사별)
```typescript
GET /api/screen-management/screens
Query: {
companyCode?: string; // 회사 코드 (관리자는 생략 가능)
page?: number;
size?: number;
}
Response: {
success: boolean;
data: ScreenDefinition[];
@ -809,6 +949,19 @@ Response: {
}
```
#### 화면 생성 (회사별)
```typescript
POST /api/screen-management/screens
Body: {
screenName: string;
screenCode: string;
tableName: string;
companyCode: string; // 사용자 회사 코드 자동 설정
description?: string;
}
```
#### 화면 생성
```typescript
@ -896,17 +1049,44 @@ Body: {
### 4. 템플릿 API
#### 템플릿 목록 조회
#### 템플릿 목록 조회 (회사별)
```typescript
GET /api/screen-management/templates
Query: {
companyCode?: string; // 회사 코드 (관리자는 생략 가능)
type?: string;
isPublic?: boolean;
createdBy?: string;
}
```
### 5. 메뉴 할당 API
#### 화면-메뉴 할당
```typescript
POST /api/screen-management/screens/:screenId/menu-assignments
Body: {
menuId: number;
companyCode: string; // 사용자 회사 코드 자동 설정
displayOrder?: number;
}
```
#### 메뉴별 화면 목록 조회
```typescript
GET /api/screen-management/menus/:menuId/screens
Query: {
companyCode: string; // 회사 코드 필수
}
Response: {
success: boolean;
data: ScreenDefinition[];
}
```
#### 템플릿 적용
```typescript
@ -934,6 +1114,14 @@ export default function ScreenDesigner() {
dragSource: "toolbox",
dropTarget: null,
});
const [groupState, setGroupState] = useState<GroupState>({
isGrouping: false,
selectedComponents: [],
groupTarget: null,
groupMode: "create",
});
const [userCompanyCode, setUserCompanyCode] = useState<string>("");
```
// 컴포넌트 추가
const addComponent = (component: ComponentData) => {
@ -961,6 +1149,49 @@ export default function ScreenDesigner() {
}));
};
// 컴포넌트 그룹화
const groupComponents = (componentIds: string[], groupTitle?: string) => {
const groupId = generateId();
const groupComponent: GroupProps = {
id: groupId,
type: "group",
title: groupTitle || "그룹",
width: 12,
height: 200,
padding: 16,
margin: 8,
backgroundColor: "#f8f9fa",
border: "1px solid #dee2e6",
borderRadius: 8,
shadow: "0 2px 4px rgba(0,0,0,0.1)",
collapsible: true,
collapsed: false,
children: componentIds,
};
setLayout((prev) => ({
...prev,
components: [...prev.components, groupComponent],
}));
};
// 그룹에서 컴포넌트 제거
const ungroupComponent = (componentId: string, groupId: string) => {
setLayout((prev) => ({
...prev,
components: prev.components.map((c) => {
if (c.id === groupId && c.type === "group") {
return {
...c,
children: c.children.filter((id) => id !== componentId),
};
}
return c;
}),
}));
};
return (
<div className="screen-designer">
<Toolbox onComponentSelect={addComponent} />
@ -976,12 +1207,21 @@ export default function ScreenDesigner() {
<PropertiesPanel
component={layout.components.find((c) => c.id === selectedComponent)}
onPropertyChange={updateComponentProperty}
onGroupCreate={groupComponents}
onGroupRemove={ungroupComponent}
/>
<PreviewPanel layout={layout} />
<GroupingToolbar
groupState={groupState}
onGroupStateChange={setGroupState}
onGroupCreate={groupComponents}
onGroupRemove={ungroupComponent}
/>
</div>
);
}
```
````
### 2. 드래그앤드롭 구현
@ -1024,7 +1264,7 @@ export function useDragAndDrop() {
updateDropTarget,
};
}
```
````
### 3. 그리드 시스템
@ -1045,6 +1285,56 @@ export default function GridSystem({ children, columns = 12 }) {
);
}
// 그룹화 도구 모음
export function GroupingToolbar({
groupState,
onGroupStateChange,
onGroupCreate,
onGroupRemove,
}) {
const handleGroupCreate = () => {
if (groupState.selectedComponents.length > 1) {
const groupTitle = prompt("그룹 제목을 입력하세요:");
onGroupCreate(groupState.selectedComponents, groupTitle);
onGroupStateChange({
...groupState,
isGrouping: false,
selectedComponents: [],
});
}
};
const handleGroupRemove = () => {
if (groupState.groupTarget) {
onGroupRemove(groupState.selectedComponents[0], groupState.groupTarget);
onGroupStateChange({
...groupState,
isGrouping: false,
selectedComponents: [],
});
}
};
return (
<div className="grouping-toolbar">
<button
onClick={handleGroupCreate}
disabled={groupState.selectedComponents.length < 2}
className="btn btn-primary"
>
그룹 생성
</button>
<button
onClick={handleGroupRemove}
disabled={!groupState.groupTarget}
className="btn btn-secondary"
>
그룹 해제
</button>
</div>
);
}
// GridItem.tsx
interface GridItemProps {
width: number; // 1-12
@ -1080,15 +1370,22 @@ export default function GridItem({
```typescript
// screenManagementService.ts
export class ScreenManagementService {
// 화면 정의 생성
// 화면 정의 생성 (회사별)
async createScreen(
screenData: CreateScreenRequest
screenData: CreateScreenRequest,
userCompanyCode: string
): Promise<ScreenDefinition> {
// 권한 검증: 사용자 회사 코드 확인
if (userCompanyCode !== "*" && userCompanyCode !== screenData.companyCode) {
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,
},
@ -1097,6 +1394,30 @@ export class ScreenManagementService {
return this.mapToScreenDefinition(screen);
}
// 회사별 화면 목록 조회
async getScreensByCompany(
companyCode: string,
page: number = 1,
size: number = 20
): Promise<{ screens: ScreenDefinition[]; total: number }> {
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 {
screens: screens.map(this.mapToScreenDefinition),
total,
};
// 레이아웃 저장
async saveLayout(screenId: number, layoutData: LayoutData): Promise<void> {
// 기존 레이아웃 삭제
@ -1449,7 +1770,23 @@ export class TableTypeIntegrationService {
## 🎬 사용 시나리오
### 1. 웹 타입 설정 (테이블 타입관리)
### 1. 회사별 화면 관리
#### 일반 사용자 (회사 코드: 'COMP001')
1. **로그인**: 자신의 회사 코드로 시스템 로그인
2. **화면 목록 조회**: 자신이 속한 회사의 화면만 표시
3. **화면 생성**: 회사 코드가 자동으로 설정되어 생성
4. **메뉴 할당**: 자신의 회사 메뉴에만 화면 할당 가능
#### 관리자 (회사 코드: '\*')
1. **로그인**: 관리자 권한으로 시스템 로그인
2. **전체 화면 조회**: 모든 회사의 화면을 조회/수정 가능
3. **회사별 화면 관리**: 각 회사별로 화면 생성/수정/삭제
4. **크로스 회사 메뉴 할당**: 모든 회사의 메뉴에 화면 할당 가능
### 2. 웹 타입 설정 (테이블 타입관리)
1. **테이블 선택**: 테이블 타입관리에서 웹 타입을 설정할 테이블 선택
2. **컬럼 관리**: 해당 테이블의 컬럼 목록에서 웹 타입을 설정할 컬럼 선택
@ -1462,38 +1799,48 @@ export class TableTypeIntegrationService {
5. **저장**: 웹 타입 설정을 데이터베이스에 저장
6. **연계 확인**: 화면관리 시스템에서 자동 위젯 생성 확인
### 2. 새로운 화면 설계
### 3. 새로운 화면 설계
1. **테이블 선택**: 테이블 타입관리에서 설계할 테이블 선택
2. **웹 타입 확인**: 각 컬럼의 웹 타입 설정 상태 확인
3. **화면 생성**: 화면명과 코드를 입력하여 새 화면 생성
3. **화면 생성**: 화면명과 코드를 입력하여 새 화면 생성 (회사 코드 자동 설정)
4. **자동 위젯 생성**: 컬럼의 웹 타입에 따라 자동으로 위젯 생성
5. **컴포넌트 배치**: 드래그앤드롭으로 컴포넌트를 캔버스에 배치
6. **속성 설정**: 각 컴포넌트의 속성을 Properties 패널에서 설정
7. **미리보기**: 실시간으로 설계한 화면 확인
8. **저장**: 완성된 화면 레이아웃을 데이터베이스에 저장
6. **컨테이너 그룹화**: 관련 컴포넌트들을 그룹으로 묶어 깔끔하게 정렬
7. **속성 설정**: 각 컴포넌트의 속성을 Properties 패널에서 설정
8. **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인
9. **저장**: 완성된 화면 레이아웃을 데이터베이스에 저장
### 2. 기존 화면 수정
### 4. 기존 화면 수정
1. **화면 선택**: 수정할 화면을 목록에서 선택
1. **화면 선택**: 수정할 화면을 목록에서 선택 (권한 확인)
2. **레이아웃 로드**: 기존 레이아웃을 캔버스에 로드
3. **컴포넌트 수정**: 컴포넌트 추가/삭제/이동/수정
4. **속성 변경**: 컴포넌트 속성 변경
5. **변경사항 확인**: 미리보기로 변경사항 확인
6. **저장**: 수정된 레이아웃 저장
4. **그룹 구조 조정**: 컴포넌트 그룹화/그룹 해제/그룹 속성 변경
5. **속성 변경**: 컴포넌트 속성 변경
6. **변경사항 확인**: 실시간 미리보기로 변경사항 확인
7. **저장**: 수정된 레이아웃 저장
### 3. 템플릿 활용
### 5. 템플릿 활용
1. **템플릿 선택**: 적합한 템플릿을 목록에서 선택
1. **템플릿 선택**: 적합한 템플릿을 목록에서 선택 (회사별 템플릿)
2. **템플릿 적용**: 선택한 템플릿을 현재 화면에 적용
3. **커스터마이징**: 템플릿을 기반으로 필요한 부분 수정
4. **저장**: 커스터마이징된 화면 저장
### 4. 화면 배포
### 6. 메뉴 할당 및 관리
1. **메뉴 선택**: 화면을 할당할 메뉴 선택 (회사별 메뉴만 표시)
2. **화면 할당**: 선택한 화면을 메뉴에 할당
3. **할당 순서 조정**: 메뉴 내 화면 표시 순서 조정
4. **할당 해제**: 메뉴에서 화면 할당 해제
5. **권한 확인**: 메뉴 할당 시 회사 코드 일치 여부 확인
### 7. 화면 배포
1. **화면 활성화**: 설계 완료된 화면을 활성 상태로 변경
2. **권한 설정**: 화면 접근 권한 설정
3. **메뉴 연결**: 메뉴 시스템에 화면 연결
2. **권한 설정**: 화면 접근 권한 설정 (회사별 권한)
3. **메뉴 연결**: 메뉴 시스템에 화면 연결 (회사별 메뉴)
4. **테스트**: 실제 환경에서 화면 동작 테스트
5. **배포**: 운영 환경에 화면 배포
@ -1545,6 +1892,25 @@ export class TableTypeIntegrationService {
## 🎯 결론
화면관리 시스템은 테이블 타입관리와 연계하여 사용자가 직관적으로 웹 화면을 설계할 수 있는 강력한 도구입니다. 드래그앤드롭 인터페이스와 자동 위젯 생성 기능을 통해 개발자가 아닌 사용자도 전문적인 웹 화면을 쉽게 구성할 수 있습니다.
화면관리 시스템은 **회사별 권한 관리**와 **테이블 타입관리 연계**를 통해 사용자가 직관적으로 웹 화면을 설계할 수 있는 강력한 도구입니다.
이 시스템을 통해 ERP 시스템의 화면 개발 생산성을 크게 향상시키고, 사용자 요구사항에 따른 빠른 화면 구성이 가능해질 것입니다.
### 🏢 **회사별 화면 관리의 핵심 가치**
- **권한 격리**: 사용자는 자신이 속한 회사의 화면만 제작/수정 가능
- **관리자 통제**: 회사 코드 '\*'인 관리자는 모든 회사의 화면을 제어
- **메뉴 연동**: 각 회사의 메뉴에만 화면 할당하여 완벽한 데이터 분리
### 🎨 **향상된 사용자 경험**
- **드래그앤드롭 인터페이스**: 직관적인 화면 설계
- **컨테이너 그룹화**: 컴포넌트를 깔끔하게 정렬하는 그룹 기능
- **실시간 미리보기**: 설계한 화면을 실제 화면과 동일하게 확인
- **자동 위젯 생성**: 컬럼의 웹 타입에 따른 스마트한 위젯 생성
### 🚀 **기술적 혜택**
- **기존 테이블 구조 100% 호환**: 별도 스키마 변경 없이 바로 개발 가능
- **권한 기반 보안**: 회사 간 데이터 완전 격리
- **확장 가능한 아키텍처**: 새로운 웹 타입과 컴포넌트 쉽게 추가
이 시스템을 통해 ERP 시스템의 화면 개발 생산성을 크게 향상시키고, **회사별 맞춤형 화면 구성**과 **사용자 요구사항에 따른 빠른 화면 구성**이 가능해질 것입니다.