하관우 하관우 05-22
2025 - 5 -22 하관우 엑셀다운로드 스타일 변경경
@c221bcfebe7a68bbe2cf562758830e44595f8723
client/resources/api/file.js
--- client/resources/api/file.js
+++ client/resources/api/file.js
@@ -5,6 +5,11 @@
   return downloadService.downloadFile(file, { responseType: 'blob' });
 }
 
+// 엑셀 다운로드
+export const excelDownloadProc = (searchReqDTO , fileName) => {
+  return downloadService.downloadExcel(searchReqDTO, fileName, { responseType: 'blob' });
+}
+
 // 다중 파일 다운로드
 export const multiFileDownloadProc = (files) => {
   return downloadService.downloadMultipleFiles(files, { responseType: 'blob' });
client/resources/js/downloadService.js
--- client/resources/js/downloadService.js
+++ client/resources/js/downloadService.js
@@ -120,6 +120,73 @@
     }
   },
 
+  // 엑셀 다운로드 메서드
+  async downloadExcel(searchReqDTO, fileName, options = {}) {
+    try {
+      // 다운로드 상태 초기화 (현재 진행률 유지)
+      const currentProgress = uploadProgressStore.totalProgress;
+      uploadProgressStore.startDownload(fileName || '파일 다운로드 중...');
+      uploadProgressStore.setStage('downloading');
+
+      // 이전 진행률이 있으면 유지
+      if (currentProgress > 0) {
+        uploadProgressStore.totalProgress = currentProgress;
+      }
+
+      // 즉시 진행률 시뮬레이션 시작 (서버 응답 전)
+      this._startProgressSimulation();
+
+      // apiClient를 사용하여 다운로드 요청
+      const response = await apiClient.get(`/excel/excelDownloadAll.json`, {
+        params: searchReqDTO, // 검색 조건 파라미터 전달
+        responseType: 'blob', // 엑셀 파일을 Blob 형태로 받기 위해 설정
+        ...options, // 외부에서 전달된 추가 옵션 적용
+        onDownloadProgress: (progressEvent) => {
+          // 시뮬레이션 중단
+          this._stopProgressSimulation();
+
+          if (progressEvent.total) {
+            // 진행 상태 계산
+            const realProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
+
+            // 실제 진행률이 시뮬레이션 진행률보다 낮으면, 시뮬레이션 진행률부터 시작
+            const startProgress = Math.max(this._lastSimulatedProgress, realProgress);
+
+            // 남은 진행률을 60%~100% 범위로 매핑
+            // 예: 실제 진행률이 0%일 때 40%, 100%일 때 100%가 되도록
+            const adjustedProgress = 40 + (realProgress * 60 / 100);
+
+            // 둘 중 더 큰 값을 사용
+            uploadProgressStore.totalProgress = Math.round(Math.max(startProgress, adjustedProgress));
+          }
+
+          // 사용자 정의 onDownloadProgress 콜백이 있으면 호출
+          if (options.onDownloadProgress) {
+            options.onDownloadProgress(progressEvent);
+          }
+        }
+      });
+
+      // 시뮬레이션 중단 (만약 아직 실행 중이라면)
+      this._stopProgressSimulation();
+
+      // 다운로드 완료 표시
+      uploadProgressStore.totalProgress = 100;
+
+      // 잠시 후 응답 반환 (완료 상태를 보여줄 시간 제공)
+      await new Promise(resolve => setTimeout(resolve, 300));
+
+      return response;
+    } catch (error) {
+      // 시뮬레이션 중단
+      this._stopProgressSimulation();
+
+      // 오류 발생 시 상태 초기화
+      uploadProgressStore.handleError();
+      throw error;
+    }
+  },
+
   // 다중 파일 다운로드 메서드
   async downloadMultipleFiles(files, options = {}) {
     try {
client/views/pages/bbsDcryPhoto/PicHistorySearch.vue
--- client/views/pages/bbsDcryPhoto/PicHistorySearch.vue
+++ client/views/pages/bbsDcryPhoto/PicHistorySearch.vue
@@ -77,7 +77,8 @@
 import DefaultPagination from '@/views/component/DefaultPagination.vue';
 // API
 import { findDcrysProc } from "@/resources/api/dcry";
-import { excelDownloadAll } from "../../../resources/api/main";
+import { excelDownloadProc } from '@/resources/api/file';
+import uploadProgressStore from '@/resources/js/uploadProgressStore';
 
 export default {
   components: {
@@ -277,7 +278,6 @@
 
     // 사진 기록물 엑셀 다운로드
     async fnDownload() {
-      this.loading = true; // 로딩 시작
       try {
         const params = JSON.parse(JSON.stringify(this.searchReqDTO));
         if (this.searchReqDTO.searchCtgries && this.searchReqDTO.searchCtgries.length > 0) {
@@ -286,19 +286,18 @@
           delete params.searchCtgries;
         }
 
+        let today = new Date().toISOString().substring(2, 10);
+        today = today.replace(/[^0-9]/g, "");
+        const fileName = `[사진 기록물]기록물_${today}.xlsx`;
+
         params.usePhoto = true;
-        const response = await excelDownloadAll(params);
+        const response = await excelDownloadProc(params, fileName);
 
         const url = window.URL.createObjectURL(
           new Blob([response.data], {
             type: response.headers["content-type"],
           })
         );
-
-        let today = new Date().toISOString().substring(2, 10);
-        today = today.replace(/[^0-9]/g, "");
-        const fileName = `[사진기록물]기록물_${today}.xlsx`;
-
         const link = document.createElement("a");
         link.href = url;
         link.setAttribute("download", fileName);
@@ -318,7 +317,7 @@
           alert("엑셀 다운로드 중 네트워크 에러가 발생했습니다.\n관리자에게 문의해주세요.");
         }
       } finally {
-        this.loading = false;
+        uploadProgressStore.closeModal();
       }
     },
   },
client/views/pages/bbsDcryVideo/VideoHistorySearch.vue
--- client/views/pages/bbsDcryVideo/VideoHistorySearch.vue
+++ client/views/pages/bbsDcryVideo/VideoHistorySearch.vue
@@ -77,7 +77,8 @@
 import DefaultPagination from '@/views/component/DefaultPagination.vue';
 // API
 import { findDcrysProc } from "@/resources/api/dcry";
-import { excelDownloadAll } from "../../../resources/api/main"
+import { excelDownloadProc } from '@/resources/api/file';
+import uploadProgressStore from '@/resources/js/uploadProgressStore';
 export default {
   components: {
     SearchFormComponent,
@@ -275,7 +276,6 @@
     },
     // 영상상 기록물 엑셀 다운로드
     async fnDownload() {
-      this.loading = true; // 로딩 시작
       try {
         const params = JSON.parse(JSON.stringify(this.searchReqDTO));
         if (this.searchReqDTO.searchCtgries && this.searchReqDTO.searchCtgries.length > 0) {
@@ -284,19 +284,18 @@
           delete params.searchCtgries;
         }
 
+        let today = new Date().toISOString().substring(2, 10);
+        today = today.replace(/[^0-9]/g, "");
+        const fileName = `[영상 기록물]기록물_${today}.xlsx`;
+
         params.useVideo = true;
-        const response = await excelDownloadAll(params);
+        const response = await excelDownloadProc(params, fileName);
 
         const url = window.URL.createObjectURL(
           new Blob([response.data], {
             type: response.headers["content-type"],
           })
         );
-
-        let today = new Date().toISOString().substring(2, 10);
-        today = today.replace(/[^0-9]/g, "");
-        const fileName = `[영상기록물]기록물_${today}.xlsx`;
-
         const link = document.createElement("a");
         link.href = url;
         link.setAttribute("download", fileName);
@@ -316,7 +315,7 @@
           alert("엑셀 다운로드 중 네트워크 에러가 발생했습니다.\n관리자에게 문의해주세요.");
         }
       } finally {
-        this.loading = false;
+        uploadProgressStore.closeModal();
       }
     },
   },
client/views/pages/bbsMediaVido/MediaVideoSearch.vue
--- client/views/pages/bbsMediaVido/MediaVideoSearch.vue
+++ client/views/pages/bbsMediaVido/MediaVideoSearch.vue
@@ -72,7 +72,8 @@
 import DefaultPagination from '@/views/component/DefaultPagination.vue';
 // API
 import { findAllMediaVidosProc } from "@/resources/api/mediaVido";
-import { excelDownloadAll } from "../../../resources/api/main";
+import { excelDownloadProc } from '@/resources/api/file';
+import uploadProgressStore from '@/resources/js/uploadProgressStore';
 
 export default {
   components: {
@@ -270,7 +271,6 @@
 
     // 미디어 영상 엑셀 다운로드
     async fnDownload() {
-      this.loading = true; // 로딩 시작
       try {
         const params = JSON.parse(JSON.stringify(this.searchReqDTO));
         if (this.searchReqDTO.searchCtgries && this.searchReqDTO.searchCtgries.length > 0) {
@@ -278,20 +278,19 @@
         } else {
           delete params.searchCtgries;
         }
-        
-        params.useMedia =true;
-        const response = await excelDownloadAll(params);
+
+        let today = new Date().toISOString().substring(2, 10);
+        today = today.replace(/[^0-9]/g, "");
+        const fileName = `[미디어 영상]언론에서 바라보는 구미시_${today}.xlsx`;
+
+        params.useMedia = true;
+        const response = await excelDownloadProc(params, fileName);
 
         const url = window.URL.createObjectURL(
           new Blob([response.data], {
             type: response.headers["content-type"],
           })
         );
-
-        let today = new Date().toISOString().substring(2, 10);
-        today = today.replace(/[^0-9]/g, "");
-        const fileName = `[미디어영상]언론에서 바라보는 구미시시_${today}.xlsx`;
-
         const link = document.createElement("a");
         link.href = url;
         link.setAttribute("download", fileName);
@@ -311,7 +310,7 @@
           alert("엑셀 다운로드 중 네트워크 에러가 발생했습니다.\n관리자에게 문의해주세요.");
         }
       } finally {
-        this.loading = false;
+        uploadProgressStore.closeModal();
       }
     },
   },
client/views/pages/bbsNesDta/NewsReleaseSearch.vue
--- client/views/pages/bbsNesDta/NewsReleaseSearch.vue
+++ client/views/pages/bbsNesDta/NewsReleaseSearch.vue
@@ -73,7 +73,8 @@
 import DefaultPagination from '@/views/component/DefaultPagination.vue';
 // API
 import { findAllNesDtasProc } from "@/resources/api/nesDta";
-import { excelDownloadAll } from "../../../resources/api/main";
+import { excelDownloadProc } from '@/resources/api/file';
+import uploadProgressStore from '@/resources/js/uploadProgressStore';
 
 export default {
   components: {
@@ -271,7 +272,6 @@
 
     // 스크랩 자료 엑셀 다운로드
     async fnDownload() {
-      this.loading = true; // 로딩 시작
       try {
         const params = JSON.parse(JSON.stringify(this.searchReqDTO));
         if (this.searchReqDTO.searchCtgries && this.searchReqDTO.searchCtgries.length > 0) {
@@ -279,20 +279,19 @@
         } else {
           delete params.searchCtgries;
         }
-        
-        params.useNews =true;
-        const response = await excelDownloadAll(params);
+
+        let today = new Date().toISOString().substring(2, 10);
+        today = today.replace(/[^0-9]/g, "");
+        const fileName = `[스크랩 자료]언론에서 바라보는 구미시_${today}.xlsx`;
+
+        params.useNews = true;
+        const response = await excelDownloadProc(params, fileName);
 
         const url = window.URL.createObjectURL(
           new Blob([response.data], {
             type: response.headers["content-type"],
           })
         );
-
-        let today = new Date().toISOString().substring(2, 10);
-        today = today.replace(/[^0-9]/g, "");
-        const fileName = `[스크랩자료]언론에서 바라보는 구미시_${today}.xlsx`;
-
         const link = document.createElement("a");
         link.href = url;
         link.setAttribute("download", fileName);
@@ -312,7 +311,7 @@
           alert("엑셀 다운로드 중 네트워크 에러가 발생했습니다.\n관리자에게 문의해주세요.");
         }
       } finally {
-        this.loading = false;
+        uploadProgressStore.closeModal();
       }
     },
   },
Add a comment
List