도면업로드 품번 디비에서 매칭
This commit is contained in:
@@ -336,19 +336,6 @@ String connector = person.getUserId();
|
||||
return;
|
||||
}
|
||||
|
||||
// 선택된 파트 확인 (필수 아님 - 전체 파트 대상)
|
||||
var selectedParts = _tabulGrid.getSelectedData();
|
||||
if(!selectedParts || selectedParts.length === 0) {
|
||||
// 선택 없으면 전체 파트 대상으로 진행
|
||||
var confirmMsg = '파트를 선택하지 않았습니다.\n';
|
||||
confirmMsg += '전체 파트를 대상으로 파일명과 일치하는 품번에 업로드됩니다.\n';
|
||||
confirmMsg += '계속하시겠습니까?';
|
||||
|
||||
if(!confirm(confirmMsg)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 파일 분류 및 처리
|
||||
var filesByType = {
|
||||
'3D': [], // stp 파일
|
||||
@@ -406,28 +393,9 @@ String connector = person.getUserId();
|
||||
|
||||
// 실제 업로드 처리
|
||||
function fn_processDrawingUpload(filesByType) {
|
||||
// 현재 그리드에 표시된 파트 데이터 가져오기
|
||||
var gridData = _tabulGrid.getData();
|
||||
if(!gridData || gridData.length === 0) {
|
||||
Swal.fire('페이지에 표시된 파트가 없습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 품번 목록 생성 (현재 화면에 보이는 파트만)
|
||||
var partNoList = [];
|
||||
for(var i = 0; i < gridData.length; i++) {
|
||||
var partNo = gridData[i].PART_NO;
|
||||
if(partNo) {
|
||||
partNoList.push(partNo);
|
||||
}
|
||||
}
|
||||
|
||||
// FormData 생성
|
||||
var formData = new FormData();
|
||||
|
||||
// 현재 화면의 품번 목록 전송
|
||||
formData.append('partNoList', JSON.stringify(partNoList));
|
||||
|
||||
// 모든 파일을 files 이름으로 추가
|
||||
var allFiles = filesByType['3D'].concat(filesByType['2D']).concat(filesByType['PDF']);
|
||||
for(var i = 0; i < allFiles.length; i++) {
|
||||
|
||||
@@ -2666,26 +2666,16 @@ public class PartMngController {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 품번 추출 (맨 마지막 확장자만 제거 후 하이픈 기준 추출)
|
||||
String extractedPartNo = extractPartNoFromFileName(originalFileName);
|
||||
|
||||
// 품번과 정확히 일치하는 경우만 매칭
|
||||
String matchedPartNo = null;
|
||||
System.out.println("품번 매칭 시작 - 추출된 품번: " + extractedPartNo);
|
||||
|
||||
if(extractedPartNo != null && !extractedPartNo.isEmpty()) {
|
||||
// 정확한 매칭 (추출된 품번과 DB 품번이 정확히 일치)
|
||||
if(partNoMap.containsKey(extractedPartNo)) {
|
||||
matchedPartNo = extractedPartNo;
|
||||
System.out.println(" ✓ 품번 정확 매칭 성공: " + matchedPartNo);
|
||||
}
|
||||
}
|
||||
// 파일명에서 확장자 제거 후 DB 품번과 매칭
|
||||
String fileNameWithoutExt = removeFileExtensions(originalFileName);
|
||||
String matchedPartNo = findMatchingPartNo(fileNameWithoutExt, partNoMap.keySet());
|
||||
|
||||
if(matchedPartNo == null) {
|
||||
System.out.println(" ✗ 품번 매칭 실패 - 파일명: " + originalFileName + ", 추출된 품번: " + extractedPartNo);
|
||||
System.out.println(" ✗ 품번 매칭 실패 - 파일명: " + originalFileName + ", 확장자 제거: " + fileNameWithoutExt);
|
||||
notFoundCount++;
|
||||
continue;
|
||||
}
|
||||
System.out.println(" ✓ 품번 매칭 성공: " + matchedPartNo + " (파일: " + originalFileName + ")");
|
||||
|
||||
// 해당 파트에 파일 정보 저장
|
||||
Map partInfo = partNoMap.get(matchedPartNo);
|
||||
@@ -2766,34 +2756,9 @@ public class PartMngController {
|
||||
multi = new MultipartRequest(request, storagePath, maxSize, "UTF-8", frc);
|
||||
java.util.List fileList = frc.getFileList();
|
||||
|
||||
// 화면에서 전달된 품번 목록 가져오기
|
||||
String partNoListJson = multi.getParameter("partNoList");
|
||||
if(partNoListJson == null || partNoListJson.isEmpty()) {
|
||||
resultMap.put("result", "fail");
|
||||
resultMap.put("message", "품번 목록이 전달되지 않았습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// JSON 파싱 (Gson 사용)
|
||||
Gson gson = new Gson();
|
||||
Type listType = new TypeToken<ArrayList<String>>(){}.getType();
|
||||
java.util.List<String> partNoList = gson.fromJson(partNoListJson, listType);
|
||||
|
||||
if(partNoList.isEmpty()) {
|
||||
resultMap.put("result", "fail");
|
||||
resultMap.put("message", "페이지에 표시된 파트가 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
System.out.println("========== 화면에서 전달된 품번 목록 ==========");
|
||||
System.out.println("품번 개수: " + partNoList.size());
|
||||
System.out.println("품번 목록: " + partNoList);
|
||||
System.out.println("==========================================");
|
||||
|
||||
// 전달된 품번 목록에 해당하는 파트만 조회
|
||||
// 전체 파트 조회 (IS_LAST='1')
|
||||
Map<String, Object> partParam = new HashMap<>();
|
||||
partParam.put("IS_LAST", "1");
|
||||
partParam.put("PART_NO_LIST", partNoList);
|
||||
ArrayList<Map> partList = commonService.selectList("partMng.partMngListByPartNos", request, partParam);
|
||||
|
||||
if(partList == null || partList.isEmpty()) {
|
||||
@@ -2802,7 +2767,7 @@ public class PartMngController {
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 품번 기준 파트 맵 생성 (화면에 표시된 파트만)
|
||||
// 품번 기준 파트 맵 생성
|
||||
Map<String, Map> partNoMap = new HashMap<>();
|
||||
for(Map part : partList) {
|
||||
String partNo = CommonUtils.checkNull((String)part.get("PART_NO"));
|
||||
@@ -2811,7 +2776,9 @@ public class PartMngController {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("========== 전체 파트 품번 매칭 대상 ==========");
|
||||
System.out.println("매칭 가능한 품번 개수: " + partNoMap.size());
|
||||
System.out.println("==========================================");
|
||||
|
||||
int successCount = 0;
|
||||
int failCount = 0;
|
||||
@@ -2863,31 +2830,20 @@ public class PartMngController {
|
||||
docType = "2D_PDF_CAD";
|
||||
docTypeName = "2D(PDF) CAD 첨부파일";
|
||||
} else {
|
||||
// 지원하지 않는 확장자는 스킵
|
||||
System.out.println("지원하지 않는 확장자: " + fileExt + ", 파일명: " + originalFileName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 품번 추출 (맨 마지막 확장자만 제거 후 하이픈 기준 추출)
|
||||
String extractedPartNo = extractPartNoFromFileName(originalFileName);
|
||||
|
||||
// 품번과 정확히 일치하는 경우만 매칭
|
||||
String matchedPartNo = null;
|
||||
System.out.println("품번 매칭 시작 - 추출된 품번: " + extractedPartNo);
|
||||
|
||||
if(extractedPartNo != null && !extractedPartNo.isEmpty()) {
|
||||
// 정확한 매칭 (추출된 품번과 DB 품번이 정확히 일치)
|
||||
if(partNoMap.containsKey(extractedPartNo)) {
|
||||
matchedPartNo = extractedPartNo;
|
||||
System.out.println(" ✓ 품번 정확 매칭 성공: " + matchedPartNo);
|
||||
}
|
||||
}
|
||||
// 파일명에서 확장자 제거 후 DB 품번과 매칭
|
||||
String fileNameWithoutExt = removeFileExtensions(originalFileName);
|
||||
String matchedPartNo = findMatchingPartNo(fileNameWithoutExt, partNoMap.keySet());
|
||||
|
||||
if(matchedPartNo == null) {
|
||||
System.out.println(" ✗ 품번 매칭 실패 - 파일명: " + originalFileName + ", 추출된 품번: " + extractedPartNo);
|
||||
System.out.println(" ✗ 품번 매칭 실패 - 파일명: " + originalFileName + ", 확장자 제거: " + fileNameWithoutExt);
|
||||
notFoundCount++;
|
||||
continue;
|
||||
}
|
||||
System.out.println(" ✓ 품번 매칭 성공: " + matchedPartNo + " (파일: " + originalFileName + ")");
|
||||
|
||||
// 해당 파트에 파일 정보 저장
|
||||
Map partInfo = partNoMap.get(matchedPartNo);
|
||||
@@ -2936,114 +2892,59 @@ public class PartMngController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일명에서 품번을 추출하는 헬퍼 메서드
|
||||
*
|
||||
* 품번 추출 규칙:
|
||||
* 1. 모든 확장자 제거 (.idw.pdf → .idw도 제거)
|
||||
* 2. 확장자 제거 후 첫 번째 하이픈(-) 위치 찾기
|
||||
* 3. 하이픈 앞 자릿수에 따라 품번 길이 결정
|
||||
* - 5자리: 하이픈 포함 10자리 추출 (예: 20002-0043)
|
||||
* - 7자리: 하이픈 포함 16자리 추출 (예: 2000200-004300-01)
|
||||
*
|
||||
* @param fileName 원본 파일명 (예: "20002-0043.idw.pdf")
|
||||
* @return 추출된 품번 (예: "20002-0043") 또는 null
|
||||
* 파일명에서 알려진 확장자를 모두 제거
|
||||
* 이중/삼중 확장자 대응 (예: file.idw.pdf → file)
|
||||
*/
|
||||
private String extractPartNoFromFileName(String fileName) {
|
||||
private String removeFileExtensions(String fileName) {
|
||||
if(fileName == null || fileName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// 1단계: 모든 확장자 제거 (이중/삼중 확장자 대응)
|
||||
// 알려진 CAD 확장자 목록
|
||||
String[] cadExtensions = {".idw", ".dwg", ".dxf", ".stp", ".step", ".pdf", ".chg"};
|
||||
|
||||
String fileNameWithoutExt = fileName;
|
||||
|
||||
// 반복적으로 확장자 제거 (예: file.idw.pdf → file.idw → file)
|
||||
boolean extensionRemoved = true;
|
||||
while(extensionRemoved) {
|
||||
extensionRemoved = false;
|
||||
|
||||
// 마지막 점 찾기
|
||||
int lastDotIndex = fileNameWithoutExt.lastIndexOf('.');
|
||||
if(lastDotIndex > 0) {
|
||||
String currentExt = fileNameWithoutExt.substring(lastDotIndex).toLowerCase();
|
||||
|
||||
// 알려진 CAD 확장자인 경우 제거
|
||||
for(String ext : cadExtensions) {
|
||||
if(currentExt.equals(ext)) {
|
||||
fileNameWithoutExt = fileNameWithoutExt.substring(0, lastDotIndex);
|
||||
extensionRemoved = true;
|
||||
System.out.println("[품번 추출] 확장자 제거: " + currentExt + " → " + fileNameWithoutExt);
|
||||
break;
|
||||
}
|
||||
String[] knownExtensions = {".idw", ".dwg", ".dxf", ".stp", ".step", ".pdf", ".chg"};
|
||||
String result = fileName;
|
||||
|
||||
boolean extensionRemoved = true;
|
||||
while(extensionRemoved) {
|
||||
extensionRemoved = false;
|
||||
int lastDotIndex = result.lastIndexOf('.');
|
||||
if(lastDotIndex > 0) {
|
||||
String currentExt = result.substring(lastDotIndex).toLowerCase();
|
||||
for(String ext : knownExtensions) {
|
||||
if(currentExt.equals(ext)) {
|
||||
result = result.substring(0, lastDotIndex);
|
||||
extensionRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("[품번 추출] 1단계 완료 - 모든 확장자 제거: " + fileNameWithoutExt);
|
||||
|
||||
// 2단계: 첫 번째 하이픈 위치 찾기
|
||||
int firstHyphenIndex = fileNameWithoutExt.indexOf('-');
|
||||
if(firstHyphenIndex == -1) {
|
||||
System.out.println("[품번 추출] 하이픈이 없음 - 추출 실패");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 3단계: 하이픈 앞 자릿수 확인
|
||||
String beforeHyphen = fileNameWithoutExt.substring(0, firstHyphenIndex);
|
||||
int beforeHyphenLength = beforeHyphen.length();
|
||||
|
||||
System.out.println("[품번 추출] 2단계 - 하이픈 앞 문자열: " + beforeHyphen + " (길이: " + beforeHyphenLength + ")");
|
||||
|
||||
// 4단계: 자릿수에 따라 품번 추출
|
||||
String extractedPartNo = null;
|
||||
|
||||
if(beforeHyphenLength == 5) {
|
||||
// 스핀들 설계팀: 5자리 -> 하이픈 1개 (5-4 = 10자리)
|
||||
// 예: 20002-0043
|
||||
int targetLength = 10;
|
||||
if(fileNameWithoutExt.length() >= targetLength) {
|
||||
extractedPartNo = fileNameWithoutExt.substring(0, targetLength);
|
||||
System.out.println("[품번 추출] 3단계 - 5자리 패턴 (10자리 추출): " + extractedPartNo);
|
||||
} else {
|
||||
System.out.println("[품번 추출] 5자리 패턴이지만 총 길이가 10자리 미만 - 추출 실패");
|
||||
}
|
||||
} else if(beforeHyphenLength == 7) {
|
||||
// 장비 개발팀: 7자리 -> 하이픈이 1개 또는 2개
|
||||
// 하이픈 1개: 7-9 = 17자리 (예: 2000200-004300-0)
|
||||
// 하이픈 2개: 7-6-2 = 18자리 (예: 2000200-004300-02)
|
||||
|
||||
// 두 번째 하이픈이 있는지 확인
|
||||
int secondHyphenIndex = fileNameWithoutExt.indexOf('-', firstHyphenIndex + 1);
|
||||
|
||||
if(secondHyphenIndex != -1) {
|
||||
// 하이픈이 2개인 경우: 7-6-2 패턴 = 18자리
|
||||
// 예: 2000200-004300-02
|
||||
extractedPartNo = fileNameWithoutExt;
|
||||
System.out.println("[품번 추출] 3단계 - 7자리 패턴 (하이픈 2개, 전체 품번): " + extractedPartNo);
|
||||
} else {
|
||||
// 하이픈이 1개인 경우: 7-9 패턴 = 17자리
|
||||
// 예: 2000200-004300-0 (16자리만 추출)
|
||||
int targetLength = 16;
|
||||
if(fileNameWithoutExt.length() >= targetLength) {
|
||||
extractedPartNo = fileNameWithoutExt.substring(0, targetLength);
|
||||
System.out.println("[품번 추출] 3단계 - 7자리 패턴 (하이픈 1개, 16자리 추출): " + extractedPartNo);
|
||||
} else {
|
||||
System.out.println("[품번 추출] 7자리 패턴이지만 총 길이가 16자리 미만 - 추출 실패");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("[품번 추출] 하이픈 앞이 5자리 또는 7자리가 아님 - 추출 실패");
|
||||
}
|
||||
|
||||
return extractedPartNo;
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("[품번 추출] 예외 발생: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 확장자 제거된 파일명에서 DB 품번과 매칭
|
||||
* 파일명이 품번과 일치하거나 품번으로 시작하는 경우 매칭
|
||||
* 여러 품번이 매칭되면 가장 긴 품번 우선 (정확도 높은 매칭)
|
||||
*/
|
||||
private String findMatchingPartNo(String fileNameWithoutExt, java.util.Set<String> partNoSet) {
|
||||
if(fileNameWithoutExt == null || fileNameWithoutExt.isEmpty() || partNoSet == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 정확 매칭 우선
|
||||
if(partNoSet.contains(fileNameWithoutExt)) {
|
||||
return fileNameWithoutExt;
|
||||
}
|
||||
|
||||
// 파일명이 품번으로 시작하는지 확인 (가장 긴 품번 우선)
|
||||
String bestMatch = null;
|
||||
for(String partNo : partNoSet) {
|
||||
if(fileNameWithoutExt.startsWith(partNo)) {
|
||||
if(bestMatch == null || partNo.length() > bestMatch.length()) {
|
||||
bestMatch = partNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestMatch;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user