# BOM 구조 관리 SEQ 드래그앤드롭 기능 ## 개요 BOM(Bill of Materials) 구조 관리 화면에서 PART 항목들을 드래그앤드롭으로 순서를 변경할 수 있는 기능입니다. ## 핵심 기능 - **LEVEL별 SEQ 관리**: 각 LEVEL(PARENT_OBJID) 내에서 SEQ를 1, 2, 3... 순차적으로 관리 - **드래그앤드롭**: jQuery UI Sortable을 이용한 직관적인 순서 변경 - **자동 저장**: 드래그 완료 시 자동으로 DB에 저장 및 페이지 새로고침 - **엑셀 업로드**: 업로드 순서대로 SEQ 자동 부여 ## 구현 내용 ### 1. 데이터베이스 (partMng.xml) ```sql -- PART 추가 시 자동 SEQ 부여 (LEVEL별 MAX + 1) SEQ = COALESCE( (SELECT MAX(seq) + 1 FROM BOM_PART_QTY WHERE bom_report_objid = #{BOM_REPORT_OBJID} AND COALESCE(parent_objid, '') = COALESCE(#{PARENT_OBJID}, '')), 1 ) -- 엑셀 업로드 시 순서대로 SEQ 부여 SEQ = ROW_NUMBER() OVER ( PARTITION BY BOM_REPORT_OBJID, PARENT_OBJID ORDER BY T.seq ASC ) -- 드래그앤드롭 후 SEQ 일괄 업데이트 UPDATE BOM_PART_QTY SET seq = CASE child_objid WHEN #{item.CHILD_OBJID} THEN #{item.SEQ}::numeric ... END WHERE child_objid IN (...) ``` ### 2. 백엔드 (Java/Spring) **PartMngService.java** - `structureDragDropSeqSave()`: JSON 파싱 및 SEQ 일괄 업데이트 - Gson을 이용한 JSON → List 변환 - 트랜잭션 처리 (commit/rollback) **PartMngController.java** - `POST /partMng/structureDragDropSeqSave.do`: SEQ 저장 API ### 3. 프론트엔드 (structurePopupLeft.jsp) **jQuery UI Sortable 적용** ```javascript $("#structurePopupTable2").sortable({ items: "tr.sortable-row", axis: "y", tolerance: "pointer", start: function(event, ui) { // 드래그 시작: 같은 그룹만 허용 var dragGroupKey = ui.item.attr("data-group-key"); ui.item.data("dragGroupKey", dragGroupKey); }, stop: function(event, ui) { // 드래그 종료: 위치 검증 및 저장 var dragGroupKey = ui.item.data("dragGroupKey"); var $prev = ui.item.prev("tr.sortable-row"); var $next = ui.item.next("tr.sortable-row"); // 같은 LEVEL 내에서만 이동 가능 if (isValidPosition) { saveDragDropSeq(dragGroupKey); } else { $("#structurePopupTable2").sortable("cancel"); } } }); ``` **SEQ 저장 및 새로고침** ```javascript function saveDragDropSeq(groupKey) { // 같은 그룹의 모든 항목 SEQ 수집 var seqList = []; $("#structurePopupTable2 tr.sortable-row").each(function() { if ($(this).attr("data-group-key") === groupKey) { seqList.push({ CHILD_OBJID: childObjid, SEQ: seqList.length + 1 }); } }); // AJAX로 저장 $.ajax({ url: "/partMng/structureDragDropSeqSave.do", data: { seqList: JSON.stringify(seqList) }, success: function(data) { if (data.result) { location.reload(); // 자동 새로고침 } } }); } ``` ## 주요 특징 ### 1. LEVEL별 독립적인 SEQ 관리 - LEVEL 1: SEQ = 1, 2, 3, 4... - LEVEL 2: SEQ = 1, 2, 3, 4... - LEVEL 3: SEQ = 1, 2, 3, 4... ### 2. 드래그 제약 조건 - **같은 LEVEL 내에서만** 순서 변경 가능 - 다른 LEVEL로 이동 시도 시 자동 취소 - 시각적 피드백 (disabled 클래스) ### 3. 자동 저장 및 반영 - 드래그 완료 즉시 DB 저장 - 성공 메시지 표시 (0.8초) - 자동 페이지 새로고침으로 변경 사항 즉시 반영 ## 기존 데이터 마이그레이션 **파일**: `db/migration_seq_reorder.sql` 전역 시퀀스로 부여된 기존 SEQ를 LEVEL별로 재정렬: ```bash psql -U postgres -d ilshin -f db/migration_seq_reorder.sql ``` ## 수정된 파일 목록 1. `src/com/pms/mapper/partMng.xml` - SQL 쿼리 수정 2. `src/com/pms/service/PartMngService.java` - 비즈니스 로직 3. `src/com/pms/controller/PartMngController.java` - API 엔드포인트 4. `WebContent/WEB-INF/view/partMng/structurePopupLeft.jsp` - UI 구현 5. `db/migration_seq_reorder.sql` - 마이그레이션 스크립트 ## 사용 방법 1. BOM 구조 관리 화면 접속 2. 같은 LEVEL의 PART 항목을 드래그 3. 원하는 위치에 드롭 4. 자동 저장 및 페이지 새로고침 5. 변경된 순서 확인 ## 트러블슈팅 ### 드래그가 안 될 때 - jQuery UI 라이브러리 로드 확인 - 브라우저 콘솔에서 에러 확인 - `data-group-key` 속성 확인 ### 저장이 안 될 때 - 서버 콘솔에서 로그 확인 - JSON 파싱 오류 확인 - DB 트랜잭션 상태 확인 ### 순서가 이상할 때 - 마이그레이션 스크립트 실행 확인 - SEQ 중복 여부 확인 - LEVEL별 SEQ 범위 확인 ## 참고 사항 - jQuery UI Sortable 1.12.1 사용 - Gson 2.3.1로 JSON 파싱 - PostgreSQL Recursive CTE로 계층 구조 조회 - 트랜잭션 처리로 데이터 무결성 보장