
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
// @/resources/js/downloadService.js
import { apiClient } from '@/resources/api/index';
import uploadProgressStore from '@/resources/js/uploadProgressStore';
// 파일 다운로드를 처리하는 서비스
const downloadService = {
// 내부 타이머 변수
_simulationTimer: null,
// 마지막 시뮬레이션 진행률
_lastSimulatedProgress: 0,
// 진행률 시뮬레이션 시작 (서버 응답이 지연될 때)
_startProgressSimulation() {
// 이미 타이머가 있으면 정리
if (this._simulationTimer) {
clearInterval(this._simulationTimer);
}
// 현재 진행률 저장
this._lastSimulatedProgress = uploadProgressStore.totalProgress;
// 시작 진행률 설정 (최소 5%)
if (this._lastSimulatedProgress < 5) {
this._lastSimulatedProgress = 5;
uploadProgressStore.totalProgress = 5;
}
// 진행률 시뮬레이션 시작 (최대 40%까지만)
let simulatedProgress = this._lastSimulatedProgress;
this._simulationTimer = setInterval(() => {
// 실제 진행이 시작되면 시뮬레이션 중단
if (uploadProgressStore.totalProgress > simulatedProgress) {
this._lastSimulatedProgress = uploadProgressStore.totalProgress;
clearInterval(this._simulationTimer);
this._simulationTimer = null;
return;
}
// 진행률 증가 (40%까지)
if (simulatedProgress < 40) {
simulatedProgress += Math.random() * 1.5; // 0~1.5% 랜덤하게 증가
uploadProgressStore.totalProgress = Math.round(simulatedProgress);
this._lastSimulatedProgress = uploadProgressStore.totalProgress;
}
}, 200); // 0.2초마다 업데이트
},
// 시뮬레이션 종료
_stopProgressSimulation() {
if (this._simulationTimer) {
clearInterval(this._simulationTimer);
this._simulationTimer = null;
}
},
// 단일 파일 다운로드 메서드
async downloadFile(file, options = {}) {
try {
// 다운로드 상태 초기화 (현재 진행률 유지)
const currentProgress = uploadProgressStore.totalProgress;
uploadProgressStore.startDownload(file.fileNm || '파일 다운로드 중...');
uploadProgressStore.setStage('downloading');
// 이전 진행률이 있으면 유지
if (currentProgress > 0) {
uploadProgressStore.totalProgress = currentProgress;
}
// 즉시 진행률 시뮬레이션 시작 (서버 응답 전)
this._startProgressSimulation();
// apiClient를 사용하여 다운로드 요청
const response = await apiClient.get(`/file/${file.fileId}/${file.fileOrdr || 1}/fileDownload.json`, {
responseType: '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 {
// 다운로드 상태 초기화 (현재 진행률 유지)
const currentProgress = uploadProgressStore.totalProgress;
uploadProgressStore.startDownload('다중 파일 다운로드 중...');
uploadProgressStore.setStage('downloading');
// 이전 진행률이 있으면 유지
if (currentProgress > 0) {
uploadProgressStore.totalProgress = currentProgress;
}
// 즉시 진행률 시뮬레이션 시작 (서버 응답 전)
this._startProgressSimulation();
// apiClient를 사용하여 다운로드 요청
const response = await apiClient.post(`/file/multiFileDownload.json`, files, {
responseType: '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);
// 남은 진행률을 40%~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;
}
}
};
export default downloadService;