docs: 비즈니스 로직 요청 양식 검증 및 화면 분석 요약 추가
- 비즈니스 로직 요청 시 필수 양식을 명시하고, 미준수 시 대응 방안을 추가하였습니다. - 전체 화면 분석 요약을 업데이트하여 컴포넌트 커버리지 및 신규 컴포넌트 개발 우선순위를 명확히 하였습니다. - 폴더 구조를 정리하고, 각 컴포넌트의 구현 상태를 표기하여 개발자들이 쉽게 참고할 수 있도록 하였습니다.
This commit is contained in:
parent
7a9ec8d02c
commit
4ab2761c82
43
.cursorrules
43
.cursorrules
|
|
@ -1,5 +1,48 @@
|
|||
# Cursor Rules for ERP-node Project
|
||||
|
||||
## 🚨 비즈니스 로직 요청 양식 검증 (필수)
|
||||
|
||||
**사용자가 화면 개발 또는 비즈니스 로직 구현을 요청할 때, 아래 양식을 따르지 않으면 반드시 다음과 같이 응답하세요:**
|
||||
|
||||
```
|
||||
안녕하세요. Oh My Master! 양식을 못 알아 듣겠습니다.
|
||||
다시 한번 작성해주십쇼.
|
||||
=== 비즈니스 로직 요청서 ===
|
||||
|
||||
【화면 정보】
|
||||
- 화면명:
|
||||
- 회사코드:
|
||||
- 메뉴ID (있으면):
|
||||
|
||||
【테이블 정보】
|
||||
- 메인 테이블:
|
||||
- 디테일 테이블 (있으면):
|
||||
- 관계 FK (있으면):
|
||||
|
||||
【버튼 목록】
|
||||
버튼1:
|
||||
- 버튼명:
|
||||
- 동작 유형: (저장/삭제/수정/조회/기타)
|
||||
- 조건 (있으면):
|
||||
- 대상 테이블:
|
||||
- 추가 동작 (있으면):
|
||||
|
||||
【추가 요구사항】
|
||||
-
|
||||
```
|
||||
|
||||
**양식 미준수 판단 기준:**
|
||||
1. "화면 만들어줘" 같이 테이블명/버튼 정보 없이 요청
|
||||
2. "저장하면 저장해줘" 같이 구체적인 테이블/로직 설명 없음
|
||||
3. "이전이랑 비슷하게" 같이 모호한 참조
|
||||
4. 버튼별 조건/동작이 명시되지 않음
|
||||
|
||||
**양식 미준수 시 절대 작업 진행하지 말고, 위 양식을 보여주며 다시 작성하라고 요청하세요.**
|
||||
|
||||
**상세 가이드**: [화면개발_표준_가이드.md](docs/screen-implementation-guide/화면개발_표준_가이드.md)
|
||||
|
||||
---
|
||||
|
||||
## 🚨 최우선 보안 규칙: 멀티테넌시
|
||||
|
||||
**모든 코드 작성/수정 완료 후 반드시 다음 파일을 확인하세요:**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"components": [
|
||||
{
|
||||
"id": "comp_search",
|
||||
"url": "@/lib/registry/components/v2-table-search-widget",
|
||||
"size": { "width": 1920, "height": 80 },
|
||||
"position": { "x": 0, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-table-search-widget",
|
||||
"label": "Search Filter",
|
||||
"webTypeConfig": {}
|
||||
},
|
||||
"displayOrder": 0
|
||||
},
|
||||
{
|
||||
"id": "comp_table",
|
||||
"url": "@/lib/registry/components/v2-table-list",
|
||||
"size": { "width": 1920, "height": 800 },
|
||||
"position": { "x": 0, "y": 150, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-table-list",
|
||||
"label": "Sales Order List",
|
||||
"filter": { "enabled": true, "filters": [] },
|
||||
"height": "auto",
|
||||
"actions": { "actions": [], "bulkActions": false, "showActions": false },
|
||||
"columns": [
|
||||
{ "align": "left", "order": 0, "format": "text", "visible": true, "sortable": true, "columnName": "order_no", "searchable": true, "displayName": "Order No" },
|
||||
{ "align": "left", "order": 1, "format": "text", "visible": true, "sortable": true, "columnName": "partner_id", "searchable": true, "displayName": "Customer" },
|
||||
{ "align": "left", "order": 2, "format": "text", "visible": true, "sortable": true, "columnName": "part_code", "searchable": true, "displayName": "Part Code" },
|
||||
{ "align": "left", "order": 3, "format": "text", "visible": true, "sortable": true, "columnName": "part_name", "searchable": true, "displayName": "Part Name" },
|
||||
{ "align": "left", "order": 4, "format": "text", "visible": true, "sortable": true, "columnName": "spec", "searchable": true, "displayName": "Spec" },
|
||||
{ "align": "left", "order": 5, "format": "text", "visible": true, "sortable": true, "columnName": "material", "searchable": true, "displayName": "Material" },
|
||||
{ "align": "right", "order": 6, "format": "number", "visible": true, "sortable": true, "columnName": "order_qty", "searchable": false, "displayName": "Order Qty" },
|
||||
{ "align": "right", "order": 7, "format": "number", "visible": true, "sortable": true, "columnName": "ship_qty", "searchable": false, "displayName": "Ship Qty" },
|
||||
{ "align": "right", "order": 8, "format": "number", "visible": true, "sortable": true, "columnName": "balance_qty", "searchable": false, "displayName": "Balance" },
|
||||
{ "align": "right", "order": 9, "format": "number", "visible": true, "sortable": true, "columnName": "inventory_qty", "searchable": false, "displayName": "Stock" },
|
||||
{ "align": "right", "order": 10, "format": "number", "visible": true, "sortable": true, "columnName": "plan_ship_qty", "searchable": false, "displayName": "Plan Ship Qty" },
|
||||
{ "align": "right", "order": 11, "format": "number", "visible": true, "sortable": true, "columnName": "unit_price", "searchable": false, "displayName": "Unit Price" },
|
||||
{ "align": "right", "order": 12, "format": "number", "visible": true, "sortable": true, "columnName": "total_amount", "searchable": false, "displayName": "Amount" },
|
||||
{ "align": "left", "order": 13, "format": "text", "visible": true, "sortable": true, "columnName": "delivery_partner_id", "searchable": true, "displayName": "Delivery Partner" },
|
||||
{ "align": "left", "order": 14, "format": "text", "visible": true, "sortable": true, "columnName": "delivery_address", "searchable": true, "displayName": "Delivery Address" },
|
||||
{ "align": "center", "order": 15, "format": "text", "visible": true, "sortable": true, "columnName": "shipping_method", "searchable": true, "displayName": "Shipping Method" },
|
||||
{ "align": "center", "order": 16, "format": "date", "visible": true, "sortable": true, "columnName": "due_date", "searchable": false, "displayName": "Due Date" },
|
||||
{ "align": "center", "order": 17, "format": "date", "visible": true, "sortable": true, "columnName": "order_date", "searchable": false, "displayName": "Order Date" },
|
||||
{ "align": "center", "order": 18, "format": "text", "visible": true, "sortable": true, "columnName": "status", "searchable": true, "displayName": "Status" },
|
||||
{ "align": "left", "order": 19, "format": "text", "visible": true, "sortable": true, "columnName": "manager_name", "searchable": true, "displayName": "Manager" },
|
||||
{ "align": "left", "order": 20, "format": "text", "visible": true, "sortable": true, "columnName": "memo", "searchable": true, "displayName": "Memo" }
|
||||
],
|
||||
"autoLoad": true,
|
||||
"checkbox": { "enabled": true, "multiple": true, "position": "left", "selectAll": true },
|
||||
"pagination": { "enabled": true, "pageSize": 20, "showPageInfo": true, "pageSizeOptions": [10, 20, 50, 100], "showSizeSelector": true },
|
||||
"showFooter": true,
|
||||
"showHeader": true,
|
||||
"tableStyle": { "theme": "default", "rowHeight": "normal", "borderStyle": "light", "headerStyle": "default", "hoverEffect": true, "alternateRows": true },
|
||||
"displayMode": "table",
|
||||
"stickyHeader": false,
|
||||
"selectedTable": "sales_order_mng",
|
||||
"webTypeConfig": {},
|
||||
"horizontalScroll": { "enabled": true, "maxColumnWidth": 300, "minColumnWidth": 80, "maxVisibleColumns": 10 }
|
||||
},
|
||||
"displayOrder": 1
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_upload",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1610, "y": 30, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "Excel Upload",
|
||||
"type": "v2-button-primary",
|
||||
"label": "Excel Upload Button",
|
||||
"action": { "type": "excel_upload" },
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 2
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_download",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 110, "height": 40 },
|
||||
"position": { "x": 1720, "y": 30, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "Excel Download",
|
||||
"type": "v2-button-primary",
|
||||
"label": "Excel Download Button",
|
||||
"action": { "type": "excel_download" },
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 3
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_register",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1500, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "New Order",
|
||||
"type": "v2-button-primary",
|
||||
"label": "New Order Button",
|
||||
"action": {
|
||||
"type": "modal",
|
||||
"modalSize": "lg",
|
||||
"modalTitle": "New Sales Order",
|
||||
"targetScreenId": 3732,
|
||||
"successMessage": "Saved successfully.",
|
||||
"errorMessage": "Error saving."
|
||||
},
|
||||
"variant": "success",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "default", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 4
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_edit",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 80, "height": 40 },
|
||||
"position": { "x": 1610, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "Edit",
|
||||
"type": "v2-button-primary",
|
||||
"label": "Edit Button",
|
||||
"action": {
|
||||
"type": "edit",
|
||||
"modalSize": "lg",
|
||||
"modalTitle": "Edit Sales Order",
|
||||
"targetScreenId": 3732,
|
||||
"successMessage": "Updated successfully.",
|
||||
"errorMessage": "Error updating."
|
||||
},
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 5
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_delete",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 80, "height": 40 },
|
||||
"position": { "x": 1700, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "Delete",
|
||||
"type": "v2-button-primary",
|
||||
"label": "Delete Button",
|
||||
"action": {
|
||||
"type": "delete",
|
||||
"successMessage": "Deleted successfully.",
|
||||
"errorMessage": "Error deleting."
|
||||
},
|
||||
"variant": "danger",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 6
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_shipment",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1790, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "Shipment Plan",
|
||||
"type": "v2-button-primary",
|
||||
"label": "Shipment Plan Button",
|
||||
"action": { "type": "custom" },
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"components": [
|
||||
{
|
||||
"id": "comp_search",
|
||||
"url": "@/lib/registry/components/v2-table-search-widget",
|
||||
"size": { "width": 1920, "height": 80 },
|
||||
"position": { "x": 0, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-table-search-widget",
|
||||
"label": "검색 필터",
|
||||
"webTypeConfig": {}
|
||||
},
|
||||
"displayOrder": 0
|
||||
},
|
||||
{
|
||||
"id": "comp_table",
|
||||
"url": "@/lib/registry/components/v2-table-list",
|
||||
"size": { "width": 1920, "height": 800 },
|
||||
"position": { "x": 0, "y": 150, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-table-list",
|
||||
"label": "수주 목록",
|
||||
"filter": { "enabled": true, "filters": [] },
|
||||
"height": "auto",
|
||||
"actions": { "actions": [], "bulkActions": false, "showActions": false },
|
||||
"columns": [
|
||||
{ "align": "left", "order": 0, "format": "text", "visible": true, "sortable": true, "columnName": "order_no", "searchable": true, "displayName": "수주번호" },
|
||||
{ "align": "left", "order": 1, "format": "text", "visible": true, "sortable": true, "columnName": "partner_id", "searchable": true, "displayName": "거래처" },
|
||||
{ "align": "left", "order": 2, "format": "text", "visible": true, "sortable": true, "columnName": "part_code", "searchable": true, "displayName": "품목코드" },
|
||||
{ "align": "left", "order": 3, "format": "text", "visible": true, "sortable": true, "columnName": "part_name", "searchable": true, "displayName": "품명" },
|
||||
{ "align": "left", "order": 4, "format": "text", "visible": true, "sortable": true, "columnName": "spec", "searchable": true, "displayName": "규격" },
|
||||
{ "align": "left", "order": 5, "format": "text", "visible": true, "sortable": true, "columnName": "material", "searchable": true, "displayName": "재질" },
|
||||
{ "align": "right", "order": 6, "format": "number", "visible": true, "sortable": true, "columnName": "order_qty", "searchable": false, "displayName": "수주수량" },
|
||||
{ "align": "right", "order": 7, "format": "number", "visible": true, "sortable": true, "columnName": "ship_qty", "searchable": false, "displayName": "출하수량" },
|
||||
{ "align": "right", "order": 8, "format": "number", "visible": true, "sortable": true, "columnName": "balance_qty", "searchable": false, "displayName": "잔량" },
|
||||
{ "align": "right", "order": 9, "format": "number", "visible": true, "sortable": true, "columnName": "inventory_qty", "searchable": false, "displayName": "현재고" },
|
||||
{ "align": "right", "order": 10, "format": "number", "visible": true, "sortable": true, "columnName": "plan_ship_qty", "searchable": false, "displayName": "출하계획량" },
|
||||
{ "align": "right", "order": 11, "format": "number", "visible": true, "sortable": true, "columnName": "unit_price", "searchable": false, "displayName": "단가" },
|
||||
{ "align": "right", "order": 12, "format": "number", "visible": true, "sortable": true, "columnName": "total_amount", "searchable": false, "displayName": "금액" },
|
||||
{ "align": "left", "order": 13, "format": "text", "visible": true, "sortable": true, "columnName": "delivery_partner_id", "searchable": true, "displayName": "납품처" },
|
||||
{ "align": "left", "order": 14, "format": "text", "visible": true, "sortable": true, "columnName": "delivery_address", "searchable": true, "displayName": "납품장소" },
|
||||
{ "align": "center", "order": 15, "format": "text", "visible": true, "sortable": true, "columnName": "shipping_method", "searchable": true, "displayName": "배송방법" },
|
||||
{ "align": "center", "order": 16, "format": "date", "visible": true, "sortable": true, "columnName": "due_date", "searchable": false, "displayName": "납기일" },
|
||||
{ "align": "center", "order": 17, "format": "date", "visible": true, "sortable": true, "columnName": "order_date", "searchable": false, "displayName": "수주일" },
|
||||
{ "align": "center", "order": 18, "format": "text", "visible": true, "sortable": true, "columnName": "status", "searchable": true, "displayName": "상태" },
|
||||
{ "align": "left", "order": 19, "format": "text", "visible": true, "sortable": true, "columnName": "manager_name", "searchable": true, "displayName": "담당자" },
|
||||
{ "align": "left", "order": 20, "format": "text", "visible": true, "sortable": true, "columnName": "memo", "searchable": true, "displayName": "메모" }
|
||||
],
|
||||
"autoLoad": true,
|
||||
"checkbox": { "enabled": true, "multiple": true, "position": "left", "selectAll": true },
|
||||
"pagination": { "enabled": true, "pageSize": 20, "showPageInfo": true, "pageSizeOptions": [10, 20, 50, 100], "showSizeSelector": true },
|
||||
"showFooter": true,
|
||||
"showHeader": true,
|
||||
"tableStyle": { "theme": "default", "rowHeight": "normal", "borderStyle": "light", "headerStyle": "default", "hoverEffect": true, "alternateRows": true },
|
||||
"displayMode": "table",
|
||||
"stickyHeader": false,
|
||||
"selectedTable": "sales_order_mng",
|
||||
"webTypeConfig": {},
|
||||
"horizontalScroll": { "enabled": true, "maxColumnWidth": 300, "minColumnWidth": 80, "maxVisibleColumns": 10 }
|
||||
},
|
||||
"displayOrder": 1
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_upload",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1610, "y": 30, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "엑셀 업로드",
|
||||
"type": "v2-button-primary",
|
||||
"label": "엑셀 업로드 버튼",
|
||||
"action": { "type": "excel_upload" },
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 2
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_download",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 110, "height": 40 },
|
||||
"position": { "x": 1720, "y": 30, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "엑셀 다운로드",
|
||||
"type": "v2-button-primary",
|
||||
"label": "엑셀 다운로드 버튼",
|
||||
"action": { "type": "excel_download" },
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 3
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_register",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1500, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "수주 등록",
|
||||
"type": "v2-button-primary",
|
||||
"label": "수주 등록 버튼",
|
||||
"action": {
|
||||
"type": "modal",
|
||||
"modalSize": "lg",
|
||||
"modalTitle": "수주 등록",
|
||||
"targetScreenId": 3732,
|
||||
"successMessage": "저장되었습니다.",
|
||||
"errorMessage": "저장 중 오류가 발생했습니다."
|
||||
},
|
||||
"variant": "success",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "default", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 4
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_edit",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 80, "height": 40 },
|
||||
"position": { "x": 1610, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "수정",
|
||||
"type": "v2-button-primary",
|
||||
"label": "수정 버튼",
|
||||
"action": {
|
||||
"type": "edit",
|
||||
"modalSize": "lg",
|
||||
"modalTitle": "수주 수정",
|
||||
"targetScreenId": 3732,
|
||||
"successMessage": "수정되었습니다.",
|
||||
"errorMessage": "수정 중 오류가 발생했습니다."
|
||||
},
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 5
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_delete",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 80, "height": 40 },
|
||||
"position": { "x": 1700, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "삭제",
|
||||
"type": "v2-button-primary",
|
||||
"label": "삭제 버튼",
|
||||
"action": {
|
||||
"type": "delete",
|
||||
"successMessage": "삭제되었습니다.",
|
||||
"errorMessage": "삭제 중 오류가 발생했습니다."
|
||||
},
|
||||
"variant": "danger",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 6
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_shipment",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1790, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "출하계획",
|
||||
"type": "v2-button-primary",
|
||||
"label": "출하계획 버튼",
|
||||
"action": { "type": "custom" },
|
||||
"variant": "secondary",
|
||||
"actionType": "button",
|
||||
"webTypeConfig": { "variant": "secondary", "actionType": "custom" }
|
||||
},
|
||||
"displayOrder": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"components": [
|
||||
{
|
||||
"id": "comp_order_no",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Order No",
|
||||
"fieldName": "order_no",
|
||||
"placeholder": "Enter order number",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 0
|
||||
},
|
||||
{
|
||||
"id": "comp_order_date",
|
||||
"url": "@/lib/registry/components/v2-date",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-date",
|
||||
"label": "Order Date",
|
||||
"fieldName": "order_date",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 1
|
||||
},
|
||||
{
|
||||
"id": "comp_partner_id",
|
||||
"url": "@/lib/registry/components/v2-select",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-select",
|
||||
"label": "Customer",
|
||||
"fieldName": "partner_id",
|
||||
"required": true,
|
||||
"config": {
|
||||
"mode": "dropdown",
|
||||
"source": "table",
|
||||
"sourceTable": "customer_mng",
|
||||
"valueField": "id",
|
||||
"labelField": "name"
|
||||
}
|
||||
},
|
||||
"displayOrder": 2
|
||||
},
|
||||
{
|
||||
"id": "comp_part_code",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Part Code",
|
||||
"fieldName": "part_code",
|
||||
"placeholder": "Enter part code",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 3
|
||||
},
|
||||
{
|
||||
"id": "comp_part_name",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 180, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Part Name",
|
||||
"fieldName": "part_name",
|
||||
"placeholder": "Enter part name"
|
||||
},
|
||||
"displayOrder": 4
|
||||
},
|
||||
{
|
||||
"id": "comp_spec",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 180, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Spec",
|
||||
"fieldName": "spec",
|
||||
"placeholder": "Enter spec"
|
||||
},
|
||||
"displayOrder": 5
|
||||
},
|
||||
{
|
||||
"id": "comp_material",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 260, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Material",
|
||||
"fieldName": "material",
|
||||
"placeholder": "Enter material"
|
||||
},
|
||||
"displayOrder": 6
|
||||
},
|
||||
{
|
||||
"id": "comp_order_qty",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 260, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"inputType": "number",
|
||||
"label": "Order Qty",
|
||||
"fieldName": "order_qty",
|
||||
"placeholder": "Enter order quantity",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 7
|
||||
},
|
||||
{
|
||||
"id": "comp_unit_price",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 340, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"inputType": "number",
|
||||
"label": "Unit Price",
|
||||
"fieldName": "unit_price",
|
||||
"placeholder": "Enter unit price",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 8
|
||||
},
|
||||
{
|
||||
"id": "comp_due_date",
|
||||
"url": "@/lib/registry/components/v2-date",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 340, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-date",
|
||||
"label": "Due Date",
|
||||
"fieldName": "due_date"
|
||||
},
|
||||
"displayOrder": 9
|
||||
},
|
||||
{
|
||||
"id": "comp_status",
|
||||
"url": "@/lib/registry/components/v2-select",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 420, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-select",
|
||||
"label": "Status",
|
||||
"fieldName": "status",
|
||||
"required": true,
|
||||
"config": {
|
||||
"mode": "dropdown",
|
||||
"source": "static",
|
||||
"options": [
|
||||
{ "value": "수주", "label": "수주" },
|
||||
{ "value": "진행중", "label": "진행중" },
|
||||
{ "value": "완료", "label": "완료" },
|
||||
{ "value": "취소", "label": "취소" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"displayOrder": 10
|
||||
},
|
||||
{
|
||||
"id": "comp_shipping_method",
|
||||
"url": "@/lib/registry/components/v2-select",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 420, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-select",
|
||||
"label": "Shipping Method",
|
||||
"fieldName": "shipping_method",
|
||||
"config": {
|
||||
"mode": "dropdown",
|
||||
"source": "static",
|
||||
"options": [
|
||||
{ "value": "택배", "label": "택배" },
|
||||
{ "value": "화물", "label": "화물" },
|
||||
{ "value": "직송", "label": "직송" },
|
||||
{ "value": "퀵서비스", "label": "퀵서비스" },
|
||||
{ "value": "해상운송", "label": "해상운송" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"displayOrder": 11
|
||||
},
|
||||
{
|
||||
"id": "comp_delivery_address",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 620, "height": 60 },
|
||||
"position": { "x": 20, "y": 500, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Delivery Address",
|
||||
"fieldName": "delivery_address",
|
||||
"placeholder": "Enter delivery address"
|
||||
},
|
||||
"displayOrder": 12
|
||||
},
|
||||
{
|
||||
"id": "comp_manager_name",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 580, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "Manager",
|
||||
"fieldName": "manager_name",
|
||||
"placeholder": "Enter manager name"
|
||||
},
|
||||
"displayOrder": 13
|
||||
},
|
||||
{
|
||||
"id": "comp_memo",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 620, "height": 80 },
|
||||
"position": { "x": 20, "y": 660, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"inputType": "textarea",
|
||||
"label": "Memo",
|
||||
"fieldName": "memo",
|
||||
"placeholder": "Enter memo"
|
||||
},
|
||||
"displayOrder": 14
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_save",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 540, "y": 760, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "Save",
|
||||
"type": "v2-button-primary",
|
||||
"label": "Save Button",
|
||||
"action": {
|
||||
"type": "save",
|
||||
"closeModalAfterSave": true,
|
||||
"refreshParentTable": true,
|
||||
"successMessage": "Saved successfully.",
|
||||
"errorMessage": "Error saving."
|
||||
},
|
||||
"variant": "primary",
|
||||
"actionType": "button"
|
||||
},
|
||||
"displayOrder": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
{
|
||||
"version": "2.0",
|
||||
"components": [
|
||||
{
|
||||
"id": "comp_order_no",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "수주번호",
|
||||
"fieldName": "order_no",
|
||||
"placeholder": "수주번호를 입력하세요",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 0
|
||||
},
|
||||
{
|
||||
"id": "comp_order_date",
|
||||
"url": "@/lib/registry/components/v2-date",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-date",
|
||||
"label": "수주일",
|
||||
"fieldName": "order_date",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 1
|
||||
},
|
||||
{
|
||||
"id": "comp_partner_id",
|
||||
"url": "@/lib/registry/components/v2-select",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-select",
|
||||
"label": "거래처",
|
||||
"fieldName": "partner_id",
|
||||
"required": true,
|
||||
"config": {
|
||||
"mode": "dropdown",
|
||||
"source": "table",
|
||||
"sourceTable": "customer_mng",
|
||||
"valueField": "id",
|
||||
"labelField": "name"
|
||||
}
|
||||
},
|
||||
"displayOrder": 2
|
||||
},
|
||||
{
|
||||
"id": "comp_part_code",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 100, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "품목코드",
|
||||
"fieldName": "part_code",
|
||||
"placeholder": "품목코드를 입력하세요",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 3
|
||||
},
|
||||
{
|
||||
"id": "comp_part_name",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 180, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "품명",
|
||||
"fieldName": "part_name",
|
||||
"placeholder": "품명을 입력하세요"
|
||||
},
|
||||
"displayOrder": 4
|
||||
},
|
||||
{
|
||||
"id": "comp_spec",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 180, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "규격",
|
||||
"fieldName": "spec",
|
||||
"placeholder": "규격을 입력하세요"
|
||||
},
|
||||
"displayOrder": 5
|
||||
},
|
||||
{
|
||||
"id": "comp_material",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 260, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "재질",
|
||||
"fieldName": "material",
|
||||
"placeholder": "재질을 입력하세요"
|
||||
},
|
||||
"displayOrder": 6
|
||||
},
|
||||
{
|
||||
"id": "comp_order_qty",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 260, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"inputType": "number",
|
||||
"label": "수주수량",
|
||||
"fieldName": "order_qty",
|
||||
"placeholder": "수주수량을 입력하세요",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 7
|
||||
},
|
||||
{
|
||||
"id": "comp_unit_price",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 340, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"inputType": "number",
|
||||
"label": "단가",
|
||||
"fieldName": "unit_price",
|
||||
"placeholder": "단가를 입력하세요",
|
||||
"required": true
|
||||
},
|
||||
"displayOrder": 8
|
||||
},
|
||||
{
|
||||
"id": "comp_due_date",
|
||||
"url": "@/lib/registry/components/v2-date",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 340, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-date",
|
||||
"label": "납기일",
|
||||
"fieldName": "due_date"
|
||||
},
|
||||
"displayOrder": 9
|
||||
},
|
||||
{
|
||||
"id": "comp_status",
|
||||
"url": "@/lib/registry/components/v2-select",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 420, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-select",
|
||||
"label": "상태",
|
||||
"fieldName": "status",
|
||||
"required": true,
|
||||
"config": {
|
||||
"mode": "dropdown",
|
||||
"source": "static",
|
||||
"options": [
|
||||
{ "value": "수주", "label": "수주" },
|
||||
{ "value": "진행중", "label": "진행중" },
|
||||
{ "value": "완료", "label": "완료" },
|
||||
{ "value": "취소", "label": "취소" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"displayOrder": 10
|
||||
},
|
||||
{
|
||||
"id": "comp_shipping_method",
|
||||
"url": "@/lib/registry/components/v2-select",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 340, "y": 420, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-select",
|
||||
"label": "배송방법",
|
||||
"fieldName": "shipping_method",
|
||||
"config": {
|
||||
"mode": "dropdown",
|
||||
"source": "static",
|
||||
"options": [
|
||||
{ "value": "택배", "label": "택배" },
|
||||
{ "value": "화물", "label": "화물" },
|
||||
{ "value": "직송", "label": "직송" },
|
||||
{ "value": "퀵서비스", "label": "퀵서비스" },
|
||||
{ "value": "해상운송", "label": "해상운송" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"displayOrder": 11
|
||||
},
|
||||
{
|
||||
"id": "comp_delivery_address",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 620, "height": 60 },
|
||||
"position": { "x": 20, "y": 500, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "납품장소",
|
||||
"fieldName": "delivery_address",
|
||||
"placeholder": "납품장소를 입력하세요"
|
||||
},
|
||||
"displayOrder": 12
|
||||
},
|
||||
{
|
||||
"id": "comp_manager_name",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 300, "height": 60 },
|
||||
"position": { "x": 20, "y": 580, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"label": "담당자",
|
||||
"fieldName": "manager_name",
|
||||
"placeholder": "담당자를 입력하세요"
|
||||
},
|
||||
"displayOrder": 13
|
||||
},
|
||||
{
|
||||
"id": "comp_memo",
|
||||
"url": "@/lib/registry/components/v2-input",
|
||||
"size": { "width": 620, "height": 80 },
|
||||
"position": { "x": 20, "y": 660, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-input",
|
||||
"inputType": "textarea",
|
||||
"label": "메모",
|
||||
"fieldName": "memo",
|
||||
"placeholder": "메모를 입력하세요"
|
||||
},
|
||||
"displayOrder": 14
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_save",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 540, "y": 760, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "저장",
|
||||
"type": "v2-button-primary",
|
||||
"label": "저장 버튼",
|
||||
"action": {
|
||||
"type": "save",
|
||||
"closeModalAfterSave": true,
|
||||
"refreshParentTable": true,
|
||||
"successMessage": "저장되었습니다.",
|
||||
"errorMessage": "저장 중 오류가 발생했습니다."
|
||||
},
|
||||
"variant": "primary",
|
||||
"actionType": "button"
|
||||
},
|
||||
"displayOrder": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
# 화면 전체 분석 보고서
|
||||
|
||||
> **분석 대상**: `/Users/kimjuseok/Downloads/화면개발 8` 폴더 내 핵심 업무 화면
|
||||
> **분석 기준**: 메뉴별 분류, 3개 이상 재활용 가능한 컴포넌트 식별
|
||||
> **분석 일자**: 2026-01-30
|
||||
|
||||
---
|
||||
|
||||
## 1. 현재 사용 중인 V2 컴포넌트 목록
|
||||
|
||||
> **중요**: v2- 접두사가 붙은 컴포넌트만 사용합니다.
|
||||
|
||||
### 입력 컴포넌트
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-input` | V2 입력 | 텍스트, 숫자, 비밀번호, 이메일 등 입력 |
|
||||
| `v2-select` | V2 선택 | 드롭다운, 콤보박스, 라디오, 체크박스 |
|
||||
| `v2-date` | V2 날짜 | 날짜, 시간, 날짜범위 입력 |
|
||||
|
||||
### 표시 컴포넌트
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-text-display` | 텍스트 표시 | 라벨, 텍스트 표시 |
|
||||
| `v2-card-display` | 카드 디스플레이 | 테이블 데이터를 카드 형태로 표시 |
|
||||
| `v2-aggregation-widget` | 집계 위젯 | 합계, 평균, 개수 등 집계 표시 |
|
||||
|
||||
### 테이블/데이터 컴포넌트
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-table-list` | 테이블 리스트 | 데이터 테이블 표시, 페이지네이션, 정렬, 필터 |
|
||||
| `v2-table-search-widget` | 검색 필터 | 화면 내 테이블 검색/필터/그룹 기능 |
|
||||
| `v2-pivot-grid` | 피벗 그리드 | 다차원 데이터 분석 (피벗 테이블) |
|
||||
|
||||
### 레이아웃 컴포넌트
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-split-panel-layout` | 분할 패널 | 마스터-디테일 좌우 분할 레이아웃 |
|
||||
| `v2-tabs-widget` | 탭 위젯 | 탭 전환, 탭 내 컴포넌트 배치 |
|
||||
| `v2-section-card` | Section Card | 제목/테두리가 있는 그룹화 컨테이너 |
|
||||
| `v2-section-paper` | Section Paper | 배경색 기반 미니멀 그룹화 컨테이너 |
|
||||
| `v2-divider-line` | 구분선 | 영역 구분 |
|
||||
| `v2-repeat-container` | 리피터 컨테이너 | 데이터 수만큼 내부 컴포넌트 반복 렌더링 |
|
||||
| `v2-repeater` | 리피터 | 반복 컨트롤 |
|
||||
|
||||
### 액션/기타 컴포넌트
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-button-primary` | 기본 버튼 | 저장, 삭제 등 액션 버튼 |
|
||||
| `v2-numbering-rule` | 채번규칙 | 자동 코드/번호 생성 |
|
||||
| `v2-category-manager` | 카테고리 관리자 | 카테고리 관리 |
|
||||
| `v2-location-swap-selector` | 위치 교환 선택기 | 위치 교환 기능 |
|
||||
| `v2-rack-structure` | 랙 구조 | 창고 랙 시각화 |
|
||||
| `v2-media` | 미디어 | 미디어 표시 |
|
||||
|
||||
**총 23개 V2 컴포넌트**
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 분류 (메뉴별)
|
||||
|
||||
### 01. 기준정보 (master-data)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 회사정보 | 회사정보.html | 검색+테이블 | ✅ 완전 |
|
||||
| 부서정보 | 부서정보.html | 검색+테이블 | ✅ 완전 |
|
||||
| 품목정보 | 품목정보.html | 검색+테이블+그룹화 | ⚠️ 그룹화 미지원 |
|
||||
| BOM관리 | BOM관리.html | 분할패널+트리 | ⚠️ 트리뷰 미지원 |
|
||||
| 공정정보관리 | 공정정보관리.html | 분할패널+테이블 | ✅ 완전 |
|
||||
| 공정작업기준 | 공정작업기준관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 품목라우팅 | 품목라우팅관리.html | 분할패널+테이블 | ✅ 완전 |
|
||||
|
||||
### 02. 영업관리 (sales)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 수주관리 | 수주관리.html | 분할패널+테이블 | ✅ 완전 |
|
||||
| 견적관리 | 견적관리.html | 분할패널+테이블 | ✅ 완전 |
|
||||
| 거래처관리 | 거래처관리.html | 분할패널+탭+그룹화 | ⚠️ 그룹화 미지원 |
|
||||
| 판매품목정보 | 판매품목정보.html | 검색+테이블 | ✅ 완전 |
|
||||
| 출하계획관리 | 출하계획관리.html | 검색+테이블 | ✅ 완전 |
|
||||
|
||||
### 03. 생산관리 (production)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 생산계획관리 | 생산계획관리.html | 분할패널+탭+타임라인 | ❌ 타임라인 미지원 |
|
||||
| 생산관리 | 생산관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 생산실적관리 | 생산실적관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 작업지시 | 작업지시.html | 탭+그룹화테이블+분할패널 | ⚠️ 그룹화 미지원 |
|
||||
| 공정관리 | 공정관리.html | 분할패널+테이블 | ✅ 완전 |
|
||||
|
||||
### 04. 구매관리 (purchase)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 발주관리 | 발주관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 공급업체관리 | 공급업체관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 구매입고 | pages/구매입고.html | 검색+테이블 | ✅ 완전 |
|
||||
|
||||
### 05. 설비관리 (equipment)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 설비정보 | 설비정보.html | 분할패널+카드+탭 | ✅ v2-card-display 활용 |
|
||||
|
||||
### 06. 물류관리 (logistics)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 창고관리 | 창고관리.html | 모바일앱스타일+iframe | ❌ 별도개발 필요 |
|
||||
| 창고정보관리 | 창고정보관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 입출고관리 | 입출고관리.html | 검색+테이블+그룹화 | ⚠️ 그룹화 미지원 |
|
||||
| 재고현황 | 재고현황.html | 검색+테이블 | ✅ 완전 |
|
||||
|
||||
### 07. 품질관리 (quality)
|
||||
| 화면명 | 파일명 | 패턴 | 구현 가능 |
|
||||
|--------|--------|------|----------|
|
||||
| 검사기준 | 검사기준.html | 검색+테이블 | ✅ 완전 |
|
||||
| 검사정보관리 | 검사정보관리.html | 탭+테이블 | ✅ 완전 |
|
||||
| 검사장비관리 | 검사장비관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 불량관리 | 불량관리.html | 검색+테이블 | ✅ 완전 |
|
||||
| 클레임관리 | 클레임관리.html | 검색+테이블 | ✅ 완전 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 화면 UI 패턴 분석
|
||||
|
||||
### 패턴 A: 검색 + 테이블 (가장 기본)
|
||||
**해당 화면**: 약 60% (15개 이상)
|
||||
|
||||
**사용 컴포넌트**:
|
||||
- `v2-table-search-widget`: 검색 필터
|
||||
- `v2-table-list`: 데이터 테이블
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ [검색필드들...] [조회] [엑셀] │ ← v2-table-search-widget
|
||||
├─────────────────────────────────────────┤
|
||||
│ 테이블 제목 [신규등록] [삭제] │
|
||||
│ ────────────────────────────────────── │
|
||||
│ □ | 코드 | 이름 | 상태 | 등록일 | │ ← v2-table-list
|
||||
│ □ | A001 | 테스트| 사용 | 2026-01-30 | │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 패턴 B: 분할 패널 (마스터-디테일)
|
||||
**해당 화면**: 약 25% (8개)
|
||||
|
||||
**사용 컴포넌트**:
|
||||
- `v2-split-panel-layout`: 좌우 분할
|
||||
- `v2-table-list`: 마스터/디테일 테이블
|
||||
- `v2-tabs-widget`: 상세 탭 (선택)
|
||||
|
||||
```
|
||||
┌──────────────────┬──────────────────────┐
|
||||
│ 마스터 리스트 │ 상세 정보 / 탭 │
|
||||
│ ─────────────── │ ┌────┬────┬────┐ │
|
||||
│ □ A001 제품A │ │기본│이력│첨부│ │
|
||||
│ □ A002 제품B ← │ └────┴────┴────┘ │
|
||||
│ □ A003 제품C │ [테이블 or 폼] │
|
||||
└──────────────────┴──────────────────────┘
|
||||
```
|
||||
|
||||
### 패턴 C: 탭 + 테이블
|
||||
**해당 화면**: 약 10% (3개)
|
||||
|
||||
**사용 컴포넌트**:
|
||||
- `v2-tabs-widget`: 탭 전환
|
||||
- `v2-table-list`: 탭별 테이블
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ [탭1] [탭2] [탭3] │
|
||||
├─────────────────────────────────────────┤
|
||||
│ [테이블 영역] │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 패턴 D: 특수 UI
|
||||
**해당 화면**: 약 5% (2개)
|
||||
|
||||
- 생산계획관리: 타임라인/간트 차트 → **v2-timeline 미존재**
|
||||
- 창고관리: 모바일 앱 스타일 → **별도 개발 필요**
|
||||
|
||||
---
|
||||
|
||||
## 4. 신규 컴포넌트 분석 (3개 이상 재활용 기준)
|
||||
|
||||
### 4.1 v2-grouped-table (그룹화 테이블)
|
||||
**재활용 화면 수**: 5개 이상 ✅
|
||||
|
||||
| 화면 | 그룹화 기준 |
|
||||
|------|------------|
|
||||
| 품목정보 | 품목구분, 카테고리 |
|
||||
| 거래처관리 | 거래처유형, 지역 |
|
||||
| 작업지시 | 작업일자, 공정 |
|
||||
| 입출고관리 | 입출고구분, 창고 |
|
||||
| 견적관리 | 상태, 거래처 |
|
||||
|
||||
**기능 요구사항**:
|
||||
- 특정 컬럼 기준 그룹핑
|
||||
- 그룹 접기/펼치기
|
||||
- 그룹 헤더에 집계 표시
|
||||
- 다중 그룹핑 지원
|
||||
|
||||
**구현 복잡도**: 중
|
||||
|
||||
### 4.2 v2-tree-view (트리 뷰)
|
||||
**재활용 화면 수**: 3개 ✅
|
||||
|
||||
| 화면 | 트리 용도 |
|
||||
|------|----------|
|
||||
| BOM관리 | BOM 구조 (정전개/역전개) |
|
||||
| 부서정보 | 조직도 |
|
||||
| 메뉴관리 | 메뉴 계층 |
|
||||
|
||||
**기능 요구사항**:
|
||||
- 노드 접기/펼치기
|
||||
- 드래그앤드롭 (선택)
|
||||
- 정전개/역전개 전환
|
||||
- 노드 선택 이벤트
|
||||
|
||||
**구현 복잡도**: 중상
|
||||
|
||||
### 4.3 v2-timeline-scheduler (타임라인)
|
||||
**재활용 화면 수**: 1~2개 (기준 미달)
|
||||
|
||||
| 화면 | 용도 |
|
||||
|------|------|
|
||||
| 생산계획관리 | 간트 차트 |
|
||||
| 설비 가동 현황 | 타임라인 |
|
||||
|
||||
**기능 요구사항**:
|
||||
- 시간축 기반 배치
|
||||
- 드래그로 일정 변경
|
||||
- 공정별 색상 구분
|
||||
- 줌 인/아웃
|
||||
|
||||
**구현 복잡도**: 상
|
||||
|
||||
> **참고**: 3개 미만이므로 우선순위 하향
|
||||
|
||||
---
|
||||
|
||||
## 5. 컴포넌트 커버리지
|
||||
|
||||
### 현재 V2 컴포넌트로 구현 가능
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 17개 화면 (65%) │
|
||||
│ - 기본 검색 + 테이블 패턴 │
|
||||
│ - 분할 패널 │
|
||||
│ - 탭 전환 │
|
||||
│ - 카드 디스플레이 │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### v2-grouped-table 개발 후
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ +5개 화면 (22개, 85%) │
|
||||
│ - 품목정보, 거래처관리, 작업지시 │
|
||||
│ - 입출고관리, 견적관리 │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### v2-tree-view 개발 후
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ +2개 화면 (24개, 92%) │
|
||||
│ - BOM관리, 부서정보(계층) │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 별도 개발 필요
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 2개 화면 (8%) │
|
||||
│ - 생산계획관리 (타임라인) │
|
||||
│ - 창고관리 (모바일 앱 스타일) │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 신규 컴포넌트 개발 우선순위
|
||||
|
||||
| 순위 | 컴포넌트 | 재활용 화면 수 | 복잡도 | ROI |
|
||||
|------|----------|--------------|--------|-----|
|
||||
| 1 | v2-grouped-table | 5+ | 중 | ⭐⭐⭐⭐⭐ |
|
||||
| 2 | v2-tree-view | 3 | 중상 | ⭐⭐⭐⭐ |
|
||||
| 3 | v2-timeline-scheduler | 1~2 | 상 | ⭐⭐ |
|
||||
|
||||
---
|
||||
|
||||
## 7. 권장 구현 전략
|
||||
|
||||
### Phase 1: 즉시 구현 (현재 V2 컴포넌트)
|
||||
- 회사정보, 부서정보
|
||||
- 발주관리, 공급업체관리
|
||||
- 검사기준, 검사장비관리, 불량관리
|
||||
- 창고정보관리, 재고현황
|
||||
- 공정작업기준관리
|
||||
- 수주관리, 견적관리, 공정관리
|
||||
- 설비정보 (v2-card-display 활용)
|
||||
- 검사정보관리
|
||||
|
||||
### Phase 2: v2-grouped-table 개발 후
|
||||
- 품목정보, 거래처관리, 입출고관리
|
||||
- 작업지시
|
||||
|
||||
### Phase 3: v2-tree-view 개발 후
|
||||
- BOM관리
|
||||
- 부서정보 (계층 뷰)
|
||||
|
||||
### Phase 4: 개별 개발
|
||||
- 생산계획관리 (타임라인)
|
||||
- 창고관리 (모바일 스타일)
|
||||
|
||||
---
|
||||
|
||||
## 8. 요약
|
||||
|
||||
| 항목 | 수치 |
|
||||
|------|------|
|
||||
| 전체 분석 화면 수 | 26개 |
|
||||
| 현재 즉시 구현 가능 | 17개 (65%) |
|
||||
| v2-grouped-table 추가 시 | 22개 (85%) |
|
||||
| v2-tree-view 추가 시 | 24개 (92%) |
|
||||
| 별도 개발 필요 | 2개 (8%) |
|
||||
|
||||
**핵심 결론**:
|
||||
1. **현재 V2 컴포넌트**로 65% 화면 구현 가능
|
||||
2. **v2-grouped-table** 1개 컴포넌트 개발로 85%까지 확대
|
||||
3. **v2-tree-view** 추가로 92% 도달
|
||||
4. 나머지 8%는 화면별 특수 UI (타임라인, 모바일 스타일)로 개별 개발 필요
|
||||
|
|
@ -0,0 +1,541 @@
|
|||
# V2 공통 컴포넌트 사용 가이드
|
||||
|
||||
> **목적**: 다양한 회사에서 V2 컴포넌트를 활용하여 화면을 개발할 때 참고하는 범용 가이드
|
||||
> **대상**: 화면 설계자, 개발자
|
||||
> **버전**: 1.0.0
|
||||
> **작성일**: 2026-01-30
|
||||
|
||||
---
|
||||
|
||||
## 1. V2 컴포넌트로 가능한 것 / 불가능한 것
|
||||
|
||||
### 1.1 가능한 화면 유형
|
||||
|
||||
| 화면 유형 | 설명 | 대표 예시 |
|
||||
|-----------|------|----------|
|
||||
| 마스터 관리 | 단일 테이블 CRUD | 회사정보, 부서정보, 코드관리 |
|
||||
| 마스터-디테일 | 좌측 선택 → 우측 상세 | 공정관리, 품목라우팅, 견적관리 |
|
||||
| 탭 기반 화면 | 탭별 다른 테이블/뷰 | 검사정보관리, 거래처관리 |
|
||||
| 카드 뷰 | 이미지+정보 카드 형태 | 설비정보, 대시보드 |
|
||||
| 피벗 분석 | 다차원 집계 | 매출분석, 재고현황 |
|
||||
| 반복 컨테이너 | 데이터 수만큼 UI 반복 | 주문 상세, 항목 리스트 |
|
||||
|
||||
### 1.2 불가능한 화면 유형 (별도 개발 필요)
|
||||
|
||||
| 화면 유형 | 이유 | 해결 방안 |
|
||||
|-----------|------|----------|
|
||||
| 간트 차트 / 타임라인 | 시간축 기반 UI 없음 | 별도 컴포넌트 개발 or 외부 라이브러리 |
|
||||
| 트리 뷰 (계층 구조) | 트리 컴포넌트 미존재 | `v2-tree-view` 개발 필요 |
|
||||
| 그룹화 테이블 | 그룹핑 기능 미지원 | `v2-grouped-table` 개발 필요 |
|
||||
| 드래그앤드롭 보드 | 칸반 스타일 UI 없음 | 별도 개발 |
|
||||
| 모바일 앱 스타일 | 네이티브 앱 UI | 별도 개발 |
|
||||
| 복잡한 차트 | 기본 집계 외 시각화 | 차트 라이브러리 연동 |
|
||||
|
||||
---
|
||||
|
||||
## 2. V2 컴포넌트 전체 목록 (23개)
|
||||
|
||||
### 2.1 입력 컴포넌트 (3개)
|
||||
|
||||
| ID | 이름 | 용도 | 주요 옵션 |
|
||||
|----|------|------|----------|
|
||||
| `v2-input` | 입력 | 텍스트, 숫자, 비밀번호, 이메일, 전화번호, URL, 여러 줄 | inputType, required, readonly, maxLength |
|
||||
| `v2-select` | 선택 | 드롭다운, 콤보박스, 라디오, 체크박스 | mode, source(distinct/static/code/entity), multiple |
|
||||
| `v2-date` | 날짜 | 날짜, 시간, 날짜시간, 날짜범위, 월, 연도 | dateType, format, showTime |
|
||||
|
||||
### 2.2 표시 컴포넌트 (3개)
|
||||
|
||||
| ID | 이름 | 용도 | 주요 옵션 |
|
||||
|----|------|------|----------|
|
||||
| `v2-text-display` | 텍스트 표시 | 라벨, 제목, 설명 텍스트 | fontSize, fontWeight, color, textAlign |
|
||||
| `v2-card-display` | 카드 디스플레이 | 테이블 데이터를 카드 형태로 표시 | cardsPerRow, showImage, columnMapping |
|
||||
| `v2-aggregation-widget` | 집계 위젯 | 합계, 평균, 개수, 최대, 최소 | items, filters, layout |
|
||||
|
||||
### 2.3 테이블/데이터 컴포넌트 (3개)
|
||||
|
||||
| ID | 이름 | 용도 | 주요 옵션 |
|
||||
|----|------|------|----------|
|
||||
| `v2-table-list` | 테이블 리스트 | 데이터 조회/편집 테이블 | selectedTable, columns, pagination, filter |
|
||||
| `v2-table-search-widget` | 검색 필터 | 테이블 검색/필터/그룹 | autoSelectFirstTable, showTableSelector |
|
||||
| `v2-pivot-grid` | 피벗 그리드 | 다차원 분석 (행/열/데이터 영역) | fields, totals, aggregation |
|
||||
|
||||
### 2.4 레이아웃 컴포넌트 (8개)
|
||||
|
||||
| ID | 이름 | 용도 | 주요 옵션 |
|
||||
|----|------|------|----------|
|
||||
| `v2-split-panel-layout` | 분할 패널 | 마스터-디테일 좌우 분할 | splitRatio, resizable, relation |
|
||||
| `v2-tabs-widget` | 탭 위젯 | 탭 전환, 탭 내 컴포넌트 | tabs, activeTabId |
|
||||
| `v2-section-card` | 섹션 카드 | 제목+테두리 그룹화 | title, collapsible, padding |
|
||||
| `v2-section-paper` | 섹션 페이퍼 | 배경색 그룹화 | backgroundColor, padding, shadow |
|
||||
| `v2-divider-line` | 구분선 | 영역 구분 | orientation, thickness |
|
||||
| `v2-repeat-container` | 리피터 컨테이너 | 데이터 수만큼 반복 렌더링 | dataSourceType, layout, gridColumns |
|
||||
| `v2-repeater` | 리피터 | 반복 컨트롤 | - |
|
||||
| `v2-repeat-screen-modal` | 반복 화면 모달 | 모달 반복 | - |
|
||||
|
||||
### 2.5 액션/특수 컴포넌트 (6개)
|
||||
|
||||
| ID | 이름 | 용도 | 주요 옵션 |
|
||||
|----|------|------|----------|
|
||||
| `v2-button-primary` | 기본 버튼 | 저장, 삭제 등 액션 | text, actionType, variant |
|
||||
| `v2-numbering-rule` | 채번규칙 | 자동 코드/번호 생성 | rule, prefix, format |
|
||||
| `v2-category-manager` | 카테고리 관리자 | 카테고리 관리 UI | - |
|
||||
| `v2-location-swap-selector` | 위치 교환 | 위치 선택/교환 | - |
|
||||
| `v2-rack-structure` | 랙 구조 | 창고 랙 시각화 | - |
|
||||
| `v2-media` | 미디어 | 이미지/동영상 표시 | - |
|
||||
|
||||
---
|
||||
|
||||
## 3. 화면 패턴별 컴포넌트 조합
|
||||
|
||||
### 3.1 패턴 A: 기본 마스터 화면 (가장 흔함)
|
||||
|
||||
**적용 화면**: 코드관리, 사용자관리, 부서정보, 창고정보 등
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ v2-table-search-widget │
|
||||
│ [검색필드1] [검색필드2] [조회] [엑셀] │
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ v2-table-list │
|
||||
│ 제목 [신규] [삭제] │
|
||||
│ ─────────────────────────────────────────────── │
|
||||
│ □ | 코드 | 이름 | 상태 | 등록일 | │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**필수 컴포넌트**:
|
||||
- `v2-table-search-widget` (1개)
|
||||
- `v2-table-list` (1개)
|
||||
|
||||
**설정 포인트**:
|
||||
- 테이블명 지정
|
||||
- 검색 대상 컬럼 설정
|
||||
- 컬럼 표시/숨김 설정
|
||||
|
||||
---
|
||||
|
||||
### 3.2 패턴 B: 마스터-디테일 화면
|
||||
|
||||
**적용 화면**: 공정관리, 견적관리, 수주관리, 품목라우팅 등
|
||||
|
||||
```
|
||||
┌──────────────────┬──────────────────────────────┐
|
||||
│ v2-table-list │ v2-table-list 또는 폼 │
|
||||
│ (마스터) │ (디테일) │
|
||||
│ ─────────────── │ │
|
||||
│ □ A001 항목1 │ [상세 정보] │
|
||||
│ □ A002 항목2 ← │ │
|
||||
│ □ A003 항목3 │ │
|
||||
└──────────────────┴──────────────────────────────┘
|
||||
v2-split-panel-layout
|
||||
```
|
||||
|
||||
**필수 컴포넌트**:
|
||||
- `v2-split-panel-layout` (1개)
|
||||
- `v2-table-list` (2개: 마스터, 디테일)
|
||||
|
||||
**설정 포인트**:
|
||||
- `splitRatio`: 좌우 비율 (기본 30:70)
|
||||
- `relation.type`: join / detail / custom
|
||||
- `relation.foreignKey`: 연결 키 컬럼
|
||||
|
||||
---
|
||||
|
||||
### 3.3 패턴 C: 마스터-디테일 + 탭
|
||||
|
||||
**적용 화면**: 거래처관리, 품목정보, 설비정보 등
|
||||
|
||||
```
|
||||
┌──────────────────┬──────────────────────────────┐
|
||||
│ v2-table-list │ v2-tabs-widget │
|
||||
│ (마스터) │ ┌────┬────┬────┐ │
|
||||
│ │ │기본│이력│첨부│ │
|
||||
│ □ A001 거래처1 │ └────┴────┴────┘ │
|
||||
│ □ A002 거래처2 ← │ [탭별 컨텐츠] │
|
||||
└──────────────────┴──────────────────────────────┘
|
||||
```
|
||||
|
||||
**필수 컴포넌트**:
|
||||
- `v2-split-panel-layout` (1개)
|
||||
- `v2-table-list` (1개: 마스터)
|
||||
- `v2-tabs-widget` (1개)
|
||||
|
||||
**설정 포인트**:
|
||||
- 탭별 표시할 테이블/폼 설정
|
||||
- 마스터 선택 시 탭 컨텐츠 연동
|
||||
|
||||
---
|
||||
|
||||
### 3.4 패턴 D: 카드 뷰
|
||||
|
||||
**적용 화면**: 설비정보, 대시보드, 상품 카탈로그 등
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ v2-table-search-widget │
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ v2-card-display │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
||||
│ │ [이미지]│ │ [이미지]│ │ [이미지]│ │
|
||||
│ │ 제목 │ │ 제목 │ │ 제목 │ │
|
||||
│ │ 설명 │ │ 설명 │ │ 설명 │ │
|
||||
│ └─────────┘ └─────────┘ └─────────┘ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**필수 컴포넌트**:
|
||||
- `v2-table-search-widget` (1개)
|
||||
- `v2-card-display` (1개)
|
||||
|
||||
**설정 포인트**:
|
||||
- `cardsPerRow`: 한 행당 카드 수
|
||||
- `columnMapping`: 제목, 부제목, 이미지, 상태 필드 매핑
|
||||
- `cardStyle`: 이미지 위치, 크기
|
||||
|
||||
---
|
||||
|
||||
### 3.5 패턴 E: 피벗 분석
|
||||
|
||||
**적용 화면**: 매출분석, 재고현황, 생산실적 분석 등
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ v2-pivot-grid │
|
||||
│ │ 2024년 │ 2025년 │ 2026년 │ 합계 │
|
||||
│ ─────────────────────────────────────────────── │
|
||||
│ 지역A │ 1,000 │ 1,200 │ 1,500 │ 3,700 │
|
||||
│ 지역B │ 2,000 │ 2,500 │ 3,000 │ 7,500 │
|
||||
│ 합계 │ 3,000 │ 3,700 │ 4,500 │ 11,200 │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**필수 컴포넌트**:
|
||||
- `v2-pivot-grid` (1개)
|
||||
|
||||
**설정 포인트**:
|
||||
- `fields[].area`: row / column / data / filter
|
||||
- `fields[].summaryType`: sum / avg / count / min / max
|
||||
- `fields[].groupInterval`: 날짜 그룹화 (year/quarter/month)
|
||||
|
||||
---
|
||||
|
||||
## 4. 회사별 개발 시 핵심 체크포인트
|
||||
|
||||
### 4.1 테이블 설계 확인
|
||||
|
||||
**가장 먼저 확인**:
|
||||
1. 회사에서 사용할 테이블 목록
|
||||
2. 테이블 간 관계 (FK)
|
||||
3. 조회 조건으로 쓸 컬럼
|
||||
|
||||
```
|
||||
✅ 체크리스트:
|
||||
□ 테이블명이 DB에 존재하는가?
|
||||
□ company_code 컬럼이 있는가? (멀티테넌시)
|
||||
□ 마스터-디테일 관계의 FK가 정의되어 있는가?
|
||||
□ 검색 대상 컬럼에 인덱스가 있는가?
|
||||
```
|
||||
|
||||
### 4.2 화면 패턴 판단
|
||||
|
||||
**질문을 통한 판단**:
|
||||
|
||||
| 질문 | 예 → 패턴 |
|
||||
|------|----------|
|
||||
| 단일 테이블만 조회/편집? | 패턴 A (기본 마스터) |
|
||||
| 마스터 선택 시 디테일 표시? | 패턴 B (마스터-디테일) |
|
||||
| 상세에 탭이 필요? | 패턴 C (마스터-디테일+탭) |
|
||||
| 이미지+정보 카드 형태? | 패턴 D (카드 뷰) |
|
||||
| 다차원 집계/분석? | 패턴 E (피벗) |
|
||||
|
||||
### 4.3 컴포넌트 설정 필수 항목
|
||||
|
||||
#### v2-table-list 필수 설정
|
||||
|
||||
```typescript
|
||||
{
|
||||
selectedTable: "테이블명", // 필수
|
||||
columns: [ // 표시할 컬럼
|
||||
{ columnName: "id", displayName: "ID", visible: true, sortable: true },
|
||||
// ...
|
||||
],
|
||||
pagination: {
|
||||
enabled: true,
|
||||
pageSize: 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### v2-split-panel-layout 필수 설정
|
||||
|
||||
```typescript
|
||||
{
|
||||
leftPanel: {
|
||||
tableName: "마스터_테이블명"
|
||||
},
|
||||
rightPanel: {
|
||||
tableName: "디테일_테이블명",
|
||||
relation: {
|
||||
type: "detail", // join | detail | custom
|
||||
foreignKey: "master_id" // 연결 키
|
||||
}
|
||||
},
|
||||
splitRatio: 30 // 좌측 비율
|
||||
}
|
||||
```
|
||||
|
||||
#### v2-card-display 필수 설정
|
||||
|
||||
```typescript
|
||||
{
|
||||
dataSource: "table",
|
||||
columnMapping: {
|
||||
title: "name", // 제목 필드
|
||||
subtitle: "code", // 부제목 필드
|
||||
image: "image_url", // 이미지 필드 (선택)
|
||||
status: "status" // 상태 필드 (선택)
|
||||
},
|
||||
cardsPerRow: 3
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 공통 컴포넌트 한계점
|
||||
|
||||
### 5.1 현재 불가능한 기능
|
||||
|
||||
| 기능 | 상태 | 대안 |
|
||||
|------|------|------|
|
||||
| 트리 뷰 (BOM, 조직도) | ❌ 미지원 | 테이블로 대체 or 별도 개발 |
|
||||
| 그룹화 테이블 | ❌ 미지원 | 일반 테이블로 대체 or 별도 개발 |
|
||||
| 간트 차트 | ❌ 미지원 | 별도 개발 필요 |
|
||||
| 드래그앤드롭 정렬 | ❌ 미지원 | 순서 컬럼으로 대체 |
|
||||
| 인라인 편집 | ⚠️ 제한적 | 모달 편집으로 대체 |
|
||||
| 복잡한 차트 | ❌ 미지원 | 외부 라이브러리 연동 |
|
||||
|
||||
### 5.2 권장하지 않는 조합
|
||||
|
||||
| 조합 | 이유 |
|
||||
|------|------|
|
||||
| 3단계 이상 중첩 분할 | 화면 복잡도 증가, 성능 저하 |
|
||||
| 탭 안에 탭 | 사용성 저하 |
|
||||
| 한 화면에 3개 이상 테이블 | 데이터 로딩 성능 |
|
||||
| 피벗 + 상세 테이블 동시 | 데이터 과부하 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 제어관리 (비즈니스 로직) - 별도 설정 필수
|
||||
|
||||
> **핵심**: V2 컴포넌트는 **UI만 담당**합니다. 비즈니스 로직은 **제어관리**에서 별도 설정해야 합니다.
|
||||
|
||||
### 6.1 UI vs 제어 분리 구조
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 화면 구성 │
|
||||
├─────────────────────────────┬───────────────────────────────────┤
|
||||
│ UI 레이아웃 │ 제어관리 │
|
||||
│ (screen_layouts_v2) │ (dataflow_diagrams) │
|
||||
├─────────────────────────────┼───────────────────────────────────┤
|
||||
│ • 컴포넌트 배치 │ • 버튼 클릭 시 액션 │
|
||||
│ • 검색 필드 구성 │ • INSERT/UPDATE/DELETE 설정 │
|
||||
│ • 테이블 컬럼 표시 │ • 조건부 실행 │
|
||||
│ • 카드/탭 레이아웃 │ • 다중 행 처리 │
|
||||
│ │ • 테이블 간 데이터 이동 │
|
||||
└─────────────────────────────┴───────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.2 HTML에서 파악 가능/불가능
|
||||
|
||||
| 구분 | HTML에서 파악 | 이유 |
|
||||
|------|--------------|------|
|
||||
| 컴포넌트 배치 | ✅ 가능 | HTML 구조에서 보임 |
|
||||
| 검색 필드 | ✅ 가능 | input 태그로 확인 |
|
||||
| 테이블 컬럼 | ✅ 가능 | thead에서 확인 |
|
||||
| **저장 테이블** | ❌ 불가능 | JS/백엔드에서 처리 |
|
||||
| **버튼 액션** | ❌ 불가능 | 제어관리에서 설정 |
|
||||
| **전/후 처리** | ❌ 불가능 | 제어관리에서 설정 |
|
||||
| **다중 행 처리** | ❌ 불가능 | 제어관리에서 설정 |
|
||||
| **테이블 간 관계** | ❌ 불가능 | DB/제어관리에서 설정 |
|
||||
|
||||
### 6.3 제어관리 설정 항목
|
||||
|
||||
#### 트리거 타입
|
||||
- **버튼 클릭 전 (before)**: 클릭 직전 실행
|
||||
- **버튼 클릭 후 (after)**: 클릭 완료 후 실행
|
||||
|
||||
#### 액션 타입
|
||||
- **INSERT**: 새로운 데이터 삽입
|
||||
- **UPDATE**: 기존 데이터 수정
|
||||
- **DELETE**: 데이터 삭제
|
||||
|
||||
#### 조건 설정
|
||||
```typescript
|
||||
// 예: 선택된 행의 상태가 '대기'인 경우에만 실행
|
||||
{
|
||||
field: "status",
|
||||
operator: "=",
|
||||
value: "대기",
|
||||
dataType: "string"
|
||||
}
|
||||
```
|
||||
|
||||
#### 필드 매핑
|
||||
```typescript
|
||||
// 예: 소스 테이블의 값을 타겟 테이블로 이동
|
||||
{
|
||||
sourceTable: "order_master",
|
||||
sourceField: "order_no",
|
||||
targetTable: "order_history",
|
||||
targetField: "order_no"
|
||||
}
|
||||
```
|
||||
|
||||
### 6.4 제어관리 예시: 수주 확정 버튼
|
||||
|
||||
**시나리오**: 수주 목록에서 3건 선택 후 [확정] 버튼 클릭
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [확정] 버튼 클릭 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 1. 조건 체크: status = '대기' 인 행만 │
|
||||
│ 2. UPDATE order_master SET status = '확정' WHERE id IN (선택) │
|
||||
│ 3. INSERT order_history (수주이력 테이블에 기록) │
|
||||
│ 4. 외부 시스템 호출 (ERP 연동) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**제어관리 설정**:
|
||||
```json
|
||||
{
|
||||
"triggerType": "after",
|
||||
"actions": [
|
||||
{
|
||||
"actionType": "update",
|
||||
"targetTable": "order_master",
|
||||
"conditions": [{ "field": "status", "operator": "=", "value": "대기" }],
|
||||
"fieldMappings": [{ "targetField": "status", "defaultValue": "확정" }]
|
||||
},
|
||||
{
|
||||
"actionType": "insert",
|
||||
"targetTable": "order_history",
|
||||
"fieldMappings": [
|
||||
{ "sourceField": "order_no", "targetField": "order_no" },
|
||||
{ "sourceField": "customer_name", "targetField": "customer_name" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 6.5 회사별 개발 시 제어관리 체크리스트
|
||||
|
||||
```
|
||||
□ 버튼별 액션 정의
|
||||
- 어떤 버튼이 있는가?
|
||||
- 각 버튼 클릭 시 무슨 동작?
|
||||
|
||||
□ 저장/수정/삭제 대상 테이블
|
||||
- 메인 테이블은?
|
||||
- 이력 테이블은?
|
||||
- 연관 테이블은?
|
||||
|
||||
□ 조건부 실행
|
||||
- 특정 상태일 때만 실행?
|
||||
- 특정 값 체크 필요?
|
||||
|
||||
□ 다중 행 처리
|
||||
- 여러 행 선택 후 일괄 처리?
|
||||
- 각 행별 개별 처리?
|
||||
|
||||
□ 외부 연동
|
||||
- ERP/MES 등 외부 시스템 호출?
|
||||
- API 연동 필요?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 회사별 커스터마이징 영역
|
||||
|
||||
### 7.1 컴포넌트로 처리되는 영역 (표준화)
|
||||
|
||||
| 영역 | 설명 |
|
||||
|------|------|
|
||||
| UI 레이아웃 | 컴포넌트 배치, 크기, 위치 |
|
||||
| 검색 조건 | 화면 디자이너에서 설정 |
|
||||
| 테이블 컬럼 | 표시/숨김, 순서, 너비 |
|
||||
| 기본 CRUD | 조회, 저장, 삭제 자동 처리 |
|
||||
| 페이지네이션 | 자동 처리 |
|
||||
| 정렬/필터 | 자동 처리 |
|
||||
|
||||
### 7.2 회사별 개발 필요 영역
|
||||
|
||||
| 영역 | 설명 | 개발 방법 |
|
||||
|------|------|----------|
|
||||
| 비즈니스 로직 | 저장 전/후 검증, 계산 | 데이터플로우 또는 백엔드 API |
|
||||
| 특수 UI | 간트, 트리, 차트 등 | 별도 컴포넌트 개발 |
|
||||
| 외부 연동 | ERP, MES 등 연계 | 외부 호출 설정 |
|
||||
| 리포트/인쇄 | 전표, 라벨 출력 | 리포트 컴포넌트 |
|
||||
| 결재 프로세스 | 승인/반려 흐름 | 워크플로우 설정 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 빠른 개발 가이드
|
||||
|
||||
### Step 1: 화면 분석
|
||||
1. 어떤 테이블을 사용하는가?
|
||||
2. 테이블 간 관계는?
|
||||
3. 어떤 패턴인가? (A/B/C/D/E)
|
||||
|
||||
### Step 2: 컴포넌트 배치
|
||||
1. 화면 디자이너에서 패턴에 맞는 컴포넌트 배치
|
||||
2. 각 컴포넌트에 테이블/컬럼 설정
|
||||
|
||||
### Step 3: 연동 설정
|
||||
1. 마스터-디테일 관계 설정 (FK)
|
||||
2. 검색 조건 설정
|
||||
3. 버튼 액션 설정
|
||||
|
||||
### Step 4: 테스트
|
||||
1. 데이터 조회 확인
|
||||
2. 마스터 선택 시 디테일 연동 확인
|
||||
3. 저장/삭제 동작 확인
|
||||
|
||||
---
|
||||
|
||||
## 9. 요약
|
||||
|
||||
### V2 컴포넌트 커버리지
|
||||
|
||||
| 화면 유형 | 지원 여부 | 주요 컴포넌트 |
|
||||
|-----------|----------|--------------|
|
||||
| 기본 CRUD | ✅ 완전 | v2-table-list, v2-table-search-widget |
|
||||
| 마스터-디테일 | ✅ 완전 | v2-split-panel-layout |
|
||||
| 탭 화면 | ✅ 완전 | v2-tabs-widget |
|
||||
| 카드 뷰 | ✅ 완전 | v2-card-display |
|
||||
| 피벗 분석 | ✅ 완전 | v2-pivot-grid |
|
||||
| 그룹화 테이블 | ❌ 미지원 | 개발 필요 |
|
||||
| 트리 뷰 | ❌ 미지원 | 개발 필요 |
|
||||
| 간트 차트 | ❌ 미지원 | 개발 필요 |
|
||||
|
||||
### 개발 시 핵심 원칙
|
||||
|
||||
1. **테이블 먼저**: DB 테이블 구조 확인이 최우선
|
||||
2. **패턴 판단**: 5가지 패턴 중 어디에 해당하는지 판단
|
||||
3. **표준 조합**: 검증된 컴포넌트 조합 사용
|
||||
4. **한계 인식**: 불가능한 UI는 조기에 식별하여 별도 개발 계획
|
||||
5. **멀티테넌시**: 모든 테이블에 company_code 필터링 필수
|
||||
6. **제어관리 필수**: UI 완성 후 버튼별 비즈니스 로직 설정 필수
|
||||
|
||||
### UI vs 제어 구분
|
||||
|
||||
| 영역 | 담당 | 설정 위치 |
|
||||
|------|------|----------|
|
||||
| 화면 레이아웃 | V2 컴포넌트 | 화면 디자이너 |
|
||||
| 비즈니스 로직 | 제어관리 | dataflow_diagrams |
|
||||
| 외부 연동 | 외부호출 설정 | external_call_configs |
|
||||
|
||||
**HTML에서 배낄 수 있는 것**: UI 구조만
|
||||
**별도 설정 필요한 것**: 저장 테이블, 버튼 액션, 조건 처리, 다중 행 처리
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
# BOM관리 화면 구현 가이드
|
||||
|
||||
> **화면명**: BOM관리
|
||||
> **파일**: BOM관리.html
|
||||
> **분류**: 기준정보
|
||||
> **구현 가능**: ⚠️ 부분 (트리 뷰 컴포넌트 필요)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
BOM(Bill of Materials) 관리 화면으로, 제품의 부품 구성을 트리 구조로 관리합니다.
|
||||
|
||||
### 핵심 기능
|
||||
- BOM 목록 조회/검색
|
||||
- BOM 구조 트리 표시 (정전개/역전개)
|
||||
- BOM 등록/수정/삭제
|
||||
- 버전/차수 관리
|
||||
- 엑셀 업로드/다운로드
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [품목코드] [품목명] [품목구분▼] [버전▼] [사용여부▼] [초기화][조회]│
|
||||
│ [사용자옵션][업로드][다운로드]│
|
||||
├───────────────────────┬─────────────────────────────────────────┤
|
||||
│ 📦 BOM 목록 │ 📋 BOM 상세정보 │
|
||||
│ ─────────────── │ [이력] [버전] [수정] [삭제] │
|
||||
│ [신규등록] │ ───────────────────────── │
|
||||
│ ┌──────────────────┐ │ 품목코드: PRD-001 │
|
||||
│ │□|코드|품목명|구분..│ │ 품목명: 제품A │
|
||||
│ │□|P01|제품A |제품 │ │ 기준수량: 1 │
|
||||
│ │□|P02|제품B |제품 │ ├─────────────────────────────────────────┤
|
||||
│ └──────────────────┘ │ 🌳 BOM 구조 │
|
||||
│ │ 기준수량:[1] [트리|레벨] [정전개|역전개] │
|
||||
│ 리사이저 ↔ │ ───────────────────────── │
|
||||
│ │ ▼ PRD-001 제품A (1.00 EA) │
|
||||
│ │ ├─ MAT-001 원자재A (2.00 KG) │
|
||||
│ │ └─ SEM-001 반제품A (1.00 EA) │
|
||||
│ │ └─ MAT-002 원자재B (0.50 KG) │
|
||||
└───────────────────────┴─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
### 3.1 구현 가능 영역
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| BOM 목록 테이블 | `v2-table-list` | ✅ 가능 |
|
||||
| 분할 패널 | `v2-split-panel-layout` | ⚠️ 부분 |
|
||||
|
||||
### 3.2 신규 컴포넌트 필요
|
||||
|
||||
| HTML 영역 | 필요 컴포넌트 | 재활용 가능성 |
|
||||
|-----------|---------------|--------------|
|
||||
| BOM 트리 구조 | `v2-tree-view` | 3개 화면 (부서정보, 메뉴관리) |
|
||||
| BOM 등록 모달 | `v2-modal-form` | 모든 화면 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 테이블 정의
|
||||
|
||||
### 4.1 BOM 목록 테이블 (좌측)
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'item_code', label: '품목코드', width: 100 },
|
||||
{ id: 'item_name', label: '품목명', width: 150 },
|
||||
{ id: 'item_type', label: '품목구분', width: 80 },
|
||||
{ id: 'version', label: '버전', width: 70 },
|
||||
{ id: 'revision', label: '차수', width: 70 },
|
||||
{ id: 'status', label: '사용여부', width: 80 },
|
||||
{ id: 'reg_date', label: '등록일', width: 100 }
|
||||
]
|
||||
```
|
||||
|
||||
### 4.2 BOM 상세 필드
|
||||
|
||||
```typescript
|
||||
detailFields: [
|
||||
{ id: 'item_code', label: '품목코드' },
|
||||
{ id: 'item_name', label: '품목명' },
|
||||
{ id: 'item_type', label: '품목구분' },
|
||||
{ id: 'unit', label: '단위' },
|
||||
{ id: 'base_qty', label: '기준수량' },
|
||||
{ id: 'version', label: '버전' },
|
||||
{ id: 'revision', label: '차수' },
|
||||
{ id: 'status', label: '사용여부' },
|
||||
{ id: 'remark', label: '비고' }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 검색 조건
|
||||
|
||||
| 필드명 | 컴포넌트 | 옵션 |
|
||||
|--------|----------|------|
|
||||
| 품목코드 | `v2-input` | placeholder: "품목코드" |
|
||||
| 품목명 | `v2-input` | placeholder: "품목명" |
|
||||
| 품목구분 | `v2-select` | 제품, 반제품, 원자재 |
|
||||
| 버전 | `v2-select` | 1.0, 2.0, 3.0 |
|
||||
| 사용여부 | `v2-select` | 사용, 미사용 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 특수 기능: BOM 트리 (신규 컴포넌트 필요)
|
||||
|
||||
### 6.1 트리 노드 구조
|
||||
|
||||
```typescript
|
||||
interface BomTreeNode {
|
||||
id: string;
|
||||
itemCode: string;
|
||||
itemName: string;
|
||||
itemType: string;
|
||||
quantity: number;
|
||||
unit: string;
|
||||
level: number;
|
||||
children: BomTreeNode[];
|
||||
expanded: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 정전개 vs 역전개
|
||||
|
||||
| 모드 | 설명 |
|
||||
|------|------|
|
||||
| 정전개 (Forward) | 선택 품목 → 하위 구성품목 표시 |
|
||||
| 역전개 (Reverse) | 선택 품목 → 상위 사용처 표시 |
|
||||
|
||||
### 6.3 필요 인터랙션
|
||||
|
||||
- 노드 클릭: 펼치기/접기
|
||||
- 전체 펼치기/접기 버튼
|
||||
- 레벨 뷰/트리 뷰 전환
|
||||
- 기준수량 변경 시 수량 재계산
|
||||
|
||||
---
|
||||
|
||||
## 7. 모달 폼 정의
|
||||
|
||||
### 7.1 BOM 등록 모달
|
||||
|
||||
```typescript
|
||||
modalFields: [
|
||||
{ id: 'item_code', label: '품목코드', type: 'autocomplete', required: true },
|
||||
{ id: 'item_name', label: '품목명', type: 'autocomplete', required: true },
|
||||
{ id: 'item_type', label: '품목구분', type: 'select', required: true },
|
||||
{ id: 'unit', label: '단위', type: 'select', required: true },
|
||||
{ id: 'base_qty', label: '기준수량', type: 'number', required: true },
|
||||
{ id: 'version', label: '버전', type: 'text', readonly: true },
|
||||
{ id: 'revision', label: '차수', type: 'text', readonly: true },
|
||||
{ id: 'status', label: '사용여부', type: 'radio', options: ['사용', '미사용'] },
|
||||
{ id: 'remark', label: '비고', type: 'textarea' }
|
||||
]
|
||||
|
||||
// 하위 품목 섹션
|
||||
childItemsSection: {
|
||||
title: '하위 품목 구성',
|
||||
addButton: '품목추가',
|
||||
columns: [
|
||||
{ id: 'item_code', label: '품목코드' },
|
||||
{ id: 'item_name', label: '품목명' },
|
||||
{ id: 'quantity', label: '소요량' },
|
||||
{ id: 'unit', label: '단위' },
|
||||
{ id: 'loss_rate', label: '로스율(%)' },
|
||||
{ id: 'actions', label: '' }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 현재 구현 가능 범위
|
||||
|
||||
### ✅ 가능
|
||||
- 검색 영역 (v2-table-search-widget)
|
||||
- BOM 목록 테이블 (v2-table-list)
|
||||
- 분할 패널 레이아웃 (v2-split-panel-layout)
|
||||
- 기본 상세 정보 표시
|
||||
|
||||
### ⚠️ 부분 가능 (대체 구현)
|
||||
- BOM 구조: 트리 대신 레벨 테이블로 표시 가능
|
||||
|
||||
### ❌ 불가능 (신규 개발 필요)
|
||||
- 진정한 트리 뷰 (접기/펼치기)
|
||||
- 정전개/역전개 전환
|
||||
- 하위 품목 동적 추가 모달
|
||||
|
||||
---
|
||||
|
||||
## 9. 간소화 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "BOM_MAIN",
|
||||
"screen_name": "BOM관리",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "input", "id": "item_code", "placeholder": "품목코드" },
|
||||
{ "type": "input", "id": "item_name", "placeholder": "품목명" },
|
||||
{ "type": "select", "id": "item_type", "placeholder": "품목구분" },
|
||||
{ "type": "select", "id": "status", "placeholder": "사용여부" }
|
||||
],
|
||||
"buttons": [
|
||||
{ "label": "초기화", "action": "reset" },
|
||||
{ "label": "조회", "action": "search", "variant": "primary" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-split-panel-layout",
|
||||
"config": {
|
||||
"masterPanel": {
|
||||
"title": "BOM 목록",
|
||||
"entityId": "bom_header",
|
||||
"columns": [
|
||||
{ "id": "item_code", "label": "품목코드", "width": 100 },
|
||||
{ "id": "item_name", "label": "품목명", "width": 150 },
|
||||
{ "id": "item_type", "label": "품목구분", "width": 80 },
|
||||
{ "id": "version", "label": "버전", "width": 70 }
|
||||
]
|
||||
},
|
||||
"detailPanel": {
|
||||
"title": "BOM 상세정보",
|
||||
"entityId": "bom_detail",
|
||||
"relationType": "one-to-many"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 개발 권장사항
|
||||
|
||||
1. **1단계**: 현재 컴포넌트로 기본 CRUD 구현
|
||||
2. **2단계**: `v2-tree-view` 개발 후 BOM 구조 통합
|
||||
3. **3단계**: 버전/차수 관리 기능 추가
|
||||
|
||||
**예상 재활용**: `v2-tree-view`는 부서정보, 메뉴관리에서도 사용 가능 (3개 화면)
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
# 거래처관리 화면 구현 가이드
|
||||
|
||||
> **화면명**: 거래처관리
|
||||
> **파일**: 거래처관리.html
|
||||
> **분류**: 영업관리
|
||||
> **구현 가능**: ⚠️ 부분 (그룹화 테이블 필요)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
고객사 및 공급업체 정보를 통합 관리하는 화면입니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 거래처 목록 조회/검색
|
||||
- 그룹화 기능 (거래처유형, 지역별)
|
||||
- 거래처 등록/수정/삭제
|
||||
- 거래처별 품목코드/단가 관리
|
||||
- 담당자 정보 관리
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [거래처코드] [거래처명] [거래처유형▼] [사용여부▼] [초기화][조회] │
|
||||
│ [사용자옵션][업로드][다운로드]│
|
||||
├───────────────────────┬─────────────────────────────────────────┤
|
||||
│ 📋 거래처 목록 │ [기본정보][품목코드][단가정보][담당자] │
|
||||
│ ───────────────── │ ───────────────────────────────────── │
|
||||
│ Group by: [거래처유형▼] │ 거래처코드: C-001 │
|
||||
│ ┌──────────────────┐ │ 거래처명: (주)테스트 │
|
||||
│ │▼ 고객사 (15) │ │ 사업자번호: 123-45-67890 │
|
||||
│ │ C-001 | A사 │ │ 대표자: 홍길동 │
|
||||
│ │ C-002 | B사 │ ├─────────────────────────────────────────┤
|
||||
│ │▼ 공급업체 (8) │ │ [품목코드 탭 내용] │
|
||||
│ │ S-001 | 원자재사 │ │ ┌────────────────────────────────┐ │
|
||||
│ └──────────────────┘ │ │거래처품목코드|품목명|자사품목코드│ │
|
||||
│ │ │CP-001 |원료A |M-001 │ │
|
||||
│ 리사이저 ↔ │ └────────────────────────────────┘ │
|
||||
└───────────────────────┴─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 거래처 목록 (그룹화) | `v2-table-list` | ⚠️ 그룹화 미지원 |
|
||||
| 분할 패널 | `v2-split-panel-layout` | ✅ 가능 |
|
||||
| 상세 탭 | `v2-tabs-widget` | ✅ 가능 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 테이블 정의
|
||||
|
||||
### 4.1 거래처 목록
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'customer_code', label: '거래처코드', width: 100 },
|
||||
{ id: 'customer_name', label: '거래처명', width: 200 },
|
||||
{ id: 'customer_type', label: '거래처유형', width: 100 },
|
||||
{ id: 'business_no', label: '사업자번호', width: 120 },
|
||||
{ id: 'ceo_name', label: '대표자', width: 100 },
|
||||
{ id: 'tel', label: '전화번호', width: 120 },
|
||||
{ id: 'status', label: '사용여부', width: 80 }
|
||||
]
|
||||
```
|
||||
|
||||
### 4.2 품목코드 탭
|
||||
|
||||
```typescript
|
||||
itemCodeColumns: [
|
||||
{ id: 'customer_item_code', label: '거래처품목코드', width: 150 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'our_item_code', label: '자사품목코드', width: 150 },
|
||||
{ id: 'spec', label: '규격', width: 150 }
|
||||
]
|
||||
```
|
||||
|
||||
### 4.3 단가정보 탭
|
||||
|
||||
```typescript
|
||||
priceColumns: [
|
||||
{ id: 'item_code', label: '품목코드', width: 120 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'unit_price', label: '단가', width: 100, format: 'currency' },
|
||||
{ id: 'currency', label: '통화', width: 60 },
|
||||
{ id: 'apply_date', label: '적용일', width: 100 },
|
||||
{ id: 'remark', label: '비고', width: 150 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 그룹화 기능 (신규 컴포넌트 필요)
|
||||
|
||||
### 5.1 그룹화 옵션
|
||||
|
||||
```typescript
|
||||
groupByOptions: [
|
||||
{ id: 'customer_type', label: '거래처유형' },
|
||||
{ id: 'region', label: '지역' },
|
||||
{ id: 'status', label: '사용여부' }
|
||||
]
|
||||
```
|
||||
|
||||
### 5.2 그룹 헤더 표시
|
||||
|
||||
```
|
||||
▼ 고객사 (15) ← 그룹명 + 건수
|
||||
│ C-001 │ (주)A사 │ ...
|
||||
│ C-002 │ (주)B사 │ ...
|
||||
▼ 공급업체 (8)
|
||||
│ S-001 │ 원자재사 │ ...
|
||||
```
|
||||
|
||||
### 5.3 필요 인터랙션
|
||||
|
||||
- 그룹 접기/펼치기
|
||||
- 그룹 전체 선택 체크박스
|
||||
- 다중 그룹핑 (선택)
|
||||
|
||||
---
|
||||
|
||||
## 6. 탭 구성
|
||||
|
||||
```typescript
|
||||
tabs: [
|
||||
{
|
||||
id: 'basic',
|
||||
label: '기본정보',
|
||||
fields: [
|
||||
{ id: 'customer_code', label: '거래처코드' },
|
||||
{ id: 'customer_name', label: '거래처명' },
|
||||
{ id: 'customer_type', label: '거래처유형' },
|
||||
{ id: 'business_no', label: '사업자번호' },
|
||||
{ id: 'ceo_name', label: '대표자' },
|
||||
{ id: 'address', label: '주소' },
|
||||
{ id: 'tel', label: '전화번호' },
|
||||
{ id: 'fax', label: '팩스' },
|
||||
{ id: 'email', label: '이메일' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'item_codes',
|
||||
label: '품목코드',
|
||||
type: 'table',
|
||||
entityId: 'customer_item_mapping'
|
||||
},
|
||||
{
|
||||
id: 'prices',
|
||||
label: '단가정보',
|
||||
type: 'table',
|
||||
entityId: 'customer_prices'
|
||||
},
|
||||
{
|
||||
id: 'contacts',
|
||||
label: '담당자',
|
||||
type: 'table',
|
||||
entityId: 'customer_contacts'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 현재 구현 가능 범위
|
||||
|
||||
### ✅ 가능
|
||||
- 검색 영역
|
||||
- 분할 패널 레이아웃
|
||||
- 상세 탭
|
||||
- 품목코드/단가/담당자 테이블
|
||||
|
||||
### ⚠️ 부분 가능
|
||||
- 거래처 목록: 그룹화 없이 일반 테이블로 구현
|
||||
|
||||
### ❌ 불가능
|
||||
- 동적 그룹화 (그룹 접기/펼치기)
|
||||
|
||||
---
|
||||
|
||||
## 8. 간소화 구현 JSON (그룹화 제외)
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "CUSTOMER_MAIN",
|
||||
"screen_name": "거래처관리",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "input", "id": "customer_code", "placeholder": "거래처코드" },
|
||||
{ "type": "input", "id": "customer_name", "placeholder": "거래처명" },
|
||||
{ "type": "select", "id": "customer_type", "placeholder": "거래처유형",
|
||||
"options": [
|
||||
{ "value": "customer", "label": "고객사" },
|
||||
{ "value": "supplier", "label": "공급업체" },
|
||||
{ "value": "both", "label": "고객사/공급업체" }
|
||||
]
|
||||
},
|
||||
{ "type": "select", "id": "status", "placeholder": "사용여부" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-split-panel-layout",
|
||||
"config": {
|
||||
"masterPanel": {
|
||||
"title": "거래처 목록",
|
||||
"entityId": "customer_master",
|
||||
"columns": [
|
||||
{ "id": "customer_code", "label": "거래처코드", "width": 100 },
|
||||
{ "id": "customer_name", "label": "거래처명", "width": 200 },
|
||||
{ "id": "customer_type", "label": "거래처유형", "width": 100 },
|
||||
{ "id": "ceo_name", "label": "대표자", "width": 100 }
|
||||
]
|
||||
},
|
||||
"detailPanel": {
|
||||
"tabs": [
|
||||
{ "id": "basic", "label": "기본정보", "type": "form" },
|
||||
{ "id": "items", "label": "품목코드", "type": "table", "entityId": "customer_items" },
|
||||
{ "id": "prices", "label": "단가정보", "type": "table", "entityId": "customer_prices" },
|
||||
{ "id": "contacts", "label": "담당자", "type": "table", "entityId": "customer_contacts" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. v2-grouped-table 개발 시 추가 구현
|
||||
|
||||
```typescript
|
||||
// 그룹화 테이블 설정
|
||||
groupedTableConfig: {
|
||||
groupBy: 'customer_type',
|
||||
groupByOptions: ['customer_type', 'region', 'status'],
|
||||
showGroupCount: true,
|
||||
expandAll: false,
|
||||
groupCheckbox: true
|
||||
}
|
||||
```
|
||||
|
||||
**예상 재활용**: `v2-grouped-table`은 5개 이상 화면에서 사용 가능
|
||||
- 거래처관리, 품목정보, 작업지시, 입출고관리, 견적관리
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,308 @@
|
|||
# 견적관리 화면 구현 가이드
|
||||
|
||||
> **화면명**: 견적관리
|
||||
> **파일**: 견적관리.html
|
||||
> **분류**: 영업관리
|
||||
> **구현 가능**: ✅ 완전 (현재 V2 컴포넌트)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
견적서 생성 및 관리 화면으로, 고객 요청에 대한 견적을 작성하고 수주로 전환합니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 견적 목록 조회/검색
|
||||
- 견적 등록/수정/삭제
|
||||
- 견적 상세 및 품목 내역 관리
|
||||
- 견적서 인쇄/PDF 출력
|
||||
- 수주 전환
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [기간] [거래처] [견적번호] [품목명] [상태▼] [초기화][조회] │
|
||||
│ [사용자옵션][업로드][다운로드]│
|
||||
├───────────────────────┬─────────────────────────────────────────┤
|
||||
│ 📋 견적 목록 │ 📄 견적 상세 │
|
||||
│ ─────────────── │ [인쇄] [복사] [수주전환] [수정] [삭제] │
|
||||
│ [신규등록] │ ───────────────────────── │
|
||||
│ ┌──────────────────┐ │ 견적번호: QT-2026-0001 │
|
||||
│ │견적번호|거래처|금액..│ │ 거래처: (주)테스트 │
|
||||
│ │QT-001 |A사|1,000..│ │ 견적일: 2026-01-30 │
|
||||
│ │QT-002 |B사|2,500..│ ├─────────────────────────────────────────┤
|
||||
│ └──────────────────┘ │ [기본정보] [품목내역] [첨부파일] │
|
||||
│ │ ─────────────────────────── │
|
||||
│ 리사이저 ↔ │ │품목코드|품목명|수량|단가|금액|비고│ │
|
||||
│ │ │P-001 |제품A|100|1,000|100,000| │ │
|
||||
└───────────────────────┴─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 견적 목록 | `v2-table-list` | ✅ 가능 |
|
||||
| 분할 패널 | `v2-split-panel-layout` | ✅ 가능 |
|
||||
| 상세 탭 | `v2-tabs-widget` | ✅ 가능 |
|
||||
| 품목 내역 테이블 | `v2-table-list` | ✅ 가능 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 테이블 정의
|
||||
|
||||
### 4.1 견적 목록 (좌측)
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'quote_no', label: '견적번호', width: 120 },
|
||||
{ id: 'quote_date', label: '견적일', width: 100 },
|
||||
{ id: 'customer_name', label: '거래처', width: 150 },
|
||||
{ id: 'total_amount', label: '견적금액', width: 120, align: 'right', format: 'currency' },
|
||||
{ id: 'status', label: '상태', width: 80 },
|
||||
{ id: 'valid_date', label: '유효기간', width: 100 },
|
||||
{ id: 'manager', label: '담당자', width: 100 }
|
||||
]
|
||||
```
|
||||
|
||||
### 4.2 품목 내역 (우측 탭)
|
||||
|
||||
```typescript
|
||||
detailColumns: [
|
||||
{ id: 'seq', label: 'No', width: 50 },
|
||||
{ id: 'item_code', label: '품목코드', width: 100 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'spec', label: '규격', width: 150 },
|
||||
{ id: 'quantity', label: '수량', width: 80, align: 'right' },
|
||||
{ id: 'unit', label: '단위', width: 60 },
|
||||
{ id: 'unit_price', label: '단가', width: 100, align: 'right', format: 'currency' },
|
||||
{ id: 'amount', label: '금액', width: 120, align: 'right', format: 'currency' },
|
||||
{ id: 'remark', label: '비고', width: 150 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 검색 조건
|
||||
|
||||
| 필드명 | 컴포넌트 | 설정 |
|
||||
|--------|----------|------|
|
||||
| 기간 | `v2-date` | dateRange: true |
|
||||
| 거래처 | `v2-input` | placeholder: "거래처" |
|
||||
| 견적번호 | `v2-input` | placeholder: "견적번호" |
|
||||
| 품목명 | `v2-input` | placeholder: "품목명" |
|
||||
| 상태 | `v2-select` | 작성중, 제출, 승인, 반려, 수주전환 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 상세 탭 구성
|
||||
|
||||
```typescript
|
||||
tabs: [
|
||||
{
|
||||
id: 'basic',
|
||||
label: '기본정보',
|
||||
fields: [
|
||||
{ id: 'quote_no', label: '견적번호' },
|
||||
{ id: 'quote_date', label: '견적일' },
|
||||
{ id: 'customer_code', label: '거래처코드' },
|
||||
{ id: 'customer_name', label: '거래처명' },
|
||||
{ id: 'manager', label: '담당자' },
|
||||
{ id: 'valid_date', label: '유효기간' },
|
||||
{ id: 'delivery_date', label: '납기일' },
|
||||
{ id: 'payment_term', label: '결제조건' },
|
||||
{ id: 'remark', label: '비고' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'items',
|
||||
label: '품목내역',
|
||||
type: 'table',
|
||||
entityId: 'quote_items'
|
||||
},
|
||||
{
|
||||
id: 'files',
|
||||
label: '첨부파일',
|
||||
type: 'file-list'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 버튼 액션
|
||||
|
||||
### 7.1 목록 버튼
|
||||
| 버튼 | 액션 |
|
||||
|------|------|
|
||||
| 신규등록 | 견적 등록 모달 열기 |
|
||||
|
||||
### 7.2 상세 버튼
|
||||
| 버튼 | 액션 |
|
||||
|------|------|
|
||||
| 인쇄 | 견적서 PDF 출력 |
|
||||
| 복사 | 선택 견적 복사하여 신규 생성 |
|
||||
| 수주전환 | 견적 → 수주 데이터 생성 |
|
||||
| 수정 | 견적 수정 모달 열기 |
|
||||
| 삭제 | 견적 삭제 (확인 후) |
|
||||
|
||||
---
|
||||
|
||||
## 8. 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "QUOTE_MAIN",
|
||||
"screen_name": "견적관리",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"position": { "x": 0, "y": 0, "w": 12, "h": 2 },
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "date", "id": "date_range", "placeholder": "기간", "dateRange": true },
|
||||
{ "type": "input", "id": "customer_name", "placeholder": "거래처" },
|
||||
{ "type": "input", "id": "quote_no", "placeholder": "견적번호" },
|
||||
{ "type": "input", "id": "item_name", "placeholder": "품목명" },
|
||||
{ "type": "select", "id": "status", "placeholder": "상태",
|
||||
"options": [
|
||||
{ "value": "draft", "label": "작성중" },
|
||||
{ "value": "submitted", "label": "제출" },
|
||||
{ "value": "approved", "label": "승인" },
|
||||
{ "value": "rejected", "label": "반려" },
|
||||
{ "value": "converted", "label": "수주전환" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"buttons": [
|
||||
{ "label": "초기화", "action": "reset", "variant": "outline" },
|
||||
{ "label": "조회", "action": "search", "variant": "primary" }
|
||||
],
|
||||
"rightButtons": [
|
||||
{ "label": "사용자옵션", "action": "userOptions", "variant": "outline" },
|
||||
{ "label": "엑셀업로드", "action": "excelUpload", "variant": "outline" },
|
||||
{ "label": "엑셀다운로드", "action": "excelDownload", "variant": "outline" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-split-panel-layout",
|
||||
"position": { "x": 0, "y": 2, "w": 12, "h": 10 },
|
||||
"config": {
|
||||
"masterPanel": {
|
||||
"title": "견적 목록",
|
||||
"entityId": "quote_header",
|
||||
"buttons": [
|
||||
{ "label": "신규등록", "action": "create", "variant": "primary" }
|
||||
],
|
||||
"columns": [
|
||||
{ "id": "quote_no", "label": "견적번호", "width": 120 },
|
||||
{ "id": "quote_date", "label": "견적일", "width": 100 },
|
||||
{ "id": "customer_name", "label": "거래처", "width": 150 },
|
||||
{ "id": "total_amount", "label": "견적금액", "width": 120, "align": "right" },
|
||||
{ "id": "status", "label": "상태", "width": 80 },
|
||||
{ "id": "manager", "label": "담당자", "width": 100 }
|
||||
]
|
||||
},
|
||||
"detailPanel": {
|
||||
"title": "견적 상세",
|
||||
"buttons": [
|
||||
{ "label": "인쇄", "action": "print", "variant": "outline" },
|
||||
{ "label": "복사", "action": "copy", "variant": "outline" },
|
||||
{ "label": "수주전환", "action": "convert", "variant": "secondary" },
|
||||
{ "label": "수정", "action": "edit", "variant": "outline" },
|
||||
{ "label": "삭제", "action": "delete", "variant": "destructive" }
|
||||
],
|
||||
"tabs": [
|
||||
{
|
||||
"id": "basic",
|
||||
"label": "기본정보",
|
||||
"type": "form"
|
||||
},
|
||||
{
|
||||
"id": "items",
|
||||
"label": "품목내역",
|
||||
"type": "table",
|
||||
"entityId": "quote_items",
|
||||
"relationType": "one-to-many",
|
||||
"relationKey": "quote_id"
|
||||
},
|
||||
{
|
||||
"id": "files",
|
||||
"label": "첨부파일",
|
||||
"type": "file"
|
||||
}
|
||||
]
|
||||
},
|
||||
"defaultRatio": 40,
|
||||
"resizable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 데이터베이스 테이블
|
||||
|
||||
### quote_header (견적 헤더)
|
||||
```sql
|
||||
CREATE TABLE quote_header (
|
||||
id SERIAL PRIMARY KEY,
|
||||
company_code VARCHAR(20) NOT NULL,
|
||||
quote_no VARCHAR(50) NOT NULL,
|
||||
quote_date DATE NOT NULL,
|
||||
customer_code VARCHAR(50),
|
||||
customer_name VARCHAR(200),
|
||||
total_amount NUMERIC(15,2),
|
||||
tax_amount NUMERIC(15,2),
|
||||
status VARCHAR(20) DEFAULT 'draft',
|
||||
valid_date DATE,
|
||||
delivery_date DATE,
|
||||
payment_term VARCHAR(100),
|
||||
manager VARCHAR(100),
|
||||
remark TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
### quote_items (견적 품목)
|
||||
```sql
|
||||
CREATE TABLE quote_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
company_code VARCHAR(20) NOT NULL,
|
||||
quote_id INTEGER REFERENCES quote_header(id),
|
||||
seq INTEGER,
|
||||
item_code VARCHAR(50),
|
||||
item_name VARCHAR(200),
|
||||
spec VARCHAR(200),
|
||||
quantity NUMERIC(15,3),
|
||||
unit VARCHAR(20),
|
||||
unit_price NUMERIC(15,2),
|
||||
amount NUMERIC(15,2),
|
||||
remark TEXT
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 구현 체크리스트
|
||||
|
||||
- [x] 검색 영역: v2-table-search-widget
|
||||
- [x] 분할 패널: v2-split-panel-layout
|
||||
- [x] 목록 테이블: v2-table-list
|
||||
- [x] 상세 탭: v2-tabs-widget
|
||||
- [x] 품목 내역 테이블: v2-table-list (nested)
|
||||
- [ ] 인쇄 기능: 별도 구현 필요
|
||||
- [ ] 수주 전환: 비즈니스 로직 구현
|
||||
|
||||
**현재 V2 컴포넌트로 100% 구현 가능**
|
||||
|
|
@ -0,0 +1,601 @@
|
|||
# 생산계획관리 (Production Plan Management)
|
||||
|
||||
> ⚠️ **중요 안내**: 이 화면은 **복합형 레이아웃** (좌우 분할 패널 + 타임라인 스케줄러)으로, 현재 V2 컴포넌트만으로는 완전한 구현이 불가능합니다. 아래 문서는 화면 분석 및 향후 구현 계획을 위한 참조용입니다.
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
| 항목 | 내용 |
|
||||
|------|------|
|
||||
| **화면명** | 생산계획관리 |
|
||||
| **영문명** | Production Plan Management |
|
||||
| **화면 유형** | 복합형 (좌우 분할 패널 + 타임라인 스케줄러) |
|
||||
| **메인 테이블** | `production_plan_mng` |
|
||||
| **관련 테이블** | `sales_order_mng`, `item_info`, `equipment_info`, `bom_info` |
|
||||
| **주요 기능** | 수주 기반 생산계획 수립, 타임라인 스케줄러, 자동 스케줄 생성, 반제품 계획 연동 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 구조 분석
|
||||
|
||||
### 2.1 레이아웃 구조
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 검색 섹션 │
|
||||
│ [검색필드들...] [사용자옵션] [엑셀업로드] [엑셀다운로드] │
|
||||
├────────────────────────────────┬──┬──────────────────────────────────────────┤
|
||||
│ 왼쪽 패널 (50%, 리사이즈) │ │ 오른쪽 패널 (50%) │
|
||||
│ ┌────────────────────────────┐ │리│ ┌──────────────────────────────────────┐ │
|
||||
│ │ [수주데이터] [안전재고부족] │ │사│ │ [완제품 생산계획] [반제품 생산계획] │ │
|
||||
│ ├────────────────────────────┤ │이│ ├──────────────────────────────────────┤ │
|
||||
│ │ │ │즈│ │ │ │
|
||||
│ │ 수주 목록 테이블 │ │핸│ │ 타임라인 스케줄러 │
|
||||
│ │ (그룹화된 품목별 수주) │ │들│ │ (간트차트 형태) │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ - 체크박스 │ │ │ │ - 날짜별 그리드 │
|
||||
│ │ - 접기/펼치기 토글 │ │ │ │ - 생산계획 바 (드래그 가능) │
|
||||
│ │ - 품목별 그룹 행 │ │ │ │ - 납기일 마커 │
|
||||
│ │ - 수주 상세 행 │ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ └────────────────────────────┘ │ │ └──────────────────────────────────────┘ │
|
||||
│ [계획에 없는 품목만] [선택품목 불러오기] [새로고침] │ [자동스케줄] [저장] [초기화] │
|
||||
└────────────────────────────────┴──┴──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 탭 구조
|
||||
|
||||
**왼쪽 패널 탭**:
|
||||
1. **수주데이터**: 수주 목록 (품목별 그룹핑)
|
||||
2. **안전재고 부족분**: 안전재고 미달 품목 목록
|
||||
|
||||
**오른쪽 패널 탭**:
|
||||
1. **완제품 생산계획**: 완제품 타임라인 스케줄러
|
||||
2. **반제품 생산계획**: 반제품 타임라인 스케줄러
|
||||
|
||||
---
|
||||
|
||||
## 3. 테이블 정의
|
||||
|
||||
### 3.1 메인 테이블: `production_plan_mng`
|
||||
|
||||
| 컬럼명 | 타입 | NULL | 설명 |
|
||||
|--------|------|------|------|
|
||||
| id | SERIAL | NO | PK |
|
||||
| company_code | VARCHAR(20) | NO | 회사 코드 |
|
||||
| plan_no | VARCHAR(50) | NO | 생산계획번호 |
|
||||
| plan_date | DATE | NO | 계획일자 |
|
||||
| item_code | VARCHAR(50) | NO | 품목코드 |
|
||||
| item_name | VARCHAR(200) | YES | 품명 |
|
||||
| plan_qty | NUMERIC(15,3) | NO | 계획수량 |
|
||||
| start_date | DATE | NO | 시작일 |
|
||||
| end_date | DATE | NO | 종료일 |
|
||||
| due_date | DATE | YES | 납기일 |
|
||||
| equipment_id | INTEGER | YES | 설비 ID (FK) |
|
||||
| equipment_name | VARCHAR(100) | YES | 설비명 |
|
||||
| status | VARCHAR(20) | YES | 상태 (계획/지시/진행/완료) |
|
||||
| priority | VARCHAR(20) | YES | 우선순위 |
|
||||
| work_shift | VARCHAR(20) | YES | 작업조 (주간/야간/주야) |
|
||||
| manager_name | VARCHAR(100) | YES | 담당자 |
|
||||
| work_order_no | VARCHAR(50) | YES | 작업지시번호 |
|
||||
| remarks | TEXT | YES | 비고 |
|
||||
| order_no | VARCHAR(50) | YES | 관련 수주번호 |
|
||||
| partner_id | VARCHAR(50) | YES | 거래처 ID |
|
||||
| hourly_capacity | NUMERIC(15,3) | YES | 시간당 생산능력 |
|
||||
| daily_capacity | NUMERIC(15,3) | YES | 일일 생산능력 |
|
||||
| lead_time | INTEGER | YES | 리드타임 (일) |
|
||||
| product_type | VARCHAR(20) | YES | 제품유형 (완제품/반제품) |
|
||||
| parent_plan_id | INTEGER | YES | 모품목 계획 ID (반제품용) |
|
||||
| created_date | TIMESTAMPTZ | YES | 생성일시 |
|
||||
| created_by | VARCHAR(50) | YES | 생성자 |
|
||||
| updated_date | TIMESTAMPTZ | YES | 수정일시 |
|
||||
| updated_by | VARCHAR(50) | YES | 수정자 |
|
||||
|
||||
### 3.2 관련 테이블
|
||||
|
||||
#### `equipment_info` (설비 정보)
|
||||
|
||||
| 컬럼명 | 타입 | 설명 |
|
||||
|--------|------|------|
|
||||
| id | SERIAL | PK |
|
||||
| equipment_code | VARCHAR(50) | 설비코드 |
|
||||
| equipment_name | VARCHAR(100) | 설비명 |
|
||||
| equipment_type | VARCHAR(50) | 설비유형 |
|
||||
| capacity_per_hour | NUMERIC(15,3) | 시간당 생산능력 |
|
||||
| status | VARCHAR(20) | 상태 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 구현 가능 여부 분석
|
||||
|
||||
### 4.1 현재 V2 컴포넌트로 구현 가능한 기능
|
||||
|
||||
| 기능 | 가능 여부 | 사용 컴포넌트 | 비고 |
|
||||
|------|:---------:|--------------|------|
|
||||
| 검색 필터 | ✅ | `v2-table-search-widget` | |
|
||||
| 기본 버튼 (엑셀, 사용자옵션) | ✅ | `v2-button-primary` | |
|
||||
| 단일 테이블 목록 | ✅ | `v2-table-list` | |
|
||||
| 기본 모달 폼 | ✅ | 모달 화면 | |
|
||||
| 좌우 분할 패널 (기본) | ⚠️ | `v2-split-panel-layout` | 테이블/리스트만 표시 가능 |
|
||||
| 탭 컴포넌트 (기본) | ⚠️ | `v2-tabs-widget` | 디자인 모드에서 컴포넌트 배치 |
|
||||
|
||||
### 4.2 현재 V2 컴포넌트의 제한 사항
|
||||
|
||||
#### `v2-split-panel-layout` 제한
|
||||
|
||||
**현재 기능**:
|
||||
- 좌우 분할 패널 (리사이즈 가능)
|
||||
- 각 패널에 **테이블** 또는 **리스트** 표시 (`displayMode: "list" | "table"`)
|
||||
- leftPanel ↔ rightPanel 관계 설정 (relation)
|
||||
- 우측 패널에 추가 탭 (additionalTabs)
|
||||
|
||||
**제한 사항**:
|
||||
- ❌ 패널 안에 **임의의 컴포넌트** (타임라인 등)를 배치할 수 없음
|
||||
- ❌ **그룹화된 테이블** (접기/펼치기) 미지원
|
||||
- ❌ 복잡한 커스텀 UI 배치 불가
|
||||
|
||||
#### `v2-tabs-widget` 제한
|
||||
|
||||
**현재 기능**:
|
||||
- 탭별 컴포넌트 자유 배치
|
||||
- 디자인 모드에서 드래그&드롭
|
||||
|
||||
**제한 사항**:
|
||||
- ❌ 탭 내에 **다른 V2 컴포넌트**를 완전히 자유롭게 배치하기 어려움
|
||||
- ❌ 런타임에서 복잡한 컴포넌트 렌더링 제한
|
||||
|
||||
### 4.3 생산계획관리에 필요한 기능 vs 현재 지원
|
||||
|
||||
| 필요 기능 | 현재 지원 | 설명 |
|
||||
|----------|:---------:|------|
|
||||
| 좌우 분할 패널 | ⚠️ 부분 | `v2-split-panel-layout` - 테이블만 가능 |
|
||||
| 왼쪽 패널 탭 (수주/안전재고) | ❌ | 분할 패널 내 탭 조합 미지원 |
|
||||
| **그룹화된 테이블** (품목별 접기/펼치기) | ❌ | 신규 개발 필요 |
|
||||
| 오른쪽 패널 탭 (완제품/반제품) | ❌ | 분할 패널 내 탭 조합 미지원 |
|
||||
| **타임라인 스케줄러** (간트차트) | ❌ | 신규 개발 필요 |
|
||||
| 드래그&드롭 스케줄 이동 | ❌ | 신규 개발 필요 |
|
||||
| 복잡한 상세 모달 (분할, 설비할당) | ❌ | 커스텀 모달 개발 필요 |
|
||||
|
||||
### 4.4 향후 개발 필요 컴포넌트
|
||||
|
||||
```
|
||||
필요 컴포넌트 목록:
|
||||
1. v2-timeline-scheduler - 타임라인/간트차트 스케줄러 (핵심!)
|
||||
2. v2-table-grouped - 그룹화된 테이블 (접기/펼치기)
|
||||
3. v2-split-panel-enhanced - 패널 내 임의 컴포넌트 배치 가능한 확장판
|
||||
4. v2-modal-complex - 복잡한 모달 (분할, 다단계, 설비할당)
|
||||
```
|
||||
|
||||
### 4.5 현재 구현 가능한 최대 범위
|
||||
|
||||
현재 V2 컴포넌트로 구현 가능한 **최대 범위**:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ 검색 섹션 (v2-table-search-widget) │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 생산계획 테이블 (v2-table-list) - 단일 테이블, 그룹화 없음 │
|
||||
│ │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ [등록] [수정] [삭제] (v2-button-primary) │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**구현 불가능한 핵심 기능**:
|
||||
- 품목별 그룹핑 (접기/펼치기)
|
||||
- 간트차트 타임라인
|
||||
- 자동 스케줄 생성
|
||||
- 드래그로 스케줄 이동
|
||||
|
||||
---
|
||||
|
||||
## 5. 단순화된 구현 방안 (임시)
|
||||
|
||||
> 현재 V2 컴포넌트만으로 **간소화된 버전**을 구현할 수 있습니다.
|
||||
|
||||
### 5.1 간소화 버전 레이아웃
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ 검색 섹션 │
|
||||
│ [품목코드] [품명] [계획기간] [상태] [사용자옵션] [엑셀다운로드] │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 생산계획 목록 테이블 │
|
||||
│ (단일 테이블, 그룹화 없음) │
|
||||
│ │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ [신규등록] [수정] [삭제] │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.2 간소화 버전 테이블 컬럼
|
||||
|
||||
| 순서 | 컬럼명 | 표시명 | 정렬 | 형식 |
|
||||
|:----:|--------|--------|:----:|------|
|
||||
| 1 | plan_no | 계획번호 | left | text |
|
||||
| 2 | plan_date | 계획일자 | center | date |
|
||||
| 3 | item_code | 품목코드 | left | text |
|
||||
| 4 | item_name | 품명 | left | text |
|
||||
| 5 | plan_qty | 계획수량 | right | number |
|
||||
| 6 | start_date | 시작일 | center | date |
|
||||
| 7 | end_date | 종료일 | center | date |
|
||||
| 8 | due_date | 납기일 | center | date |
|
||||
| 9 | equipment_name | 설비 | left | text |
|
||||
| 10 | status | 상태 | center | badge |
|
||||
| 11 | manager_name | 담당자 | left | text |
|
||||
| 12 | product_type | 제품유형 | center | text |
|
||||
|
||||
### 5.3 간소화 버전 모달 필드
|
||||
|
||||
| 필드명 | 라벨 | 타입 | 필수 |
|
||||
|--------|------|------|:----:|
|
||||
| plan_no | 계획번호 | text | ✅ |
|
||||
| plan_date | 계획일자 | date | ✅ |
|
||||
| item_code | 품목코드 | select (품목 검색) | ✅ |
|
||||
| item_name | 품명 | text (자동) | |
|
||||
| plan_qty | 계획수량 | number | ✅ |
|
||||
| start_date | 시작일 | date | ✅ |
|
||||
| end_date | 종료일 | date | ✅ |
|
||||
| due_date | 납기일 | date | |
|
||||
| equipment_id | 설비 | select | |
|
||||
| status | 상태 | select | ✅ |
|
||||
| priority | 우선순위 | select | |
|
||||
| work_shift | 작업조 | select | |
|
||||
| manager_name | 담당자 | text | |
|
||||
| remarks | 비고 | textarea | |
|
||||
| product_type | 제품유형 | select | |
|
||||
|
||||
---
|
||||
|
||||
## 6. 원본 HTML 기능 상세 분석
|
||||
|
||||
### 6.1 수주데이터 탭 (왼쪽 패널)
|
||||
|
||||
**테이블 구조**:
|
||||
- 품목별 그룹 행 (접기/펼치기 가능)
|
||||
- 수주 상세 행 (그룹 행 하위)
|
||||
|
||||
**품목 그룹 행 컬럼**:
|
||||
| 컬럼 | 설명 |
|
||||
|------|------|
|
||||
| 체크박스 | 품목 그룹 선택 |
|
||||
| 토글 | 상세 접기/펼치기 |
|
||||
| 품목코드 | |
|
||||
| 품목명 | |
|
||||
| 총수주량 | 해당 품목의 모든 수주 합계 |
|
||||
| 출고량 | |
|
||||
| 잔량 | 총수주량 - 출고량 |
|
||||
| 현재고 | |
|
||||
| 안전재고 | |
|
||||
| 출하계획량 | |
|
||||
| 기생산계획량 | 이미 등록된 생산계획 수량 |
|
||||
| 생산진행 | 현재 생산 중인 수량 |
|
||||
| 필요생산계획 | 추가로 계획해야 할 수량 (빨간색 강조) |
|
||||
|
||||
**수주 상세 행**:
|
||||
- 수주번호, 거래처, 상태 배지
|
||||
- 수주량, 출고량, 잔량
|
||||
- 납기일
|
||||
|
||||
**버튼**:
|
||||
- `계획에 없는 품목만` 체크박스 필터
|
||||
- `선택 품목 불러오기`: 선택한 품목을 생산계획으로 등록
|
||||
- `새로고침`
|
||||
|
||||
### 6.2 안전재고 부족분 탭 (왼쪽 패널)
|
||||
|
||||
**테이블 컬럼**:
|
||||
| 컬럼 | 설명 |
|
||||
|------|------|
|
||||
| 체크박스 | |
|
||||
| 품목코드 | |
|
||||
| 품목명 | |
|
||||
| 현재고 | |
|
||||
| 안전재고 | |
|
||||
| 부족수량 | 빨간색 (마이너스) |
|
||||
| 권장생산량 | 녹색 |
|
||||
| 최종입고일 | |
|
||||
|
||||
### 6.3 완제품 생산계획 탭 (오른쪽 패널)
|
||||
|
||||
**스케줄 옵션**:
|
||||
- 안전리드타임 (일)
|
||||
- 표시 기간 (주)
|
||||
- 미진행 계획 재계산 체크박스
|
||||
|
||||
**범례**:
|
||||
- 계획 (파란색)
|
||||
- 지시 (주황색)
|
||||
- 진행 (녹색)
|
||||
- 완료 (회색)
|
||||
- 납기일 (빨간 테두리)
|
||||
- 긴급 (빨간 아이콘)
|
||||
|
||||
**타임라인 구조**:
|
||||
- 날짜별 헤더 (일/월 표시, 주말 강조, 오늘 강조)
|
||||
- 품목별 행
|
||||
- 생산계획 바 (드래그로 이동 가능)
|
||||
- 클릭 시 상세 모달 오픈
|
||||
|
||||
**버튼**:
|
||||
- `새로고침`
|
||||
- `자동 스케줄 생성`: 선택된 품목에 대해 자동으로 생산계획 생성
|
||||
- `선택 계획 병합`: 같은 품목의 계획을 하나로 병합
|
||||
- `선택 품목 → 반제품 계획`: BOM 기반 반제품 계획 생성
|
||||
- `저장`
|
||||
- `초기화`
|
||||
|
||||
### 6.4 반제품 생산계획 탭 (오른쪽 패널)
|
||||
|
||||
**옵션**:
|
||||
- 현재고 및 안전재고 감안
|
||||
- 진행중인 계획 유지하고 재계산
|
||||
- 투입 완료된 반제품 제외
|
||||
|
||||
**안내**:
|
||||
- 완제품 생산계획 기준으로 필요한 반제품 계획 자동 생성
|
||||
- 모품목 생산 시작일 고려하여 납기일 설정
|
||||
- BOM(자재명세서) 정보 기반 필요 수량 계산
|
||||
|
||||
### 6.5 생산 스케줄 상세 모달
|
||||
|
||||
**기본 정보**:
|
||||
- 품목코드 (읽기전용)
|
||||
- 품목명 (읽기전용)
|
||||
|
||||
**근거 정보**:
|
||||
- 수주번호, 안전재고, 재고부족 등 표시
|
||||
|
||||
**생산 정보**:
|
||||
- 총 생산수량
|
||||
- 납기일 (읽기전용)
|
||||
- 계획 시작일 (수정 가능)
|
||||
- 계획 종료일 (수정 가능)
|
||||
- 생산 기간 (자동 계산)
|
||||
|
||||
**과거 계획 경고**:
|
||||
- 시작일이 과거인 경우 경고 표시
|
||||
- `오늘부터 재조정` 버튼
|
||||
- `작업지시 즉시 생성` 버튼
|
||||
|
||||
**계획 분할**:
|
||||
- 분할 개수 선택 (2~4개)
|
||||
- 각 분할 수량 입력
|
||||
- 분할 실행
|
||||
|
||||
**설비 할당**:
|
||||
- 설비 선택 버튼
|
||||
- 선택된 설비 목록
|
||||
|
||||
**생산 상태**:
|
||||
- 상태 (자동 관리): 계획됨/작업지시/진행중/완료
|
||||
|
||||
**추가 정보**:
|
||||
- 담당자
|
||||
- 작업지시번호
|
||||
- 비고
|
||||
|
||||
**버튼**:
|
||||
- 삭제
|
||||
- 취소
|
||||
- 저장
|
||||
|
||||
---
|
||||
|
||||
## 7. 구현 우선순위
|
||||
|
||||
### Phase 1: 간소화 버전 (현재 구현 가능)
|
||||
|
||||
V2 컴포넌트로 기본 CRUD 화면 구현:
|
||||
- 검색 위젯
|
||||
- 단일 테이블 (그룹화 없음)
|
||||
- 기본 모달 폼
|
||||
- 상태 배지
|
||||
|
||||
### Phase 2: 컴포넌트 개발 후
|
||||
|
||||
1. `v2-tabs` 컴포넌트 개발
|
||||
2. `v2-split-panel` 컴포넌트 개발
|
||||
3. `v2-table-grouped` 컴포넌트 개발
|
||||
|
||||
### Phase 3: 타임라인 스케줄러
|
||||
|
||||
1. `v2-timeline-scheduler` 컴포넌트 개발
|
||||
2. 드래그&드롭 기능
|
||||
3. 자동 스케줄 생성 로직
|
||||
4. 반제품 연동
|
||||
|
||||
---
|
||||
|
||||
## 8. 참고 사항
|
||||
|
||||
### 8.1 상태 배지 스타일
|
||||
|
||||
| 상태 | 배경색 | 글자색 | 설명 |
|
||||
|------|--------|--------|------|
|
||||
| 계획 | #dbeafe | #1e40af | 파란색 |
|
||||
| 지시 | #fef3c7 | #92400e | 주황색 |
|
||||
| 진행 | #d1fae5 | #065f46 | 녹색 |
|
||||
| 완료 | #f3f4f6 | #4b5563 | 회색 |
|
||||
| 긴급 | #fee2e2 | #991b1b | 빨간색 |
|
||||
|
||||
### 8.2 자동 스케줄 생성 로직
|
||||
|
||||
```
|
||||
1. 선택된 품목의 필요 생산수량 계산
|
||||
- 필요수량 = 잔량 + 안전재고 - 현재고 - 기생산계획량
|
||||
|
||||
2. 납기일에서 안전리드타임 차감하여 완료일 계산
|
||||
|
||||
3. 일일 생산능력으로 필요 생산일수 계산
|
||||
|
||||
4. 완료일에서 역산하여 시작일 계산
|
||||
|
||||
5. 설비 가용성 확인 및 자동 할당
|
||||
|
||||
6. 반제품이 필요한 경우 BOM 기반 반제품 계획 생성
|
||||
```
|
||||
|
||||
### 8.3 계획 분할 로직
|
||||
|
||||
```
|
||||
1. 원본 계획의 총 수량 확인
|
||||
|
||||
2. 분할 개수 선택 (2~4개)
|
||||
|
||||
3. 각 분할 수량 입력 (합계 = 원본 수량)
|
||||
|
||||
4. 분할 실행 시:
|
||||
- 원본 계획 삭제
|
||||
- 새로운 N개의 계획 생성
|
||||
- 각각 별도의 시작일/종료일 설정 가능
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. DB INSERT JSON (간소화 버전)
|
||||
|
||||
> ⚠️ 이 JSON은 **간소화 버전**입니다. 전체 기능 구현 시 별도 개발이 필요합니다.
|
||||
|
||||
### 9.1 screen_definitions
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_name": "생산계획관리",
|
||||
"screen_code": "{COMPANY_CODE}_PP_MAIN",
|
||||
"table_name": "production_plan_mng",
|
||||
"company_code": "{COMPANY_CODE}",
|
||||
"description": "생산계획 관리 화면 (간소화 버전)",
|
||||
"is_active": "Y",
|
||||
"db_source_type": "internal",
|
||||
"data_source_type": "database"
|
||||
}
|
||||
```
|
||||
|
||||
### 9.2 screen_layouts_v2.layout_data (간소화 버전)
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0",
|
||||
"components": [
|
||||
{
|
||||
"id": "comp_search",
|
||||
"url": "@/lib/registry/components/v2-table-search-widget",
|
||||
"size": { "width": 1920, "height": 80 },
|
||||
"position": { "x": 0, "y": 20, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-table-search-widget",
|
||||
"label": "검색 필터"
|
||||
},
|
||||
"displayOrder": 0
|
||||
},
|
||||
{
|
||||
"id": "comp_table",
|
||||
"url": "@/lib/registry/components/v2-table-list",
|
||||
"size": { "width": 1920, "height": 700 },
|
||||
"position": { "x": 0, "y": 120, "z": 1 },
|
||||
"overrides": {
|
||||
"type": "v2-table-list",
|
||||
"label": "생산계획 목록",
|
||||
"columns": [
|
||||
{ "columnName": "plan_no", "displayName": "계획번호", "order": 0, "visible": true, "sortable": true, "format": "text", "align": "left" },
|
||||
{ "columnName": "plan_date", "displayName": "계획일자", "order": 1, "visible": true, "sortable": true, "format": "date", "align": "center" },
|
||||
{ "columnName": "item_code", "displayName": "품목코드", "order": 2, "visible": true, "sortable": true, "format": "text", "align": "left" },
|
||||
{ "columnName": "item_name", "displayName": "품명", "order": 3, "visible": true, "sortable": true, "format": "text", "align": "left" },
|
||||
{ "columnName": "plan_qty", "displayName": "계획수량", "order": 4, "visible": true, "sortable": true, "format": "number", "align": "right" },
|
||||
{ "columnName": "start_date", "displayName": "시작일", "order": 5, "visible": true, "sortable": true, "format": "date", "align": "center" },
|
||||
{ "columnName": "end_date", "displayName": "종료일", "order": 6, "visible": true, "sortable": true, "format": "date", "align": "center" },
|
||||
{ "columnName": "due_date", "displayName": "납기일", "order": 7, "visible": true, "sortable": true, "format": "date", "align": "center" },
|
||||
{ "columnName": "equipment_name", "displayName": "설비", "order": 8, "visible": true, "sortable": true, "format": "text", "align": "left" },
|
||||
{ "columnName": "status", "displayName": "상태", "order": 9, "visible": true, "sortable": true, "format": "text", "align": "center" },
|
||||
{ "columnName": "product_type", "displayName": "제품유형", "order": 10, "visible": true, "sortable": true, "format": "text", "align": "center" },
|
||||
{ "columnName": "manager_name", "displayName": "담당자", "order": 11, "visible": true, "sortable": true, "format": "text", "align": "left" }
|
||||
],
|
||||
"selectedTable": "production_plan_mng",
|
||||
"pagination": { "enabled": true, "pageSize": 20, "pageSizeOptions": [10, 20, 50, 100] },
|
||||
"checkbox": { "enabled": true, "multiple": true },
|
||||
"horizontalScroll": { "enabled": true, "minColumnWidth": 80, "maxColumnWidth": 200 }
|
||||
},
|
||||
"displayOrder": 1
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_register",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 100, "height": 40 },
|
||||
"position": { "x": 1580, "y": 70, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "신규 등록",
|
||||
"type": "v2-button-primary",
|
||||
"action": { "type": "modal", "modalTitle": "생산계획 등록", "targetScreenId": null },
|
||||
"variant": "success"
|
||||
},
|
||||
"displayOrder": 2
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_edit",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 80, "height": 40 },
|
||||
"position": { "x": 1690, "y": 70, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "수정",
|
||||
"type": "v2-button-primary",
|
||||
"action": { "type": "edit", "modalTitle": "생산계획 수정", "targetScreenId": null },
|
||||
"variant": "secondary"
|
||||
},
|
||||
"displayOrder": 3
|
||||
},
|
||||
{
|
||||
"id": "comp_btn_delete",
|
||||
"url": "@/lib/registry/components/v2-button-primary",
|
||||
"size": { "width": 80, "height": 40 },
|
||||
"position": { "x": 1780, "y": 70, "z": 1 },
|
||||
"overrides": {
|
||||
"text": "삭제",
|
||||
"type": "v2-button-primary",
|
||||
"action": { "type": "delete" },
|
||||
"variant": "danger"
|
||||
},
|
||||
"displayOrder": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 구현 체크리스트
|
||||
|
||||
### 10.1 간소화 버전 (현재 구현 가능)
|
||||
|
||||
| 체크 | 항목 | 설명 |
|
||||
|:----:|------|------|
|
||||
| ☐ | **테이블 생성** | `production_plan_mng` 테이블 생성 |
|
||||
| ☐ | **화면 정의** | `screen_definitions` INSERT |
|
||||
| ☐ | **모달 화면 생성** | 등록/수정 모달 화면 생성 |
|
||||
| ☐ | **메인 화면 생성** | `screen_layouts_v2` INSERT |
|
||||
| ☐ | **메뉴 연결** | 대상 메뉴에 화면 할당 |
|
||||
| ☐ | **기본 CRUD 테스트** | 등록/수정/삭제/조회 테스트 |
|
||||
|
||||
### 10.2 전체 버전 (향후 구현)
|
||||
|
||||
| 체크 | 항목 | 설명 |
|
||||
|:----:|------|------|
|
||||
| ☐ | **v2-tabs 개발** | 탭 컴포넌트 개발 |
|
||||
| ☐ | **v2-split-panel 개발** | 분할 패널 컴포넌트 개발 |
|
||||
| ☐ | **v2-table-grouped 개발** | 그룹화 테이블 컴포넌트 개발 |
|
||||
| ☐ | **v2-timeline-scheduler 개발** | 타임라인 스케줄러 개발 |
|
||||
| ☐ | **자동 스케줄 로직** | 자동 스케줄 생성 백엔드 API |
|
||||
| ☐ | **반제품 연동** | BOM 기반 반제품 계획 생성 |
|
||||
| ☐ | **드래그&드롭** | 타임라인 드래그 이동 기능 |
|
||||
|
||||
---
|
||||
|
||||
## 11. 관련 문서
|
||||
|
||||
- [수주관리](../02_sales/order.md)
|
||||
- [품목정보](../01_master-data/item-info.md)
|
||||
- [설비관리](../05_equipment/equipment-info.md) (예정)
|
||||
- [BOM관리](../01_master-data/bom-info.md) (예정)
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
# 작업지시 화면 구현 가이드
|
||||
|
||||
> **화면명**: 작업지시
|
||||
> **파일**: 작업지시.html
|
||||
> **분류**: 생산관리
|
||||
> **구현 가능**: ⚠️ 부분 (그룹화 테이블 필요)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
생산계획을 기반으로 작업지시를 생성하고 관리하는 화면입니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 작업지시 목록 조회 (탭별 구분)
|
||||
- 그룹화 기능 (작업일자, 공정별)
|
||||
- 작업지시 생성/수정/삭제
|
||||
- 작업지시서 인쇄
|
||||
- 실적 연계
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [기간] [품목] [공정] [작업상태▼] [초기화][조회] [사용자옵션][엑셀] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ [전체] [대기] [진행중] [완료] [지연] │
|
||||
├───────────────────────┬─────────────────────────────────────────┤
|
||||
│ 📋 작업지시 목록 │ 📄 작업지시 상세 │
|
||||
│ ─────────────── │ [인쇄] [시작] [완료] [수정] [삭제] │
|
||||
│ Group by: [작업일자▼] │ ───────────────────────── │
|
||||
│ ┌──────────────────┐ │ 지시번호: WO-2026-0001 │
|
||||
│ │▼ 2026-01-30 (5) │ │ 품목명: 제품A │
|
||||
│ │ WO-001|제품A|대기│ │ 지시수량: 100 EA │
|
||||
│ │ WO-002|제품B|진행│ ├─────────────────────────────────────────┤
|
||||
│ │▼ 2026-01-31 (3) │ │ [자재투입] [공정현황] [실적현황] │
|
||||
│ │ WO-003|제품C|대기│ │ ─────────────────────────── │
|
||||
│ └──────────────────┘ │ [투입자재 테이블] │
|
||||
└───────────────────────┴─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 상태 탭 | `v2-tabs-widget` | ✅ 가능 |
|
||||
| 작업지시 목록 (그룹화) | `v2-table-list` | ⚠️ 그룹화 미지원 |
|
||||
| 분할 패널 | `v2-split-panel-layout` | ✅ 가능 |
|
||||
| 상세 탭 | `v2-tabs-widget` | ✅ 가능 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 테이블 정의
|
||||
|
||||
### 4.1 작업지시 목록
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'work_order_no', label: '지시번호', width: 120 },
|
||||
{ id: 'work_date', label: '작업일', width: 100 },
|
||||
{ id: 'item_code', label: '품목코드', width: 100 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'order_qty', label: '지시수량', width: 100, align: 'right' },
|
||||
{ id: 'prod_qty', label: '생산수량', width: 100, align: 'right' },
|
||||
{ id: 'process_name', label: '공정', width: 100 },
|
||||
{ id: 'status', label: '상태', width: 80 },
|
||||
{ id: 'worker', label: '작업자', width: 100 }
|
||||
]
|
||||
```
|
||||
|
||||
### 4.2 자재투입 탭
|
||||
|
||||
```typescript
|
||||
materialColumns: [
|
||||
{ id: 'item_code', label: '품목코드', width: 100 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'required_qty', label: '소요량', width: 100, align: 'right' },
|
||||
{ id: 'issued_qty', label: '투입량', width: 100, align: 'right' },
|
||||
{ id: 'unit', label: '단위', width: 60 },
|
||||
{ id: 'warehouse', label: '출고창고', width: 100 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 상태 탭
|
||||
|
||||
```typescript
|
||||
statusTabs: [
|
||||
{ id: 'all', label: '전체', count: 25 },
|
||||
{ id: 'waiting', label: '대기', count: 10 },
|
||||
{ id: 'progress', label: '진행중', count: 8 },
|
||||
{ id: 'completed', label: '완료', count: 5 },
|
||||
{ id: 'delayed', label: '지연', count: 2 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 그룹화 기능 (v2-grouped-table 필요)
|
||||
|
||||
```typescript
|
||||
groupByOptions: [
|
||||
{ id: 'work_date', label: '작업일자' },
|
||||
{ id: 'process_name', label: '공정' },
|
||||
{ id: 'item_type', label: '품목구분' }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 현재 구현 가능 범위
|
||||
|
||||
### ✅ 가능
|
||||
- 검색 영역
|
||||
- 상태 탭 전환
|
||||
- 분할 패널
|
||||
- 상세 탭
|
||||
- 자재투입/공정현황/실적현황 테이블
|
||||
|
||||
### ⚠️ 부분 가능
|
||||
- 작업지시 목록: 그룹화 없이 일반 테이블
|
||||
|
||||
### ❌ 불가능
|
||||
- 동적 그룹화
|
||||
|
||||
---
|
||||
|
||||
## 8. 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "WORK_ORDER_MAIN",
|
||||
"screen_name": "작업지시",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"position": { "x": 0, "y": 0, "w": 12, "h": 1 },
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "date", "id": "date_range", "placeholder": "기간", "dateRange": true },
|
||||
{ "type": "input", "id": "item_name", "placeholder": "품목명" },
|
||||
{ "type": "select", "id": "process", "placeholder": "공정" },
|
||||
{ "type": "select", "id": "status", "placeholder": "상태" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-tabs-widget",
|
||||
"position": { "x": 0, "y": 1, "w": 12, "h": 11 },
|
||||
"config": {
|
||||
"tabs": [
|
||||
{ "id": "all", "label": "전체" },
|
||||
{ "id": "waiting", "label": "대기" },
|
||||
{ "id": "progress", "label": "진행중" },
|
||||
{ "id": "completed", "label": "완료" },
|
||||
{ "id": "delayed", "label": "지연" }
|
||||
],
|
||||
"tabContent": {
|
||||
"type": "v2-split-panel-layout",
|
||||
"config": {
|
||||
"masterPanel": {
|
||||
"title": "작업지시 목록",
|
||||
"entityId": "work_order",
|
||||
"columns": [
|
||||
{ "id": "work_order_no", "label": "지시번호" },
|
||||
{ "id": "work_date", "label": "작업일" },
|
||||
{ "id": "item_name", "label": "품목명" },
|
||||
{ "id": "order_qty", "label": "지시수량" },
|
||||
{ "id": "status", "label": "상태" }
|
||||
]
|
||||
},
|
||||
"detailPanel": {
|
||||
"tabs": [
|
||||
{ "id": "material", "label": "자재투입", "entityId": "work_order_material" },
|
||||
{ "id": "process", "label": "공정현황", "entityId": "work_order_process" },
|
||||
{ "id": "result", "label": "실적현황", "entityId": "work_order_result" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**v2-grouped-table 개발 시 재활용 가능**
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
# 발주관리 화면 구현 가이드
|
||||
|
||||
> **화면명**: 발주관리
|
||||
> **파일**: 발주관리.html
|
||||
> **분류**: 구매관리
|
||||
> **구현 가능**: ✅ 완전 (현재 V2 컴포넌트)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
자재/원자재 발주를 생성하고 관리하는 화면입니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 발주 목록 조회/검색
|
||||
- 발주 등록/수정/삭제
|
||||
- 발주서 인쇄
|
||||
- 입고 연계
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [기간] [공급업체] [발주번호] [품목명] [상태▼] [초기화][조회] │
|
||||
│ [사용자옵션][OCR][엑셀] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 📋 발주 목록 [신규등록] │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ │□|발주번호 |발주일 |공급업체 |발주금액 |상태 |담당자│ │
|
||||
│ │□|PO-2026..|2026-01-30|(주)원자재|5,000,000 |진행중|홍길동│ │
|
||||
│ │□|PO-2026..|2026-01-29|(주)부품사|3,200,000 |완료 |김철수│ │
|
||||
│ │□|PO-2026..|2026-01-28|(주)자재사|1,800,000 |진행중|이영희│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 발주 목록 | `v2-table-list` | ✅ 가능 |
|
||||
| 발주 등록 모달 | `v2-modal-form` (필요) | ⚠️ 대체 가능 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 테이블 정의
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'po_no', label: '발주번호', width: 120 },
|
||||
{ id: 'po_date', label: '발주일', width: 100 },
|
||||
{ id: 'supplier_name', label: '공급업체', width: 200 },
|
||||
{ id: 'total_amount', label: '발주금액', width: 120, align: 'right', format: 'currency' },
|
||||
{ id: 'delivery_date', label: '납기일', width: 100 },
|
||||
{ id: 'status', label: '상태', width: 80 },
|
||||
{ id: 'receive_status', label: '입고상태', width: 100 },
|
||||
{ id: 'manager', label: '담당자', width: 100 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 검색 조건
|
||||
|
||||
| 필드명 | 컴포넌트 | 설정 |
|
||||
|--------|----------|------|
|
||||
| 기간 | `v2-date` | dateRange: true |
|
||||
| 공급업체 | `v2-input` | placeholder: "공급업체" |
|
||||
| 발주번호 | `v2-input` | placeholder: "발주번호" |
|
||||
| 품목명 | `v2-input` | placeholder: "품목명" |
|
||||
| 상태 | `v2-select` | 작성중, 발주, 부분입고, 입고완료 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "PO_MAIN",
|
||||
"screen_name": "발주관리",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"position": { "x": 0, "y": 0, "w": 12, "h": 2 },
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "date", "id": "date_range", "placeholder": "발주기간", "dateRange": true },
|
||||
{ "type": "input", "id": "supplier_name", "placeholder": "공급업체" },
|
||||
{ "type": "input", "id": "po_no", "placeholder": "발주번호" },
|
||||
{ "type": "input", "id": "item_name", "placeholder": "품목명" },
|
||||
{ "type": "select", "id": "status", "placeholder": "상태" }
|
||||
],
|
||||
"buttons": [
|
||||
{ "label": "초기화", "action": "reset", "variant": "outline" },
|
||||
{ "label": "조회", "action": "search", "variant": "primary" }
|
||||
],
|
||||
"rightButtons": [
|
||||
{ "label": "사용자옵션", "action": "userOptions" },
|
||||
{ "label": "OCR입력", "action": "ocr" },
|
||||
{ "label": "엑셀다운로드", "action": "excelDownload" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-table-list",
|
||||
"position": { "x": 0, "y": 2, "w": 12, "h": 10 },
|
||||
"config": {
|
||||
"title": "발주 목록",
|
||||
"entityId": "purchase_order",
|
||||
"buttons": [
|
||||
{ "label": "신규등록", "action": "create", "variant": "primary" }
|
||||
],
|
||||
"columns": [
|
||||
{ "id": "po_no", "label": "발주번호", "width": 120 },
|
||||
{ "id": "po_date", "label": "발주일", "width": 100 },
|
||||
{ "id": "supplier_name", "label": "공급업체", "width": 200 },
|
||||
{ "id": "total_amount", "label": "발주금액", "width": 120, "align": "right" },
|
||||
{ "id": "delivery_date", "label": "납기일", "width": 100 },
|
||||
{ "id": "status", "label": "상태", "width": 80 },
|
||||
{ "id": "manager", "label": "담당자", "width": 100 }
|
||||
],
|
||||
"rowActions": [
|
||||
{ "label": "상세", "action": "view" },
|
||||
{ "label": "수정", "action": "edit" },
|
||||
{ "label": "삭제", "action": "delete" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 데이터베이스 테이블
|
||||
|
||||
### purchase_order (발주 헤더)
|
||||
```sql
|
||||
CREATE TABLE purchase_order (
|
||||
id SERIAL PRIMARY KEY,
|
||||
company_code VARCHAR(20) NOT NULL,
|
||||
po_no VARCHAR(50) NOT NULL,
|
||||
po_date DATE NOT NULL,
|
||||
supplier_code VARCHAR(50),
|
||||
supplier_name VARCHAR(200),
|
||||
total_amount NUMERIC(15,2),
|
||||
tax_amount NUMERIC(15,2),
|
||||
status VARCHAR(20) DEFAULT 'draft',
|
||||
delivery_date DATE,
|
||||
manager VARCHAR(100),
|
||||
remark TEXT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 구현 체크리스트
|
||||
|
||||
- [x] 검색 영역: v2-table-search-widget
|
||||
- [x] 발주 목록 테이블: v2-table-list
|
||||
- [x] 컬럼 정렬/필터
|
||||
- [ ] 발주 등록 모달
|
||||
- [ ] OCR 입력 기능 (별도)
|
||||
- [ ] 인쇄 기능
|
||||
|
||||
**현재 V2 컴포넌트로 핵심 기능 구현 가능**
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
# 설비정보 화면 구현 가이드
|
||||
|
||||
> **화면명**: 설비정보
|
||||
> **파일**: 설비정보.html
|
||||
> **분류**: 설비관리
|
||||
> **구현 가능**: ✅ 완전 (v2-card-display 활용)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
생산 설비의 기본정보 및 상태를 관리하는 화면입니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 설비 목록 조회 (카드 형태)
|
||||
- 설비 등록/수정/삭제
|
||||
- 설비 상세 정보 탭 관리
|
||||
- 설비 이미지 관리
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [설비코드] [설비명] [설비유형▼] [상태▼] [초기화][조회] │
|
||||
│ [사용자옵션][업로드][다운로드]│
|
||||
├───────────────────────┬─────────────────────────────────────────┤
|
||||
│ 🏭 설비 목록 │ [기본정보][보전이력][점검이력][가동현황] │
|
||||
│ ─────────────── │ ───────────────────────────────────── │
|
||||
│ [신규등록] │ 설비코드: EQ-001 │
|
||||
│ ┌──────────────────┐ │ 설비명: CNC 밀링머신 1호기 │
|
||||
│ │ [이미지] EQ-001 │ │ 설비유형: 가공설비 │
|
||||
│ │ CNC 밀링 [가동중] │ │ 상태: 가동중 │
|
||||
│ ├──────────────────┤ │ 제조사: 현대공작기계 │
|
||||
│ │ [이미지] EQ-002 │ ├─────────────────────────────────────────┤
|
||||
│ │ 선반 1호 [점검중] │ │ [보전이력 테이블] │
|
||||
│ ├──────────────────┤ │ │일자 |유형 |내용 |담당자│ │
|
||||
│ │ [이미지] EQ-003 │ │ │2026-01|정기 |오일 교환 |김철수│ │
|
||||
│ │ 프레스 [고장] │ │ │2026-01|수리 |베어링 교체 |이영희│ │
|
||||
│ └──────────────────┘ │ │
|
||||
└───────────────────────┴─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 설비 카드 목록 | `v2-card-display` | ✅ 가능 |
|
||||
| 분할 패널 | `v2-split-panel-layout` | ✅ 가능 |
|
||||
| 상세 탭 | `v2-tabs-widget` | ✅ 가능 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 설비 카드 구조
|
||||
|
||||
```typescript
|
||||
interface EquipmentCard {
|
||||
id: string;
|
||||
image: string; // 설비 이미지 URL
|
||||
code: string; // 설비코드
|
||||
name: string; // 설비명
|
||||
type: string; // 설비유형
|
||||
status: 'running' | 'idle' | 'maintenance' | 'broken';
|
||||
location: string;
|
||||
}
|
||||
|
||||
// 상태별 스타일
|
||||
statusStyles: {
|
||||
running: { bg: '#d1fae5', color: '#065f46', label: '가동중' },
|
||||
idle: { bg: '#e5e7eb', color: '#374151', label: '대기중' },
|
||||
maintenance: { bg: '#fef3c7', color: '#92400e', label: '점검중' },
|
||||
broken: { bg: '#fee2e2', color: '#991b1b', label: '고장' }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 상세 탭 구성
|
||||
|
||||
```typescript
|
||||
tabs: [
|
||||
{
|
||||
id: 'basic',
|
||||
label: '기본정보',
|
||||
fields: [
|
||||
{ id: 'eq_code', label: '설비코드' },
|
||||
{ id: 'eq_name', label: '설비명' },
|
||||
{ id: 'eq_type', label: '설비유형' },
|
||||
{ id: 'status', label: '상태' },
|
||||
{ id: 'manufacturer', label: '제조사' },
|
||||
{ id: 'model', label: '모델명' },
|
||||
{ id: 'serial_no', label: '시리얼번호' },
|
||||
{ id: 'install_date', label: '설치일' },
|
||||
{ id: 'location', label: '설치위치' },
|
||||
{ id: 'manager', label: '담당자' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'maintenance',
|
||||
label: '보전이력',
|
||||
type: 'table',
|
||||
entityId: 'equipment_maintenance',
|
||||
columns: [
|
||||
{ id: 'date', label: '일자' },
|
||||
{ id: 'type', label: '유형' },
|
||||
{ id: 'content', label: '내용' },
|
||||
{ id: 'worker', label: '담당자' },
|
||||
{ id: 'cost', label: '비용' }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'inspection',
|
||||
label: '점검이력',
|
||||
type: 'table',
|
||||
entityId: 'equipment_inspection'
|
||||
},
|
||||
{
|
||||
id: 'operation',
|
||||
label: '가동현황',
|
||||
type: 'chart' // 향후 확장
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 검색 조건
|
||||
|
||||
| 필드명 | 컴포넌트 | 옵션 |
|
||||
|--------|----------|------|
|
||||
| 설비코드 | `v2-input` | placeholder: "설비코드" |
|
||||
| 설비명 | `v2-input` | placeholder: "설비명" |
|
||||
| 설비유형 | `v2-select` | 가공설비, 조립설비, 검사설비 등 |
|
||||
| 상태 | `v2-select` | 가동중, 대기중, 점검중, 고장 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 현재 구현 가능 범위
|
||||
|
||||
### ✅ 가능
|
||||
- 검색 영역: `v2-table-search-widget`
|
||||
- 설비 카드 목록: `v2-card-display` (이미지+정보 조합 지원)
|
||||
- 분할 패널 레이아웃: `v2-split-panel-layout`
|
||||
- 상세 탭: `v2-tabs-widget`
|
||||
- 보전이력/점검이력 테이블: `v2-table-list`
|
||||
|
||||
### ⚠️ 부분 가능
|
||||
- 가동현황 차트: 별도 차트 컴포넌트 필요
|
||||
|
||||
---
|
||||
|
||||
## 8. 테이블 대체 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "EQUIPMENT_MAIN",
|
||||
"screen_name": "설비정보",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"position": { "x": 0, "y": 0, "w": 12, "h": 2 },
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "input", "id": "eq_code", "placeholder": "설비코드" },
|
||||
{ "type": "input", "id": "eq_name", "placeholder": "설비명" },
|
||||
{ "type": "select", "id": "eq_type", "placeholder": "설비유형" },
|
||||
{ "type": "select", "id": "status", "placeholder": "상태",
|
||||
"options": [
|
||||
{ "value": "running", "label": "가동중" },
|
||||
{ "value": "idle", "label": "대기중" },
|
||||
{ "value": "maintenance", "label": "점검중" },
|
||||
{ "value": "broken", "label": "고장" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-split-panel-layout",
|
||||
"position": { "x": 0, "y": 2, "w": 12, "h": 10 },
|
||||
"config": {
|
||||
"masterPanel": {
|
||||
"title": "설비 목록",
|
||||
"entityId": "equipment",
|
||||
"buttons": [
|
||||
{ "label": "신규등록", "action": "create", "variant": "primary" }
|
||||
],
|
||||
"columns": [
|
||||
{ "id": "eq_code", "label": "설비코드", "width": 100 },
|
||||
{ "id": "eq_name", "label": "설비명", "width": 200 },
|
||||
{ "id": "eq_type", "label": "설비유형", "width": 100 },
|
||||
{ "id": "status", "label": "상태", "width": 80 },
|
||||
{ "id": "location", "label": "설치위치", "width": 150 }
|
||||
]
|
||||
},
|
||||
"detailPanel": {
|
||||
"tabs": [
|
||||
{ "id": "basic", "label": "기본정보", "type": "form" },
|
||||
{ "id": "maintenance", "label": "보전이력", "type": "table", "entityId": "eq_maintenance" },
|
||||
{ "id": "inspection", "label": "점검이력", "type": "table", "entityId": "eq_inspection" },
|
||||
{ "id": "operation", "label": "가동현황", "type": "custom" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. v2-card-display 설정 예시
|
||||
|
||||
`v2-card-display`는 이미 존재하는 컴포넌트입니다.
|
||||
|
||||
```typescript
|
||||
// v2-card-display 설정
|
||||
cardDisplayConfig: {
|
||||
cardsPerRow: 3,
|
||||
cardSpacing: 16,
|
||||
cardStyle: {
|
||||
showTitle: true, // eq_name 표시
|
||||
showSubtitle: true, // eq_code 표시
|
||||
showDescription: true,
|
||||
showImage: true, // 설비 이미지 표시
|
||||
showActions: true,
|
||||
imagePosition: "top",
|
||||
imageSize: "medium",
|
||||
},
|
||||
columnMapping: {
|
||||
title: "eq_name",
|
||||
subtitle: "eq_code",
|
||||
image: "image_url",
|
||||
status: "status"
|
||||
},
|
||||
dataSource: "table"
|
||||
}
|
||||
```
|
||||
|
||||
**현재 V2 컴포넌트로 완전 구현 가능**
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
# 입출고관리 화면 구현 가이드
|
||||
|
||||
> **화면명**: 입출고관리
|
||||
> **파일**: 입출고관리.html
|
||||
> **분류**: 물류관리
|
||||
> **구현 가능**: ⚠️ 부분 (그룹화 테이블 필요)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
자재/제품의 입고 및 출고 내역을 통합 관리하는 화면입니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 입출고 내역 조회/검색
|
||||
- 그룹화 기능 (입출고구분, 창고, 카테고리별)
|
||||
- 엑셀 업로드/다운로드
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [입출고구분▼][카테고리▼][창고▼][품목코드][품목명][기간][초기화][검색]│
|
||||
│ [사용자옵션][업로드][다운로드]│
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 📋 입출고 내역 전체 150건 │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ Group by: [입출고구분▼] │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ │▼ 입고 (80) │
|
||||
│ │ │IN-001|구매입고|2026-01-30|본사창고|P-001|원자재A|100|KG │
|
||||
│ │ │IN-002|생산입고|2026-01-30|제1창고|P-002|제품A |50 |EA │
|
||||
│ │▼ 출고 (70) │
|
||||
│ │ │OUT-001|판매출고|2026-01-30|본사창고|P-003|제품B|30|EA │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 입출고 목록 (그룹화) | `v2-table-list` | ⚠️ 그룹화 미지원 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 테이블 정의
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'inout_type', label: '입출고구분', width: 100 },
|
||||
{ id: 'category', label: '카테고리', width: 120 },
|
||||
{ id: 'doc_no', label: '전표번호', width: 120 },
|
||||
{ id: 'process_date', label: '처리일자', width: 100 },
|
||||
{ id: 'warehouse', label: '창고', width: 120 },
|
||||
{ id: 'location', label: '위치', width: 100 },
|
||||
{ id: 'item_code', label: '품목코드', width: 120 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'quantity', label: '수량', width: 100, align: 'right' },
|
||||
{ id: 'unit', label: '단위', width: 60 },
|
||||
{ id: 'lot_no', label: '로트번호', width: 120 },
|
||||
{ id: 'customer', label: '거래처', width: 120 },
|
||||
{ id: 'manager', label: '담당자', width: 100 },
|
||||
{ id: 'remark', label: '비고', width: 200 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 검색 조건
|
||||
|
||||
| 필드명 | 컴포넌트 | 옵션 |
|
||||
|--------|----------|------|
|
||||
| 입출고구분 | `v2-select` | 입고, 출고 |
|
||||
| 카테고리 | `v2-select` | 구매입고, 생산입고, 반품입고, 판매출고, 생산출고 등 |
|
||||
| 창고 | `v2-select` | 본사창고, 제1창고, 제2창고 |
|
||||
| 품목코드 | `v2-input` | - |
|
||||
| 품목명 | `v2-input` | - |
|
||||
| 기간 | `v2-date` | dateRange: true |
|
||||
|
||||
---
|
||||
|
||||
## 6. 그룹화 기능 (v2-grouped-table 필요)
|
||||
|
||||
```typescript
|
||||
groupByOptions: [
|
||||
{ id: 'inout_type', label: '입출고구분' },
|
||||
{ id: 'category', label: '카테고리' },
|
||||
{ id: 'warehouse', label: '창고' },
|
||||
{ id: 'item_code', label: '품목코드' },
|
||||
{ id: 'process_date', label: '처리일자' },
|
||||
{ id: 'customer', label: '거래처' }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 현재 구현 가능 범위
|
||||
|
||||
### ✅ 가능
|
||||
- 검색 영역
|
||||
- 일반 테이블 목록
|
||||
|
||||
### ⚠️ 부분 가능
|
||||
- 그룹화 없이 필터로 대체
|
||||
|
||||
### ❌ 불가능
|
||||
- 동적 그룹화
|
||||
|
||||
---
|
||||
|
||||
## 8. 간소화 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "INOUT_MAIN",
|
||||
"screen_name": "입출고관리",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"position": { "x": 0, "y": 0, "w": 12, "h": 2 },
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "select", "id": "inout_type", "placeholder": "입출고구분",
|
||||
"options": [
|
||||
{ "value": "IN", "label": "입고" },
|
||||
{ "value": "OUT", "label": "출고" }
|
||||
]
|
||||
},
|
||||
{ "type": "select", "id": "category", "placeholder": "카테고리",
|
||||
"options": [
|
||||
{ "value": "purchase", "label": "구매입고" },
|
||||
{ "value": "production_in", "label": "생산입고" },
|
||||
{ "value": "return_in", "label": "반품입고" },
|
||||
{ "value": "sales", "label": "판매출고" },
|
||||
{ "value": "production_out", "label": "생산출고" }
|
||||
]
|
||||
},
|
||||
{ "type": "select", "id": "warehouse", "placeholder": "창고" },
|
||||
{ "type": "input", "id": "item_code", "placeholder": "품목코드" },
|
||||
{ "type": "input", "id": "item_name", "placeholder": "품목명" },
|
||||
{ "type": "date", "id": "date_range", "placeholder": "처리일자", "dateRange": true }
|
||||
],
|
||||
"buttons": [
|
||||
{ "label": "초기화", "action": "reset" },
|
||||
{ "label": "검색", "action": "search", "variant": "primary" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-table-list",
|
||||
"position": { "x": 0, "y": 2, "w": 12, "h": 10 },
|
||||
"config": {
|
||||
"title": "입출고 내역",
|
||||
"entityId": "inventory_transaction",
|
||||
"showTotalCount": true,
|
||||
"columns": [
|
||||
{ "id": "inout_type", "label": "입출고구분", "width": 100 },
|
||||
{ "id": "category", "label": "카테고리", "width": 120 },
|
||||
{ "id": "doc_no", "label": "전표번호", "width": 120 },
|
||||
{ "id": "process_date", "label": "처리일자", "width": 100 },
|
||||
{ "id": "warehouse", "label": "창고", "width": 120 },
|
||||
{ "id": "item_code", "label": "품목코드", "width": 120 },
|
||||
{ "id": "item_name", "label": "품목명", "width": 200 },
|
||||
{ "id": "quantity", "label": "수량", "width": 100, "align": "right" },
|
||||
{ "id": "unit", "label": "단위", "width": 60 }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**v2-grouped-table 개발 시 그룹화 기능 추가 가능**
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
# 검사정보관리 화면 구현 가이드
|
||||
|
||||
> **화면명**: 검사정보관리
|
||||
> **파일**: 검사정보관리.html
|
||||
> **분류**: 품질관리
|
||||
> **구현 가능**: ✅ 완전 (현재 V2 컴포넌트)
|
||||
|
||||
---
|
||||
|
||||
## 1. 화면 개요
|
||||
|
||||
품질 검사 결과를 등록하고 관리하는 화면입니다.
|
||||
|
||||
### 핵심 기능
|
||||
- 검사 유형별 탭 (수입검사, 공정검사, 출하검사)
|
||||
- 검사 결과 등록/수정
|
||||
- 불량 처리 연계
|
||||
- 검사 이력 관리
|
||||
|
||||
---
|
||||
|
||||
## 2. 화면 레이아웃
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ [기간] [품목] [거래처] [검사결과▼] [초기화][조회] [사용자옵션][엑셀]│
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ [🔍수입검사(25)][⚙️공정검사(18)][📦출하검사(12)] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 📋 수입검사 목록 [신규등록] │
|
||||
│ ───────────────────────────────────────────────────────────── │
|
||||
│ │□|검사번호 |검사일 |품목명 |검사수량|합격수량|불량수량|결과│
|
||||
│ │□|IQC-001 |2026-01-30|원자재A |100 |98 |2 |합격│
|
||||
│ │□|IQC-002 |2026-01-30|원자재B |200 |195 |5 |합격│
|
||||
│ │□|IQC-003 |2026-01-29|부품C |50 |30 |20 |불합격│
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. V2 컴포넌트 매핑
|
||||
|
||||
| HTML 영역 | V2 컴포넌트 | 상태 |
|
||||
|-----------|-------------|------|
|
||||
| 검색 섹션 | `v2-table-search-widget` | ✅ 가능 |
|
||||
| 검사유형 탭 | `v2-tabs-widget` | ✅ 가능 |
|
||||
| 검사 목록 | `v2-table-list` | ✅ 가능 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 탭 구성
|
||||
|
||||
```typescript
|
||||
tabs: [
|
||||
{ id: 'incoming', label: '수입검사', icon: '🔍', count: 25 },
|
||||
{ id: 'process', label: '공정검사', icon: '⚙️', count: 18 },
|
||||
{ id: 'shipping', label: '출하검사', icon: '📦', count: 12 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 테이블 정의
|
||||
|
||||
```typescript
|
||||
columns: [
|
||||
{ id: 'checkbox', type: 'checkbox', width: 50 },
|
||||
{ id: 'inspect_no', label: '검사번호', width: 120 },
|
||||
{ id: 'inspect_date', label: '검사일', width: 100 },
|
||||
{ id: 'item_code', label: '품목코드', width: 100 },
|
||||
{ id: 'item_name', label: '품목명', width: 200 },
|
||||
{ id: 'lot_no', label: '로트번호', width: 120 },
|
||||
{ id: 'inspect_qty', label: '검사수량', width: 100, align: 'right' },
|
||||
{ id: 'pass_qty', label: '합격수량', width: 100, align: 'right' },
|
||||
{ id: 'fail_qty', label: '불량수량', width: 100, align: 'right' },
|
||||
{ id: 'result', label: '결과', width: 80 },
|
||||
{ id: 'inspector', label: '검사자', width: 100 }
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 검색 조건
|
||||
|
||||
| 필드명 | 컴포넌트 | 설정 |
|
||||
|--------|----------|------|
|
||||
| 기간 | `v2-date` | dateRange: true |
|
||||
| 품목 | `v2-input` | placeholder: "품목" |
|
||||
| 거래처 | `v2-input` | placeholder: "거래처" |
|
||||
| 검사결과 | `v2-select` | 전체, 합격, 불합격, 조건부합격 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 구현 JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"screen_code": "INSPECTION_MAIN",
|
||||
"screen_name": "검사정보관리",
|
||||
"components": [
|
||||
{
|
||||
"type": "v2-table-search-widget",
|
||||
"position": { "x": 0, "y": 0, "w": 12, "h": 2 },
|
||||
"config": {
|
||||
"searchFields": [
|
||||
{ "type": "date", "id": "date_range", "placeholder": "검사기간", "dateRange": true },
|
||||
{ "type": "input", "id": "item_name", "placeholder": "품목" },
|
||||
{ "type": "input", "id": "supplier", "placeholder": "거래처" },
|
||||
{ "type": "select", "id": "result", "placeholder": "검사결과",
|
||||
"options": [
|
||||
{ "value": "pass", "label": "합격" },
|
||||
{ "value": "fail", "label": "불합격" },
|
||||
{ "value": "conditional", "label": "조건부합격" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"buttons": [
|
||||
{ "label": "초기화", "action": "reset" },
|
||||
{ "label": "조회", "action": "search", "variant": "primary" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "v2-tabs-widget",
|
||||
"position": { "x": 0, "y": 2, "w": 12, "h": 10 },
|
||||
"config": {
|
||||
"tabs": [
|
||||
{ "id": "incoming", "label": "수입검사" },
|
||||
{ "id": "process", "label": "공정검사" },
|
||||
{ "id": "shipping", "label": "출하검사" }
|
||||
],
|
||||
"tabContent": {
|
||||
"type": "v2-table-list",
|
||||
"config": {
|
||||
"entityId": "inspection",
|
||||
"filterByTab": true,
|
||||
"tabFilterField": "inspect_type",
|
||||
"buttons": [
|
||||
{ "label": "신규등록", "action": "create", "variant": "primary" }
|
||||
],
|
||||
"columns": [
|
||||
{ "id": "inspect_no", "label": "검사번호", "width": 120 },
|
||||
{ "id": "inspect_date", "label": "검사일", "width": 100 },
|
||||
{ "id": "item_name", "label": "품목명", "width": 200 },
|
||||
{ "id": "lot_no", "label": "로트번호", "width": 120 },
|
||||
{ "id": "inspect_qty", "label": "검사수량", "width": 100 },
|
||||
{ "id": "pass_qty", "label": "합격수량", "width": 100 },
|
||||
{ "id": "fail_qty", "label": "불량수량", "width": 100 },
|
||||
{ "id": "result", "label": "결과", "width": 80 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 구현 체크리스트
|
||||
|
||||
- [x] 검색 영역: v2-table-search-widget
|
||||
- [x] 검사유형 탭: v2-tabs-widget
|
||||
- [x] 검사 목록 테이블: v2-table-list
|
||||
- [ ] 검사 등록 모달
|
||||
- [ ] 불량 처리 연계
|
||||
|
||||
**현재 V2 컴포넌트로 핵심 기능 구현 가능**
|
||||
|
|
@ -2,56 +2,89 @@
|
|||
|
||||
V2 컴포넌트를 활용한 ERP 화면 구현 가이드입니다.
|
||||
|
||||
---
|
||||
|
||||
## 전체 화면 분석 요약 (2026-01-30)
|
||||
|
||||
### 컴포넌트 커버리지
|
||||
|
||||
| 구분 | 화면 수 | 비율 |
|
||||
|------|--------|------|
|
||||
| 현재 즉시 구현 가능 | 17개 | 65% |
|
||||
| v2-grouped-table 추가 시 | 22개 | 85% |
|
||||
| v2-tree-view 추가 시 | 24개 | 92% |
|
||||
| 별도 개발 필요 | 2개 | 8% |
|
||||
|
||||
### 신규 컴포넌트 개발 우선순위
|
||||
|
||||
| 순위 | 컴포넌트 | 재활용 화면 수 | ROI |
|
||||
|------|----------|--------------|-----|
|
||||
| 1 | v2-grouped-table | 5+ | 높음 |
|
||||
| 2 | v2-tree-view | 3 | 중간 |
|
||||
| 3 | v2-timeline-scheduler | 1~2 | 낮음 |
|
||||
|
||||
> **참고**: 화면 디자이너에서 폼 배치가 자체 규격으로 처리되므로 별도 모달/폼 컴포넌트 불필요.
|
||||
> `v2-card-display`는 이미 존재합니다.
|
||||
|
||||
> 상세 분석: [full-screen-analysis.md](./00_analysis/full-screen-analysis.md)
|
||||
|
||||
---
|
||||
|
||||
## 폴더 구조
|
||||
|
||||
```
|
||||
screen-implementation-guide/
|
||||
├── 00_analysis/ # 전체 분석
|
||||
│ └── full-screen-analysis.md # 화면 전체 분석 보고서
|
||||
│
|
||||
├── 01_master-data/ # 기준정보
|
||||
│ ├── item-info.md # 품목정보 ✅
|
||||
│ ├── bom.md # BOM관리 ⚠️
|
||||
│ ├── company-info.md # 회사정보
|
||||
│ ├── department.md # 부서관리
|
||||
│ ├── item-info.md # 품목정보
|
||||
│ └── options.md # 옵션설정
|
||||
│
|
||||
├── 02_sales/ # 영업관리
|
||||
│ ├── quotation.md # 견적관리
|
||||
│ ├── order.md # 수주관리
|
||||
│ ├── customer.md # 거래처관리
|
||||
│ ├── order.md # 수주관리 ✅
|
||||
│ ├── quote.md # 견적관리 ✅
|
||||
│ ├── customer.md # 거래처관리 ⚠️
|
||||
│ ├── sales-item.md # 판매품목정보
|
||||
│ └── options.md # 영업옵션설정
|
||||
│
|
||||
├── 03_production/ # 생산관리
|
||||
│ ├── production-plan.md # 생산계획
|
||||
│ ├── work-order.md # 작업지시
|
||||
│ ├── production-plan.md # 생산계획관리 ❌
|
||||
│ ├── work-order.md # 작업지시 ⚠️
|
||||
│ ├── production-result.md # 생산실적
|
||||
│ ├── process-info.md # 공정정보관리
|
||||
│ ├── bom.md # BOM관리
|
||||
│ └── options.md # 생산옵션설정
|
||||
│
|
||||
├── 04_purchase/ # 구매관리
|
||||
│ ├── purchase-order.md # 발주관리
|
||||
│ ├── purchase-order.md # 발주관리 ✅
|
||||
│ ├── purchase-item.md # 구매품목정보
|
||||
│ ├── supplier.md # 공급업체관리
|
||||
│ ├── receiving.md # 입고관리
|
||||
│ └── options.md # 구매옵션설정
|
||||
│
|
||||
├── 05_equipment/ # 설비관리
|
||||
│ ├── equipment-info.md # 설비정보
|
||||
│ ├── equipment-info.md # 설비정보 ✅
|
||||
│ └── options.md # 설비옵션설정
|
||||
│
|
||||
├── 06_logistics/ # 물류관리
|
||||
│ ├── inout.md # 입출고관리 ⚠️
|
||||
│ ├── logistics-info.md # 물류정보관리
|
||||
│ ├── inout.md # 입출고관리
|
||||
│ ├── inventory.md # 재고현황
|
||||
│ ├── warehouse.md # 창고정보관리
|
||||
│ ├── shipping.md # 출고관리
|
||||
│ └── options.md # 물류옵션설정
|
||||
│
|
||||
├── 07_quality/ # 품질관리
|
||||
│ ├── inspection-info.md # 검사정보관리
|
||||
│ ├── inspection.md # 검사정보관리 ✅
|
||||
│ ├── item-inspection.md # 품목검사정보
|
||||
│ └── options.md # 품질옵션설정
|
||||
│
|
||||
└── README.md
|
||||
|
||||
# 범례: ✅ 완전구현 | ⚠️ 부분구현 | ❌ 신규개발필요
|
||||
```
|
||||
|
||||
## 문서 작성 형식
|
||||
|
|
|
|||
|
|
@ -0,0 +1,572 @@
|
|||
# Screen Development Standard Guide (AI Agent Reference)
|
||||
|
||||
> **Purpose**: Ensure consistent screen development output regardless of who develops it
|
||||
> **Target**: AI Agents (Cursor, etc.), Developers
|
||||
> **Version**: 1.0.0
|
||||
|
||||
---
|
||||
|
||||
## CRITICAL RULES
|
||||
|
||||
1. **ONLY use V2 components** (components with `v2-` prefix)
|
||||
2. **SEPARATE UI and Logic**: UI in `screen_layouts_v2`, Logic in `dataflow_diagrams`
|
||||
3. **ALWAYS apply company_code filtering** (multi-tenancy)
|
||||
|
||||
---
|
||||
|
||||
## AVAILABLE V2 COMPONENTS (23 total)
|
||||
|
||||
### Input Components
|
||||
| ID | Name | Purpose |
|
||||
|----|------|---------|
|
||||
| `v2-input` | Input | text, number, password, email, tel, url, textarea |
|
||||
| `v2-select` | Select | dropdown, combobox, radio, checkbox |
|
||||
| `v2-date` | Date | date, time, datetime, daterange, month, year |
|
||||
|
||||
### Display Components
|
||||
| ID | Name | Purpose |
|
||||
|----|------|---------|
|
||||
| `v2-text-display` | Text Display | labels, titles |
|
||||
| `v2-card-display` | Card Display | table data as cards |
|
||||
| `v2-aggregation-widget` | Aggregation Widget | sum, avg, count, min, max |
|
||||
|
||||
### Table/Data Components
|
||||
| ID | Name | Purpose |
|
||||
|----|------|---------|
|
||||
| `v2-table-list` | Table List | data grid with CRUD |
|
||||
| `v2-table-search-widget` | Search Widget | table search/filter |
|
||||
| `v2-pivot-grid` | Pivot Grid | multi-dimensional analysis |
|
||||
|
||||
### Layout Components
|
||||
| ID | Name | Purpose |
|
||||
|----|------|---------|
|
||||
| `v2-split-panel-layout` | Split Panel | master-detail layout |
|
||||
| `v2-tabs-widget` | Tabs Widget | tab navigation |
|
||||
| `v2-section-card` | Section Card | titled grouping container |
|
||||
| `v2-section-paper` | Section Paper | background grouping |
|
||||
| `v2-divider-line` | Divider | area separator |
|
||||
| `v2-repeat-container` | Repeat Container | data-driven repeat |
|
||||
| `v2-repeater` | Repeater | repeat control |
|
||||
| `v2-repeat-screen-modal` | Repeat Screen Modal | modal repeat |
|
||||
|
||||
### Action/Special Components
|
||||
| ID | Name | Purpose |
|
||||
|----|------|---------|
|
||||
| `v2-button-primary` | Primary Button | save, delete, etc. |
|
||||
| `v2-numbering-rule` | Numbering Rule | auto code generation |
|
||||
| `v2-category-manager` | Category Manager | category management |
|
||||
| `v2-location-swap-selector` | Location Swap | location selection |
|
||||
| `v2-rack-structure` | Rack Structure | warehouse rack visualization |
|
||||
| `v2-media` | Media | image/video display |
|
||||
|
||||
---
|
||||
|
||||
## SCREEN PATTERNS (5 types)
|
||||
|
||||
### Pattern A: Basic Master Screen
|
||||
**When**: Single table CRUD
|
||||
**Components**:
|
||||
```
|
||||
v2-table-search-widget
|
||||
v2-table-list
|
||||
v2-button-primary
|
||||
```
|
||||
|
||||
### Pattern B: Master-Detail Screen
|
||||
**When**: Master selection → Detail display
|
||||
**Components**:
|
||||
```
|
||||
v2-split-panel-layout
|
||||
├─ left: v2-table-list (master)
|
||||
└─ right: v2-table-list (detail)
|
||||
```
|
||||
**Required Config**:
|
||||
```json
|
||||
{
|
||||
"leftPanel": { "tableName": "master_table" },
|
||||
"rightPanel": {
|
||||
"tableName": "detail_table",
|
||||
"relation": { "type": "detail", "foreignKey": "master_id" }
|
||||
},
|
||||
"splitRatio": 30
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern C: Master-Detail + Tabs
|
||||
**When**: Master selection → Multiple tabs
|
||||
**Components**:
|
||||
```
|
||||
v2-split-panel-layout
|
||||
├─ left: v2-table-list (master)
|
||||
└─ right: v2-tabs-widget
|
||||
```
|
||||
|
||||
### Pattern D: Card View
|
||||
**When**: Image + info card display
|
||||
**Components**:
|
||||
```
|
||||
v2-table-search-widget
|
||||
v2-card-display
|
||||
```
|
||||
**Required Config**:
|
||||
```json
|
||||
{
|
||||
"cardsPerRow": 3,
|
||||
"columnMapping": {
|
||||
"title": "name",
|
||||
"subtitle": "code",
|
||||
"image": "image_url"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern E: Pivot Analysis
|
||||
**When**: Multi-dimensional aggregation
|
||||
**Components**:
|
||||
```
|
||||
v2-pivot-grid
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DATABASE TABLES
|
||||
|
||||
### Screen Definition
|
||||
```sql
|
||||
-- screen_definitions: Screen basic info
|
||||
INSERT INTO screen_definitions (
|
||||
screen_name, screen_code, description, table_name, company_code
|
||||
) VALUES (...) RETURNING screen_id;
|
||||
|
||||
-- screen_layouts_v2: UI layout (JSON)
|
||||
INSERT INTO screen_layouts_v2 (
|
||||
screen_id, company_code, layout_data
|
||||
) VALUES (...);
|
||||
|
||||
-- screen_menu_assignments: Menu connection
|
||||
INSERT INTO screen_menu_assignments (
|
||||
screen_id, menu_objid, company_code
|
||||
) VALUES (...);
|
||||
```
|
||||
|
||||
### Control Management (Business Logic)
|
||||
```sql
|
||||
-- dataflow_diagrams: Business logic
|
||||
INSERT INTO dataflow_diagrams (
|
||||
diagram_name, company_code, control, plan
|
||||
) VALUES (...);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## UI SETTING vs BUSINESS LOGIC
|
||||
|
||||
### UI Setting (Screen Designer)
|
||||
| Item | Storage |
|
||||
|------|---------|
|
||||
| Component placement | screen_layouts_v2.layout_data |
|
||||
| Table name | layout_data.tableName |
|
||||
| Column visibility | layout_data.columns |
|
||||
| Search fields | layout_data.searchFields |
|
||||
| Basic save/delete | button config.action.type |
|
||||
|
||||
### Business Logic (Control Management)
|
||||
| Item | Storage |
|
||||
|------|---------|
|
||||
| Conditional execution | dataflow_diagrams.control |
|
||||
| Multi-table save | dataflow_diagrams.plan |
|
||||
| Before/after trigger | control.triggerType |
|
||||
| Field mapping | plan.mappings |
|
||||
|
||||
---
|
||||
|
||||
## BUSINESS LOGIC JSON STRUCTURE
|
||||
|
||||
### Control (Conditions)
|
||||
```json
|
||||
{
|
||||
"control": {
|
||||
"actionType": "update|insert|delete",
|
||||
"triggerType": "before|after",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "unique-id",
|
||||
"type": "condition",
|
||||
"field": "column_name",
|
||||
"operator": "=|!=|>|<|>=|<=|LIKE|IN|IS NULL",
|
||||
"value": "compare_value",
|
||||
"dataType": "string|number|date|boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Plan (Actions)
|
||||
```json
|
||||
{
|
||||
"plan": {
|
||||
"actions": [
|
||||
{
|
||||
"id": "action-id",
|
||||
"actionType": "update|insert|delete",
|
||||
"targetTable": "table_name",
|
||||
"fieldMappings": [
|
||||
{
|
||||
"sourceField": "source_column",
|
||||
"targetField": "target_column",
|
||||
"defaultValue": "static_value",
|
||||
"valueType": "field|static"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Special Values
|
||||
| Value | Meaning |
|
||||
|-------|---------|
|
||||
| `#NOW` | Current timestamp |
|
||||
| `#USER` | Current user ID |
|
||||
| `#COMPANY` | Current company code |
|
||||
|
||||
---
|
||||
|
||||
## DEVELOPMENT STEPS
|
||||
|
||||
### Step 1: Analyze Requirements
|
||||
```
|
||||
1. Which tables? (table names)
|
||||
2. Table relationships? (FK)
|
||||
3. Which pattern? (A/B/C/D/E)
|
||||
4. Which buttons?
|
||||
5. Business logic per button?
|
||||
```
|
||||
|
||||
### Step 2: INSERT screen_definitions
|
||||
```sql
|
||||
INSERT INTO screen_definitions (
|
||||
screen_name, screen_code, description, table_name, company_code, created_at
|
||||
) VALUES (
|
||||
'화면명', 'SCREEN_CODE', '설명', 'main_table', 'COMPANY_CODE', NOW()
|
||||
) RETURNING screen_id;
|
||||
```
|
||||
|
||||
### Step 3: INSERT screen_layouts_v2
|
||||
```sql
|
||||
INSERT INTO screen_layouts_v2 (
|
||||
screen_id, company_code, layout_data
|
||||
) VALUES (
|
||||
{screen_id}, 'COMPANY_CODE', '{layout_json}'::jsonb
|
||||
);
|
||||
```
|
||||
|
||||
### Step 4: INSERT dataflow_diagrams (if complex logic)
|
||||
```sql
|
||||
INSERT INTO dataflow_diagrams (
|
||||
diagram_name, company_code, control, plan
|
||||
) VALUES (
|
||||
'화면명_제어', 'COMPANY_CODE', '{control_json}'::jsonb, '{plan_json}'::jsonb
|
||||
) RETURNING diagram_id;
|
||||
```
|
||||
|
||||
### Step 5: Link button to dataflow
|
||||
In layout_data, set button config:
|
||||
```json
|
||||
{
|
||||
"id": "btn-action",
|
||||
"componentType": "v2-button-primary",
|
||||
"componentConfig": {
|
||||
"text": "확정",
|
||||
"enableDataflowControl": true,
|
||||
"dataflowDiagramId": {diagram_id}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: INSERT screen_menu_assignments
|
||||
```sql
|
||||
INSERT INTO screen_menu_assignments (
|
||||
screen_id, menu_objid, company_code
|
||||
) VALUES (
|
||||
{screen_id}, {menu_objid}, 'COMPANY_CODE'
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## EXAMPLE: Order Management
|
||||
|
||||
### Requirements
|
||||
```
|
||||
Screen: 수주관리 (Order Management)
|
||||
Pattern: B (Master-Detail)
|
||||
Tables:
|
||||
- Master: order_master
|
||||
- Detail: order_detail
|
||||
Buttons:
|
||||
- [저장]: Save to order_master
|
||||
- [확정]:
|
||||
- Condition: status = '대기'
|
||||
- Action: Update status to '확정'
|
||||
- Additional: Insert to order_history
|
||||
```
|
||||
|
||||
### layout_data JSON
|
||||
```json
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"id": "search-1",
|
||||
"componentType": "v2-table-search-widget",
|
||||
"position": {"x": 0, "y": 0},
|
||||
"size": {"width": 1920, "height": 80}
|
||||
},
|
||||
{
|
||||
"id": "split-1",
|
||||
"componentType": "v2-split-panel-layout",
|
||||
"position": {"x": 0, "y": 80},
|
||||
"size": {"width": 1920, "height": 800},
|
||||
"componentConfig": {
|
||||
"leftPanel": {"tableName": "order_master"},
|
||||
"rightPanel": {
|
||||
"tableName": "order_detail",
|
||||
"relation": {"type": "detail", "foreignKey": "order_id"}
|
||||
},
|
||||
"splitRatio": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "btn-save",
|
||||
"componentType": "v2-button-primary",
|
||||
"componentConfig": {
|
||||
"text": "저장",
|
||||
"action": {"type": "save"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "btn-confirm",
|
||||
"componentType": "v2-button-primary",
|
||||
"componentConfig": {
|
||||
"text": "확정",
|
||||
"enableDataflowControl": true,
|
||||
"dataflowDiagramId": 123
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### dataflow_diagrams JSON (for 확정 button)
|
||||
```json
|
||||
{
|
||||
"control": {
|
||||
"actionType": "update",
|
||||
"triggerType": "after",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "cond-1",
|
||||
"type": "condition",
|
||||
"field": "status",
|
||||
"operator": "=",
|
||||
"value": "대기",
|
||||
"dataType": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"plan": {
|
||||
"actions": [
|
||||
{
|
||||
"id": "action-1",
|
||||
"actionType": "update",
|
||||
"targetTable": "order_master",
|
||||
"fieldMappings": [
|
||||
{"targetField": "status", "defaultValue": "확정"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "action-2",
|
||||
"actionType": "insert",
|
||||
"targetTable": "order_history",
|
||||
"fieldMappings": [
|
||||
{"sourceField": "order_no", "targetField": "order_no"},
|
||||
{"sourceField": "customer_name", "targetField": "customer_name"},
|
||||
{"defaultValue": "#NOW", "targetField": "confirmed_at"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NOT SUPPORTED (Requires Custom Development)
|
||||
|
||||
| UI Type | Status | Alternative |
|
||||
|---------|--------|-------------|
|
||||
| Tree View | ❌ | Develop `v2-tree-view` |
|
||||
| Grouped Table | ❌ | Develop `v2-grouped-table` |
|
||||
| Gantt Chart | ❌ | Separate development |
|
||||
| Drag & Drop | ❌ | Use order column |
|
||||
|
||||
---
|
||||
|
||||
## CHECKLIST
|
||||
|
||||
### Screen Creation
|
||||
```
|
||||
□ screen_definitions INSERT completed
|
||||
□ screen_layouts_v2 INSERT completed
|
||||
□ screen_menu_assignments INSERT completed (if needed)
|
||||
□ company_code filtering applied
|
||||
□ All components have v2- prefix
|
||||
```
|
||||
|
||||
### Business Logic
|
||||
```
|
||||
□ Basic actions (save/delete) → Screen designer setting
|
||||
□ Conditional/Multi-table → dataflow_diagrams INSERT
|
||||
□ Button config has dataflowDiagramId
|
||||
□ control.conditions configured
|
||||
□ plan.actions or plan.mappings configured
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## BUSINESS LOGIC REQUEST FORMAT (MANDATORY)
|
||||
|
||||
> **WARNING**: No format = No processing. Write it properly, idiot.
|
||||
> Vague input = vague output. No input = no output.
|
||||
|
||||
### Request Template
|
||||
|
||||
```
|
||||
=== BUSINESS LOGIC REQUEST ===
|
||||
|
||||
【SCREEN INFO】
|
||||
- Screen Name:
|
||||
- Company Code:
|
||||
- Menu ID (if any):
|
||||
|
||||
【TABLE INFO】
|
||||
- Main Table:
|
||||
- Detail Table (if any):
|
||||
- FK Relation (if any):
|
||||
|
||||
【BUTTON LIST】
|
||||
Button 1:
|
||||
- Name:
|
||||
- Action Type: (save/delete/update/query/other)
|
||||
- Condition (if any):
|
||||
- Target Table:
|
||||
- Additional Actions (if any):
|
||||
|
||||
Button 2:
|
||||
- Name:
|
||||
- ...
|
||||
|
||||
【ADDITIONAL REQUIREMENTS】
|
||||
-
|
||||
```
|
||||
|
||||
### Valid Example
|
||||
|
||||
```
|
||||
=== BUSINESS LOGIC REQUEST ===
|
||||
|
||||
【SCREEN INFO】
|
||||
- Screen Name: 수주관리 (Order Management)
|
||||
- Company Code: ssalmeog
|
||||
- Menu ID: 55566
|
||||
|
||||
【TABLE INFO】
|
||||
- Main Table: order_master
|
||||
- Detail Table: order_detail
|
||||
- FK Relation: order_id
|
||||
|
||||
【BUTTON LIST】
|
||||
Button 1:
|
||||
- Name: 저장 (Save)
|
||||
- Action Type: save
|
||||
- Condition: none
|
||||
- Target Table: order_master, order_detail
|
||||
- Additional Actions: none
|
||||
|
||||
Button 2:
|
||||
- Name: 확정 (Confirm)
|
||||
- Action Type: update
|
||||
- Condition: status = '대기'
|
||||
- Target Table: order_master
|
||||
- Additional Actions:
|
||||
1. Change status to '확정'
|
||||
2. INSERT to order_history (order_no, customer_name, confirmed_at=NOW)
|
||||
|
||||
Button 3:
|
||||
- Name: 삭제 (Delete)
|
||||
- Action Type: delete
|
||||
- Condition: status != '확정'
|
||||
- Target Table: order_master, order_detail (cascade)
|
||||
- Additional Actions: none
|
||||
|
||||
【ADDITIONAL REQUIREMENTS】
|
||||
- Confirmed orders cannot be modified/deleted
|
||||
- Auto-numbering for order_no (ORDER-YYYYMMDD-0001)
|
||||
```
|
||||
|
||||
### Invalid Examples (DO NOT DO THIS)
|
||||
|
||||
```
|
||||
❌ "Make an order management screen"
|
||||
→ Which table? Buttons? Logic?
|
||||
|
||||
❌ "Save button should save"
|
||||
→ To which table? Conditions?
|
||||
|
||||
❌ "Handle inventory when confirmed"
|
||||
→ Which table? Increase? Decrease? By how much?
|
||||
|
||||
❌ "Similar to the previous screen"
|
||||
→ What previous screen?
|
||||
```
|
||||
|
||||
### Complex Logic Format
|
||||
|
||||
For multiple conditions or complex workflows:
|
||||
|
||||
```
|
||||
【COMPLEX BUTTON LOGIC】
|
||||
Button Name: 출고확정 (Shipment Confirm)
|
||||
|
||||
Execution Conditions:
|
||||
Cond1: status = '출고대기' AND
|
||||
Cond2: qty > 0 AND
|
||||
Cond3: warehouse_id IS NOT NULL
|
||||
|
||||
Execution Steps (in order):
|
||||
1. shipment_master.status → '출고완료'
|
||||
2. Decrease qty in inventory (WHERE item_code = current_row.item_code)
|
||||
3. INSERT to shipment_history:
|
||||
- shipment_no ← current_row.shipment_no
|
||||
- shipped_qty ← current_row.qty
|
||||
- shipped_at ← #NOW
|
||||
- shipped_by ← #USER
|
||||
|
||||
On Failure:
|
||||
- Insufficient stock: Show "재고가 부족합니다"
|
||||
- Condition not met: Show "출고대기 상태만 확정 가능합니다"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## REFERENCE PATHS
|
||||
|
||||
| Item | Path/Table |
|
||||
|------|------------|
|
||||
| Control Management Page | `/admin/systemMng/dataflow` |
|
||||
| Screen Definition Table | `screen_definitions` |
|
||||
| Layout Table | `screen_layouts_v2` |
|
||||
| Control Table | `dataflow_diagrams` |
|
||||
| Menu Assignment Table | `screen_menu_assignments` |
|
||||
|
|
@ -0,0 +1,706 @@
|
|||
# 화면 개발 표준 가이드
|
||||
|
||||
> **목적**: 어떤 개발자/AI가 화면을 개발하든 동일한 결과물이 나오도록 하는 표준 가이드
|
||||
> **대상**: 개발자, AI 에이전트 (Cursor 등)
|
||||
> **버전**: 1.0.0
|
||||
|
||||
---
|
||||
|
||||
## 1. 개요
|
||||
|
||||
이 문서는 WACE 솔루션에서 화면을 개발할 때 반드시 따라야 하는 표준입니다.
|
||||
비즈니스 로직을 어떻게 설명하든, 최종 결과물은 이 가이드대로 생성되어야 합니다.
|
||||
|
||||
### 핵심 원칙
|
||||
|
||||
1. **V2 컴포넌트만 사용**: `v2-` 접두사가 붙은 컴포넌트만 사용
|
||||
2. **UI와 로직 분리**: UI는 `screen_layouts_v2`, 비즈니스 로직은 `dataflow_diagrams`
|
||||
3. **멀티테넌시 필수**: 모든 쿼리에 `company_code` 필터링
|
||||
|
||||
---
|
||||
|
||||
## 2. 사용 가능한 V2 컴포넌트 목록 (23개)
|
||||
|
||||
### 입력 컴포넌트
|
||||
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-input` | 입력 | 텍스트, 숫자, 비밀번호, 이메일 등 |
|
||||
| `v2-select` | 선택 | 드롭다운, 콤보박스, 라디오, 체크박스 |
|
||||
| `v2-date` | 날짜 | 날짜, 시간, 날짜범위 |
|
||||
|
||||
### 표시 컴포넌트
|
||||
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-text-display` | 텍스트 표시 | 라벨, 제목 |
|
||||
| `v2-card-display` | 카드 디스플레이 | 테이블 데이터를 카드 형태로 표시 |
|
||||
| `v2-aggregation-widget` | 집계 위젯 | 합계, 평균, 개수 등 |
|
||||
|
||||
### 테이블/데이터 컴포넌트
|
||||
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-table-list` | 테이블 리스트 | 데이터 조회/편집 테이블 |
|
||||
| `v2-table-search-widget` | 검색 필터 | 테이블 검색/필터 |
|
||||
| `v2-pivot-grid` | 피벗 그리드 | 다차원 분석 |
|
||||
|
||||
### 레이아웃 컴포넌트
|
||||
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-split-panel-layout` | 분할 패널 | 마스터-디테일 좌우 분할 |
|
||||
| `v2-tabs-widget` | 탭 위젯 | 탭 전환 |
|
||||
| `v2-section-card` | 섹션 카드 | 제목+테두리 그룹화 |
|
||||
| `v2-section-paper` | 섹션 페이퍼 | 배경색 그룹화 |
|
||||
| `v2-divider-line` | 구분선 | 영역 구분 |
|
||||
| `v2-repeat-container` | 리피터 컨테이너 | 데이터 반복 렌더링 |
|
||||
| `v2-repeater` | 리피터 | 반복 컨트롤 |
|
||||
| `v2-repeat-screen-modal` | 반복 화면 모달 | 모달 반복 |
|
||||
|
||||
### 액션/특수 컴포넌트
|
||||
|
||||
| ID | 이름 | 용도 |
|
||||
|----|------|------|
|
||||
| `v2-button-primary` | 기본 버튼 | 저장, 삭제 등 액션 |
|
||||
| `v2-numbering-rule` | 채번규칙 | 자동 코드 생성 |
|
||||
| `v2-category-manager` | 카테고리 관리자 | 카테고리 관리 |
|
||||
| `v2-location-swap-selector` | 위치 교환 | 위치 선택/교환 |
|
||||
| `v2-rack-structure` | 랙 구조 | 창고 랙 시각화 |
|
||||
| `v2-media` | 미디어 | 이미지/동영상 표시 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 화면 패턴 (5가지)
|
||||
|
||||
### 패턴 A: 기본 마스터 화면
|
||||
|
||||
**사용 조건**: 단일 테이블 CRUD
|
||||
|
||||
**컴포넌트 구성**:
|
||||
```
|
||||
v2-table-search-widget (검색)
|
||||
v2-table-list (테이블)
|
||||
v2-button-primary (저장/삭제)
|
||||
```
|
||||
|
||||
**레이아웃**:
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ [검색필드들] [조회] [엑셀] │ ← v2-table-search-widget
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ 제목 [신규] [삭제] │
|
||||
│ ─────────────────────────────────────────────── │
|
||||
│ □ | 코드 | 이름 | 상태 | 등록일 | │ ← v2-table-list
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 패턴 B: 마스터-디테일 화면
|
||||
|
||||
**사용 조건**: 마스터 테이블 선택 → 디테일 테이블 표시
|
||||
|
||||
**컴포넌트 구성**:
|
||||
```
|
||||
v2-split-panel-layout (분할)
|
||||
├─ 좌측: v2-table-list (마스터)
|
||||
└─ 우측: v2-table-list (디테일)
|
||||
```
|
||||
|
||||
**레이아웃**:
|
||||
```
|
||||
┌──────────────────┬──────────────────────────────┐
|
||||
│ 마스터 리스트 │ 디테일 리스트 │
|
||||
│ ─────────────── │ │
|
||||
│ □ A001 항목1 │ [디테일 테이블] │
|
||||
│ □ A002 항목2 ← │ │
|
||||
└──────────────────┴──────────────────────────────┘
|
||||
v2-split-panel-layout
|
||||
```
|
||||
|
||||
**필수 설정**:
|
||||
```json
|
||||
{
|
||||
"leftPanel": {
|
||||
"tableName": "마스터_테이블명"
|
||||
},
|
||||
"rightPanel": {
|
||||
"tableName": "디테일_테이블명",
|
||||
"relation": {
|
||||
"type": "detail",
|
||||
"foreignKey": "master_id"
|
||||
}
|
||||
},
|
||||
"splitRatio": 30
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 패턴 C: 마스터-디테일 + 탭
|
||||
|
||||
**사용 조건**: 마스터 선택 → 여러 탭으로 상세 정보 표시
|
||||
|
||||
**컴포넌트 구성**:
|
||||
```
|
||||
v2-split-panel-layout (분할)
|
||||
├─ 좌측: v2-table-list (마스터)
|
||||
└─ 우측: v2-tabs-widget (탭)
|
||||
├─ 탭1: v2-table-list
|
||||
├─ 탭2: v2-table-list
|
||||
└─ 탭3: 폼 컴포넌트들
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 패턴 D: 카드 뷰
|
||||
|
||||
**사용 조건**: 이미지+정보 카드 형태 표시
|
||||
|
||||
**컴포넌트 구성**:
|
||||
```
|
||||
v2-table-search-widget (검색)
|
||||
v2-card-display (카드)
|
||||
```
|
||||
|
||||
**필수 설정**:
|
||||
```json
|
||||
{
|
||||
"cardsPerRow": 3,
|
||||
"columnMapping": {
|
||||
"title": "name",
|
||||
"subtitle": "code",
|
||||
"image": "image_url",
|
||||
"status": "status"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 패턴 E: 피벗 분석
|
||||
|
||||
**사용 조건**: 다차원 집계/분석
|
||||
|
||||
**컴포넌트 구성**:
|
||||
```
|
||||
v2-pivot-grid (피벗)
|
||||
```
|
||||
|
||||
**필수 설정**:
|
||||
```json
|
||||
{
|
||||
"fields": [
|
||||
{ "field": "region", "area": "row" },
|
||||
{ "field": "year", "area": "column" },
|
||||
{ "field": "amount", "area": "data", "summaryType": "sum" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 데이터베이스 구조
|
||||
|
||||
### 화면 정의 테이블
|
||||
|
||||
```sql
|
||||
-- screen_definitions: 화면 기본 정보
|
||||
INSERT INTO screen_definitions (
|
||||
screen_id,
|
||||
screen_name,
|
||||
screen_code,
|
||||
description,
|
||||
table_name,
|
||||
company_code
|
||||
) VALUES (...);
|
||||
|
||||
-- screen_layouts_v2: UI 레이아웃 (JSON)
|
||||
INSERT INTO screen_layouts_v2 (
|
||||
screen_id,
|
||||
company_code,
|
||||
layout_data -- JSON: 컴포넌트 배치 정보
|
||||
) VALUES (...);
|
||||
|
||||
-- screen_menu_assignments: 메뉴 연결
|
||||
INSERT INTO screen_menu_assignments (
|
||||
screen_id,
|
||||
menu_objid,
|
||||
company_code
|
||||
) VALUES (...);
|
||||
```
|
||||
|
||||
### 제어관리 테이블
|
||||
|
||||
```sql
|
||||
-- dataflow_diagrams: 비즈니스 로직
|
||||
INSERT INTO dataflow_diagrams (
|
||||
diagram_name,
|
||||
company_code,
|
||||
control, -- JSON: 조건 설정
|
||||
plan -- JSON: 실행 계획
|
||||
) VALUES (...);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. UI 설정 vs 비즈니스 로직 설정
|
||||
|
||||
### UI 설정 (화면 디자이너에서 처리)
|
||||
|
||||
| 항목 | 저장 위치 |
|
||||
|------|----------|
|
||||
| 컴포넌트 배치 | screen_layouts_v2.layout_data |
|
||||
| 테이블명 | layout_data 내 tableName |
|
||||
| 컬럼 표시/숨김 | layout_data 내 columns |
|
||||
| 검색 필드 | layout_data 내 searchFields |
|
||||
| 기본 저장/삭제 | 버튼 config.action.type |
|
||||
|
||||
### 비즈니스 로직 (제어관리에서 처리)
|
||||
|
||||
| 항목 | 저장 위치 |
|
||||
|------|----------|
|
||||
| 조건부 실행 | dataflow_diagrams.control |
|
||||
| 다중 테이블 저장 | dataflow_diagrams.plan |
|
||||
| 버튼 전/후 트리거 | dataflow_diagrams.control.triggerType |
|
||||
| 필드 매핑 | dataflow_diagrams.plan.mappings |
|
||||
|
||||
---
|
||||
|
||||
## 6. 비즈니스 로직 설정 표준 형식
|
||||
|
||||
### 기본 구조
|
||||
|
||||
```json
|
||||
{
|
||||
"control": {
|
||||
"actionType": "update",
|
||||
"triggerType": "after",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "조건ID",
|
||||
"type": "condition",
|
||||
"field": "status",
|
||||
"operator": "=",
|
||||
"value": "대기",
|
||||
"dataType": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"plan": {
|
||||
"mappings": [
|
||||
{
|
||||
"id": "매핑ID",
|
||||
"sourceField": "소스필드",
|
||||
"targetField": "타겟필드",
|
||||
"targetTable": "타겟테이블",
|
||||
"valueType": "field"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 조건 연산자
|
||||
|
||||
| 연산자 | 설명 |
|
||||
|--------|------|
|
||||
| `=` | 같음 |
|
||||
| `!=` | 다름 |
|
||||
| `>` | 큼 |
|
||||
| `<` | 작음 |
|
||||
| `>=` | 크거나 같음 |
|
||||
| `<=` | 작거나 같음 |
|
||||
| `LIKE` | 포함 |
|
||||
| `IN` | 목록에 포함 |
|
||||
| `IS NULL` | NULL 값 |
|
||||
|
||||
### 액션 타입
|
||||
|
||||
| 타입 | 설명 |
|
||||
|------|------|
|
||||
| `insert` | 새 데이터 삽입 |
|
||||
| `update` | 기존 데이터 수정 |
|
||||
| `delete` | 데이터 삭제 |
|
||||
|
||||
### 트리거 타입
|
||||
|
||||
| 타입 | 설명 |
|
||||
|------|------|
|
||||
| `before` | 버튼 클릭 전 실행 |
|
||||
| `after` | 버튼 클릭 후 실행 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 화면 개발 순서
|
||||
|
||||
### Step 1: 요구사항 분석
|
||||
|
||||
```
|
||||
1. 어떤 테이블을 사용하는가?
|
||||
2. 테이블 간 관계는? (FK)
|
||||
3. 어떤 패턴인가? (A/B/C/D/E)
|
||||
4. 어떤 버튼이 필요한가?
|
||||
5. 각 버튼의 비즈니스 로직은?
|
||||
```
|
||||
|
||||
### Step 2: screen_definitions INSERT
|
||||
|
||||
```sql
|
||||
INSERT INTO screen_definitions (
|
||||
screen_name,
|
||||
screen_code,
|
||||
description,
|
||||
table_name,
|
||||
company_code,
|
||||
created_at
|
||||
) VALUES (
|
||||
'화면명',
|
||||
'SCREEN_CODE',
|
||||
'화면 설명',
|
||||
'메인테이블명',
|
||||
'회사코드',
|
||||
NOW()
|
||||
) RETURNING screen_id;
|
||||
```
|
||||
|
||||
### Step 3: screen_layouts_v2 INSERT
|
||||
|
||||
```sql
|
||||
INSERT INTO screen_layouts_v2 (
|
||||
screen_id,
|
||||
company_code,
|
||||
layout_data
|
||||
) VALUES (
|
||||
위에서_받은_screen_id,
|
||||
'회사코드',
|
||||
'{"components": [...], "layout": {...}}'::jsonb
|
||||
);
|
||||
```
|
||||
|
||||
### Step 4: dataflow_diagrams INSERT (비즈니스 로직 있는 경우)
|
||||
|
||||
```sql
|
||||
INSERT INTO dataflow_diagrams (
|
||||
diagram_name,
|
||||
company_code,
|
||||
control,
|
||||
plan
|
||||
) VALUES (
|
||||
'화면명_제어',
|
||||
'회사코드',
|
||||
'{"조건설정"}'::jsonb,
|
||||
'{"실행계획"}'::jsonb
|
||||
);
|
||||
```
|
||||
|
||||
### Step 5: screen_menu_assignments INSERT
|
||||
|
||||
```sql
|
||||
INSERT INTO screen_menu_assignments (
|
||||
screen_id,
|
||||
menu_objid,
|
||||
company_code
|
||||
) VALUES (
|
||||
screen_id,
|
||||
메뉴ID,
|
||||
'회사코드'
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 예시: 수주관리 화면
|
||||
|
||||
### 요구사항
|
||||
|
||||
```
|
||||
화면명: 수주관리
|
||||
패턴: B (마스터-디테일)
|
||||
테이블:
|
||||
- 마스터: order_master
|
||||
- 디테일: order_detail
|
||||
버튼:
|
||||
- [저장]: order_master에 저장
|
||||
- [확정]:
|
||||
- 조건: status = '대기'
|
||||
- 동작: status를 '확정'으로 변경
|
||||
- 추가: order_history에 이력 저장
|
||||
```
|
||||
|
||||
### screen_definitions
|
||||
|
||||
```sql
|
||||
INSERT INTO screen_definitions (
|
||||
screen_name, screen_code, description, table_name, company_code
|
||||
) VALUES (
|
||||
'수주관리', 'ORDER_MNG', '수주를 관리하는 화면', 'order_master', 'COMPANY_A'
|
||||
);
|
||||
```
|
||||
|
||||
### screen_layouts_v2 (layout_data)
|
||||
|
||||
```json
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"id": "search-1",
|
||||
"componentType": "v2-table-search-widget",
|
||||
"position": {"x": 0, "y": 0},
|
||||
"size": {"width": 1920, "height": 80}
|
||||
},
|
||||
{
|
||||
"id": "split-1",
|
||||
"componentType": "v2-split-panel-layout",
|
||||
"position": {"x": 0, "y": 80},
|
||||
"size": {"width": 1920, "height": 800},
|
||||
"componentConfig": {
|
||||
"leftPanel": {
|
||||
"tableName": "order_master"
|
||||
},
|
||||
"rightPanel": {
|
||||
"tableName": "order_detail",
|
||||
"relation": {
|
||||
"type": "detail",
|
||||
"foreignKey": "order_id"
|
||||
}
|
||||
},
|
||||
"splitRatio": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "btn-save",
|
||||
"componentType": "v2-button-primary",
|
||||
"componentConfig": {
|
||||
"text": "저장",
|
||||
"action": {"type": "save"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "btn-confirm",
|
||||
"componentType": "v2-button-primary",
|
||||
"componentConfig": {
|
||||
"text": "확정",
|
||||
"enableDataflowControl": true,
|
||||
"dataflowDiagramId": 123
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### dataflow_diagrams (확정 버튼 로직)
|
||||
|
||||
```json
|
||||
{
|
||||
"control": {
|
||||
"actionType": "update",
|
||||
"triggerType": "after",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "cond-1",
|
||||
"type": "condition",
|
||||
"field": "status",
|
||||
"operator": "=",
|
||||
"value": "대기",
|
||||
"dataType": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"plan": {
|
||||
"actions": [
|
||||
{
|
||||
"id": "action-1",
|
||||
"actionType": "update",
|
||||
"targetTable": "order_master",
|
||||
"fieldMappings": [
|
||||
{"targetField": "status", "defaultValue": "확정"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "action-2",
|
||||
"actionType": "insert",
|
||||
"targetTable": "order_history",
|
||||
"fieldMappings": [
|
||||
{"sourceField": "order_no", "targetField": "order_no"},
|
||||
{"sourceField": "customer_name", "targetField": "customer_name"},
|
||||
{"defaultValue": "#NOW", "targetField": "confirmed_at"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 지원하지 않는 UI (별도 개발 필요)
|
||||
|
||||
| UI 유형 | 상태 | 대안 |
|
||||
|---------|------|------|
|
||||
| 트리 뷰 | ❌ 미지원 | 테이블로 대체 or `v2-tree-view` 개발 필요 |
|
||||
| 그룹화 테이블 | ❌ 미지원 | 일반 테이블로 대체 or `v2-grouped-table` 개발 필요 |
|
||||
| 간트 차트 | ❌ 미지원 | 별도 개발 필요 |
|
||||
| 드래그앤드롭 | ❌ 미지원 | 순서 컬럼으로 대체 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 체크리스트
|
||||
|
||||
### 화면 생성 시
|
||||
|
||||
```
|
||||
□ screen_definitions INSERT 완료
|
||||
□ screen_layouts_v2 INSERT 완료
|
||||
□ screen_menu_assignments INSERT 완료 (메뉴 연결 필요 시)
|
||||
□ company_code 필터링 적용
|
||||
□ 사용한 컴포넌트가 모두 v2- 접두사인지 확인
|
||||
```
|
||||
|
||||
### 비즈니스 로직 설정 시
|
||||
|
||||
```
|
||||
□ 기본 액션 (저장/삭제)만 → 화면 디자이너에서 설정
|
||||
□ 조건부/다중테이블 → dataflow_diagrams INSERT
|
||||
□ 버튼 config에 dataflowDiagramId 연결
|
||||
□ control.conditions 설정
|
||||
□ plan.actions 또는 plan.mappings 설정
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 비즈니스 로직 요청 양식 (필수)
|
||||
|
||||
> **경고**: 양식대로 안 쓰면 처리 안 함. 병신아 제대로 써.
|
||||
> 대충 쓰면 대충 만들어지고, 안 쓰면 안 만들어줌.
|
||||
|
||||
### 11.1 양식 템플릿
|
||||
|
||||
```
|
||||
=== 비즈니스 로직 요청서 ===
|
||||
|
||||
【화면 정보】
|
||||
- 화면명:
|
||||
- 회사코드:
|
||||
- 메뉴ID (있으면):
|
||||
|
||||
【테이블 정보】
|
||||
- 메인 테이블:
|
||||
- 디테일 테이블 (있으면):
|
||||
- 관계 FK (있으면):
|
||||
|
||||
【버튼 목록】
|
||||
버튼1:
|
||||
- 버튼명:
|
||||
- 동작 유형: (저장/삭제/수정/조회/기타)
|
||||
- 조건 (있으면):
|
||||
- 대상 테이블:
|
||||
- 추가 동작 (있으면):
|
||||
|
||||
버튼2:
|
||||
- 버튼명:
|
||||
- ...
|
||||
|
||||
【추가 요구사항】
|
||||
-
|
||||
```
|
||||
|
||||
### 11.2 작성 예시 (올바른 예시)
|
||||
|
||||
```
|
||||
=== 비즈니스 로직 요청서 ===
|
||||
|
||||
【화면 정보】
|
||||
- 화면명: 수주관리
|
||||
- 회사코드: ssalmeog
|
||||
- 메뉴ID: 55566
|
||||
|
||||
【테이블 정보】
|
||||
- 메인 테이블: order_master
|
||||
- 디테일 테이블: order_detail
|
||||
- 관계 FK: order_id
|
||||
|
||||
【버튼 목록】
|
||||
버튼1:
|
||||
- 버튼명: 저장
|
||||
- 동작 유형: 저장
|
||||
- 조건: 없음
|
||||
- 대상 테이블: order_master, order_detail
|
||||
- 추가 동작: 없음
|
||||
|
||||
버튼2:
|
||||
- 버튼명: 확정
|
||||
- 동작 유형: 수정
|
||||
- 조건: status = '대기'
|
||||
- 대상 테이블: order_master
|
||||
- 추가 동작:
|
||||
1. status를 '확정'으로 변경
|
||||
2. order_history에 이력 INSERT (order_no, customer_name, confirmed_at=현재시간)
|
||||
|
||||
버튼3:
|
||||
- 버튼명: 삭제
|
||||
- 동작 유형: 삭제
|
||||
- 조건: status != '확정'
|
||||
- 대상 테이블: order_master, order_detail (cascade)
|
||||
- 추가 동작: 없음
|
||||
|
||||
【추가 요구사항】
|
||||
- 확정된 수주는 수정/삭제 불가
|
||||
- 수주번호 자동채번 (ORDER-YYYYMMDD-0001)
|
||||
```
|
||||
|
||||
### 11.3 잘못된 예시 (이렇게 쓰면 안 됨)
|
||||
|
||||
```
|
||||
❌ "수주관리 화면 만들어줘"
|
||||
→ 테이블이 뭔데? 버튼은? 로직은?
|
||||
|
||||
❌ "저장 버튼 누르면 저장해줘"
|
||||
→ 어떤 테이블에? 조건은?
|
||||
|
||||
❌ "확정하면 재고 처리해줘"
|
||||
→ 어떤 테이블? 증가? 감소? 얼마나?
|
||||
|
||||
❌ "이전 화면이랑 비슷하게"
|
||||
→ 이전 화면이 뭔데?
|
||||
```
|
||||
|
||||
### 11.4 복잡한 로직 추가 양식
|
||||
|
||||
조건이 여러 개이거나 복잡한 경우:
|
||||
|
||||
```
|
||||
【복잡한 버튼 로직】
|
||||
버튼명: 출고확정
|
||||
|
||||
실행 조건:
|
||||
조건1: status = '출고대기' AND
|
||||
조건2: qty > 0 AND
|
||||
조건3: warehouse_id IS NOT NULL
|
||||
|
||||
실행 동작 (순서대로):
|
||||
1. shipment_master.status → '출고완료'
|
||||
2. inventory에서 qty만큼 감소 (WHERE item_code = 현재행.item_code)
|
||||
3. shipment_history에 INSERT:
|
||||
- shipment_no ← 현재행.shipment_no
|
||||
- shipped_qty ← 현재행.qty
|
||||
- shipped_at ← 현재시간
|
||||
- shipped_by ← 현재사용자
|
||||
|
||||
실패 시:
|
||||
- 재고 부족: "재고가 부족합니다" 메시지
|
||||
- 조건 불충족: "출고대기 상태만 확정 가능합니다" 메시지
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 참고 경로
|
||||
|
||||
| 항목 | 경로/테이블 |
|
||||
|------|------------|
|
||||
| 제어관리 페이지 | `/admin/systemMng/dataflow` |
|
||||
| 화면 정의 테이블 | `screen_definitions` |
|
||||
| 레이아웃 테이블 | `screen_layouts_v2` |
|
||||
| 제어관리 테이블 | `dataflow_diagrams` |
|
||||
| 메뉴 연결 테이블 | `screen_menu_assignments` |
|
||||
|
|
@ -733,7 +733,12 @@ function TableColumnAccordion({
|
|||
if (allTables.length === 0) {
|
||||
const tablesResult = await tableManagementApi.getTableList();
|
||||
if (tablesResult.success && tablesResult.data) {
|
||||
setAllTables(tablesResult.data);
|
||||
// 중복 테이블 제거 (tableName 기준)
|
||||
const uniqueTables = tablesResult.data.filter(
|
||||
(table, index, self) =>
|
||||
index === self.findIndex((t) => t.tableName === table.tableName)
|
||||
);
|
||||
setAllTables(uniqueTables);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
|
@ -1348,9 +1353,9 @@ function JoinSettingEditor({
|
|||
<CommandList>
|
||||
<CommandEmpty className="text-xs py-2">테이블을 찾을 수 없습니다.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{allTables.map(t => (
|
||||
{allTables.map((t, idx) => (
|
||||
<CommandItem
|
||||
key={t.tableName}
|
||||
key={`${t.tableName}-${idx}`}
|
||||
value={t.displayName || t.tableName}
|
||||
onSelect={() => {
|
||||
setEditingJoin({ ...editingJoin, referenceTable: t.tableName, referenceColumn: "", displayColumn: "" });
|
||||
|
|
|
|||
Loading…
Reference in New Issue