diff --git a/WebContent/WEB-INF/view/common/FileDetailPopup.jsp b/WebContent/WEB-INF/view/common/FileDetailPopup.jsp
index 8cd9fc1..474574c 100644
--- a/WebContent/WEB-INF/view/common/FileDetailPopup.jsp
+++ b/WebContent/WEB-INF/view/common/FileDetailPopup.jsp
@@ -138,7 +138,16 @@ function fileDelete(fileObjId){
dataType:"json",
async:true,
success:function(data){
- fn_fileCallback("sr","${docType}");
+ fn_fileCallback("sr","${docType}");
+ // 부모 창의 그리드 새로고침
+ if(opener && typeof opener.fn_search == "function"){
+ opener.fn_search();
+ }
+ // Tabulator 그리드가 있는 경우
+ if(opener && opener._tabulGrid){
+ opener._tabulGrid.replaceData();
+ }
+ // 기존 콜백 함수도 실행
if(fnc_checkNull(callbackFnc) != ""){
opener.eval(callbackFnc+"();");
}
diff --git a/WebContent/WEB-INF/view/common/FileRegistPopup.jsp b/WebContent/WEB-INF/view/common/FileRegistPopup.jsp
index 99431e0..071f60f 100644
--- a/WebContent/WEB-INF/view/common/FileRegistPopup.jsp
+++ b/WebContent/WEB-INF/view/common/FileRegistPopup.jsp
@@ -164,7 +164,16 @@ function fileDelete(fileObjId){
dataType:"json",
async:false,
success:function(data){
- fn_fileCallback("sr","${docType}");
+ fn_fileCallback("sr","${docType}");
+ // 부모 창의 그리드 새로고침
+ if(opener && typeof opener.fn_search == "function"){
+ opener.fn_search();
+ }
+ // Tabulator 그리드가 있는 경우
+ if(opener && opener._tabulGrid){
+ opener._tabulGrid.replaceData();
+ }
+ // 기존 콜백 함수도 실행
if(fnc_checkNull(callbackFnc) != ""){
opener.eval(callbackFnc+"();");
}
diff --git a/WebContent/WEB-INF/view/partMng/structurePopupLeft.jsp b/WebContent/WEB-INF/view/partMng/structurePopupLeft.jsp
index 699053b..ec465ff 100644
--- a/WebContent/WEB-INF/view/partMng/structurePopupLeft.jsp
+++ b/WebContent/WEB-INF/view/partMng/structurePopupLeft.jsp
@@ -39,27 +39,7 @@
.tabulator-row.level-9 { background-color: #FFFFEB !important; }
.tabulator-row.level-10 { background-color: #ffffff !important; }
-.file_icon, .file_empty_icon {
- display: inline-block;
- width: 20px;
- height: 20px;
- line-height: 20px;
- text-align: center;
- cursor: pointer;
- font-size: 16px;
-}
-.file_icon {
- color: #4CAF50;
-}
-.file_icon::before {
- content: '📄';
-}
-.file_empty_icon {
- color: #ccc;
-}
-.file_empty_icon::before {
- content: '○';
-}
+/* 파일 아이콘 스타일은 basic.css에서 관리 */
@@ -453,12 +590,10 @@ function fn_resetFilter() {
-
+
+
+
-
- ※수량 변경 후, 엔터치시면 저장됩니다.(신규 추가 파트만 가능)
-
-
diff --git a/WebContent/WEB-INF/view/projectConcept/FileRegistPopup.jsp b/WebContent/WEB-INF/view/projectConcept/FileRegistPopup.jsp
index 19d2644..216746a 100644
--- a/WebContent/WEB-INF/view/projectConcept/FileRegistPopup.jsp
+++ b/WebContent/WEB-INF/view/projectConcept/FileRegistPopup.jsp
@@ -35,6 +35,14 @@ $(document).ready(function(){
function refeshAttachFileArea(){
srAreaDraw();
+ // 부모 창의 그리드도 새로고침
+ if(opener && typeof opener.fn_search == "function"){
+ opener.fn_search();
+ }
+ // Tabulator 그리드가 있는 경우
+ if(opener && opener._tabulGrid){
+ opener._tabulGrid.replaceData();
+ }
}
//형상 영역을 display 한다.
@@ -112,7 +120,15 @@ function fileDelete(fileObjId){
dataType:"json",
async:true,
success:function(data){
- fn_fileCallback("sr","${docType}");
+ fn_fileCallback("sr","${docType}");
+ // 부모 창의 그리드 새로고침
+ if(opener && typeof opener.fn_search == "function"){
+ opener.fn_search();
+ }
+ // Tabulator 그리드가 있는 경우
+ if(opener && opener._tabulGrid){
+ opener._tabulGrid.replaceData();
+ }
},
error: function(jqxhr, status, error){
}
diff --git a/src/com/pms/controller/PartMngController.java b/src/com/pms/controller/PartMngController.java
index fc97f02..be6ee74 100644
--- a/src/com/pms/controller/PartMngController.java
+++ b/src/com/pms/controller/PartMngController.java
@@ -21,6 +21,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
+import com.oreilly.servlet.MultipartRequest;
+import com.pms.common.FileRenameClass;
import com.pms.common.JsonUtil;
import com.pms.common.SqlMapConfig;
import com.pms.common.bean.PersonBean;
@@ -2136,4 +2138,188 @@ public class PartMngController {
return "/ajax/ajaxResult";
}
+
+ /**
+ * 도면 파일 일괄 업로드
+ * 파일명에 품번이 포함된 경우 자동 매칭하여 업로드
+ * - stp 파일 -> 3D CAD 컬럼
+ * - dwg 파일 -> 2D Drawing CAD 컬럼
+ * - pdf 파일 -> 2D PDF CAD 컬럼
+ *
+ * @param request
+ * @param session
+ * @param bomObjId BOM OBJID
+ * @return
+ */
+ @RequestMapping(value="/partMng/uploadDrawingFiles.do", method=RequestMethod.POST)
+ @ResponseBody
+ public Map uploadDrawingFiles(
+ HttpServletRequest request,
+ HttpSession session) {
+
+ Map resultMap = new HashMap<>();
+ MultipartRequest multi = null;
+ FileRenameClass frc = null;
+
+ try {
+ PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN);
+ String userId = person != null ? person.getUserId() : "plmAdmin";
+
+ // MultipartRequest로 파일 업로드 처리
+ String storagePath = Constants.FILE_STORAGE;
+ int maxSize = 1024*1024*1024*9; // 9GB
+
+ File storage = new File(storagePath);
+ if(!storage.exists()) storage.mkdirs();
+
+ frc = new FileRenameClass();
+ multi = new MultipartRequest(request, storagePath, maxSize, "UTF-8", frc);
+ java.util.List fileList = frc.getFileList();
+
+ // MultipartRequest에서 bomObjId 파라미터 가져오기
+ String bomObjId = multi.getParameter("bomObjId");
+
+ if(bomObjId == null || bomObjId.isEmpty()) {
+ resultMap.put("result", "fail");
+ resultMap.put("message", "BOM ID가 전달되지 않았습니다.");
+ return resultMap;
+ }
+
+ // BOM 정보 조회
+ Map bomParam = new HashMap<>();
+ bomParam.put("objId", bomObjId);
+ Map bomInfo = partMngService.getBOMStructureStandardInfo(request, bomParam);
+
+ if(bomInfo == null) {
+ resultMap.put("result", "fail");
+ resultMap.put("message", "BOM 정보를 찾을 수 없습니다.");
+ return resultMap;
+ }
+
+ // 해당 BOM의 모든 파트 정보 조회
+ bomParam.put("SEARCH_BOM_OBJID", bomObjId);
+ ArrayList