Files
distribution_erp/BOM_SEQ_DRAG_DROP.md
T
chpark 3e135041ac Initial commit: ILSHIN PLM 프로젝트 소스 코드
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 17:49:38 +09:00

4.9 KiB

BOM 구조 관리 SEQ 드래그앤드롭 기능

개요

BOM(Bill of Materials) 구조 관리 화면에서 PART 항목들을 드래그앤드롭으로 순서를 변경할 수 있는 기능입니다.

핵심 기능

  • LEVEL별 SEQ 관리: 각 LEVEL(PARENT_OBJID) 내에서 SEQ를 1, 2, 3... 순차적으로 관리
  • 드래그앤드롭: jQuery UI Sortable을 이용한 직관적인 순서 변경
  • 자동 저장: 드래그 완료 시 자동으로 DB에 저장 및 페이지 새로고침
  • 엑셀 업로드: 업로드 순서대로 SEQ 자동 부여

구현 내용

1. 데이터베이스 (partMng.xml)

-- 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 적용

$("#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 저장 및 새로고침

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별로 재정렬:

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로 계층 구조 조회
  • 트랜잭션 처리로 데이터 무결성 보장