Skip to content

Commit

Permalink
Merge pull request #12 from hw-coconote/feature/driveRoot
Browse files Browse the repository at this point in the history
[FEAT]폴더 현재경로 표시 및 뒤로가기 추가  폴더 이름 변경 에러 수정
  • Loading branch information
jsangmin99 authored Oct 1, 2024
2 parents c185e16 + f6953ce commit 9fbf4cc
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 89 deletions.
225 changes: 138 additions & 87 deletions src/components/drive/FolderComponent.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
<template>
<div class="drive-container">
<!-- 현재 경로 표시 -->
<div class="breadcrumb">
<span v-for="(folder, index) in breadcrumb" :key="folder.folderId">
<span @click="navigateToFolder(folder.folderId)" class="breadcrumb-item">
{{ folder.folderName }}
</span>
<span v-if="index !== breadcrumb.length - 1"> / </span> <!-- 마지막 폴더에는 '/' 표시 안함 -->
</span>
</div>

<!-- 뒤로 가기 버튼 -->
<div class="toolbar">
<button @click="goBack" :disabled="!backButtonHistory.length">뒤로 가기</button>
<button @click="createFolder">새 폴더</button>
<button @click="refreshFolderList">새로고침</button>
<input type="file" multiple @change="onFileChange" />
Expand Down Expand Up @@ -45,19 +57,36 @@ import axios from '@/services/axios';
export default {
data() {
return {
folderList: [],
fileList: [],
currentFolderId: null,
folderList: [], // 현재 폴더 내 폴더 목록
fileList: [], // 현재 폴더 내 파일 목록
currentFolderId: null, // 현재 탐색 중인 폴더 ID
backButtonHistory: [], // 이전 폴더 기록
files: [], // 업로드할 파일 배열
uploadProgress: [], // 업로드 진행 상황
uploadProgress: [], // 파일 업로드 진행 상황
breadcrumb: [] // 폴더 경로를 저장하는 배열
};
},
methods: {
async loadChannelDrive() {
const channelId = this.$route.params.id; // URL에서 채널 ID 추출
try {
const response = await axios.get(`${process.env.VUE_APP_API_BASE_URL}/channel/${channelId}/drive`);
const data = response.data.result;
this.currentFolderId = data.nowFolderId;
this.folderList = data.folderListDto || [];
this.fileList = data.fileListDto || [];
this.breadcrumb = [{ folderId: this.currentFolderId, folderName: data.nowFolderName }];
} catch (error) {
console.error('채널 드라이브 로딩 실패:', error);
alert('채널 드라이브 로딩 중 오류가 발생했습니다.');
}
},
// 폴더 생성
async createFolder() {
try {
const response = await axios.post(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/create`, {
channelId: 1, // 적절한 채널 ID 설정
channelId: 1,
parentFolderId: this.currentFolderId,
});
alert(response.data.result.message || '폴더 생성 완료');
Expand All @@ -68,19 +97,54 @@ export default {
}
},
// 뒤로 가기 기능
goBack() {
if (this.backButtonHistory.length) {
console.log('뒤로 가기:', this.backButtonHistory);
const previousFolderId = this.backButtonHistory.pop(); // 마지막 폴더 ID를 제거하고 이동
this.breadcrumb.pop(); // 경로에서 마지막 폴더 제거
this.navigateToFolder(previousFolderId, false); // false는 뒤로가기 이동 시 기록하지 않기 위함
}
},
// 폴더 탐색
// async refreshFolderList() {
// try {
// const folderId = this.currentFolderId || 1; // currentFolderId가 없으면 루트 폴더 ID 사용
// const response = await axios.get(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/${folderId}`);
// this.folderList = response.data.result.folderListDto || [];
// this.fileList = response.data.result.fileListDto || [];
// } catch (error) {
// console.error('폴더/파일 목록 갱신 실패:', error);
// alert('목록 갱신 중 오류가 발생했습니다.');
// }
// },
// 폴더/파일 목록 갱신
async refreshFolderList() {
try {
const response = await axios.get(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/${this.currentFolderId || 1}`);
this.folderList = response.data.result.folderListDto || [];
this.fileList = response.data.result.fileListDto || [];
} catch (error) {
console.error('폴더/파일 목록 갱신 실패:', error);
alert('목록 갱신 중 오류가 발생했습니다.');
}
},
// 파일 선택 처리
onFileChange(event) {
this.files = Array.from(event.target.files);
this.uploadProgress = Array(this.files.length).fill(0); // 업로드 진행상황 초기화
},
// 파일을 S3에 업로드하는 함수 (첫 번째 방식과 유사)
// 파일 업로드
async uploadFiles() {
if (!this.files.length) return;
try {
// 서버에 presigned URLs 요청
const presignedUrlResponse = await axios.post('http://localhost:8080/api/v1/files/presigned-urls', this.files.map(file => ({
const presignedUrlResponse = await axios.post(`${process.env.VUE_APP_API_BASE_URL}/files/presigned-urls`, this.files.map(file => ({
fileName: file.name,
fileSize: file.size
})));
Expand Down Expand Up @@ -110,33 +174,6 @@ export default {
alert('파일 업로드 중 오류가 발생했습니다.');
}
},
// 폴더 삭제
async deleteFolder(folderId) {
try {
const response = await axios.delete(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/${folderId}`);
alert(response.data.message);
this.refreshFolderList();
} catch (error) {
console.error(error);
}
},
// 폴더 이동
async moveFolder(folderId) {
const parentId = prompt('이동할 폴더의 ID를 입력하세요:');
if (!parentId) return;
try {
const response = await axios.patch(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/move`, {
folderId: folderId,
parentId: parentId,
});
alert(response.data.message);
this.refreshFolderList();
} catch (error) {
console.error(error);
}
},
// S3에 파일 업로드
async uploadFileToS3(file, presignedUrl) {
Expand Down Expand Up @@ -168,52 +205,21 @@ export default {
// 파일 메타데이터 저장
async saveFileMetadata(uploadedFileUrls) {
// folderId가 필수라면, 없을 경우 경고 메시지 출력
if (!this.currentFolderId) {
alert("폴더를 선택해야 합니다.");
return;
}
const metadataDto = {
channelId: 1, // 적절한 채널 ID로 수정하세요
folderId: this.currentFolderId, // 반드시 folderId를 포함하여 전송
fileType: 'OTHER', // 백엔드에서 필요한 Enum 값 (FileType.THREAD, FileType.CANVAS 등)
channelId: 1, // 적절한 채널 ID로 수정
folderId: this.currentFolderId,
fileType: 'OTHER',
fileSaveListDto: uploadedFileUrls.map((url, index) => ({
fileName: this.files[index].name, // 원본 파일 이름
fileUrl: url, // 짧아진 S3 URL
})), // 파일 메타데이터 리스트
fileName: this.files[index].name,
fileUrl: url,
})),
};
await axios.post('http://localhost:8080/api/v1/files/metadata', metadataDto);
},
// 파일 다운로드
async downloadFile(fileId) {
try {
// presigned URL 가져오기
const response = await axios.get(`http://localhost:8080/api/v1/files/${fileId}/download`);
const presignedUrl = response.data.result; // presigned URL 가져오기
// Blob을 사용하여 파일 다운로드
const fileResponse = await axios.get(presignedUrl, { responseType: 'blob' });
// 파일 이름 추출
const fileName = response.headers['content-disposition']
? response.headers['content-disposition'].split('filename=')[1].replace(/"/g, '')
: 'downloaded_file';
// Blob을 파일로 변환하여 다운로드
const blob = new Blob([fileResponse.data], { type: fileResponse.headers['content-type'] });
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.setAttribute('download', fileName); // 서버에서 전달된 파일 이름으로 설정
document.body.appendChild(link);
link.click(); // 링크 클릭 이벤트로 다운로드 시작
document.body.removeChild(link); // 링크 제거
} catch (error) {
console.error("파일 다운로드에 실패했습니다.", error);
alert("파일 다운로드 중 오류가 발생했습니다.");
}
await axios.post(`${process.env.VUE_APP_API_BASE_URL}/files/metadata`, metadataDto);
},
// 파일 삭제
Expand All @@ -222,10 +228,8 @@ export default {
const confirmed = confirm("정말로 이 파일을 삭제하시겠습니까?");
if (!confirmed) return;
await axios.delete(`http://localhost:8080/api/v1/files/${fileId}`);
await axios.delete(`${process.env.VUE_APP_API_BASE_URL}/files/${fileId}`);
alert('파일이 성공적으로 삭제되었습니다.');
// 파일 목록 갱신
this.refreshFolderList();
} catch (error) {
console.error('파일 삭제 실패:', error);
Expand All @@ -242,39 +246,73 @@ export default {
}
try {
await axios.patch('http://localhost:8080/api/v1/files/move', {
await axios.patch(`${process.env.VUE_APP_API_BASE_URL}/files/move`, {
fileId: fileId,
folderId: newFolderId
});
alert('파일이 성공적으로 이동되었습니다.');
// 파일 목록 갱신
this.refreshFolderList();
} catch (error) {
console.error('파일 이동 실패:', error);
alert('파일 이동 중 오류가 발생했습니다.');
}
},
// 폴더/파일 목록 갱신
async refreshFolderList() {
// 폴더 삭제
async deleteFolder(folderId) {
try {
const response = await axios.get(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/${this.currentFolderId || 1}`);
this.folderList = response.data.result.folderListDto || [];
this.fileList = response.data.result.fileListDto || [];
const confirmed = confirm("정말로 이 폴더를 삭제하시겠습니까?");
if (!confirmed) return;
await axios.delete(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/${folderId}`);
alert('폴더가 성공적으로 삭제되었습니다.');
this.refreshFolderList();
} catch (error) {
console.error('폴더/파일 목록 갱신 실패:', error);
alert('목록 갱신 중 오류가 발생했습니다.');
console.error('폴더 삭제 실패:', error);
alert('폴더 삭제 중 오류가 발생했습니다.');
}
},
// 폴더 이름 변경
async renameFolder(folderId) {
const newFolderName = prompt("새 폴더 이름을 입력하세요:");
if (!newFolderName) {
alert("유효한 폴더 이름을 입력하세요.");
return;
}
try {
// 백엔드의 API 경로에 맞춰서 folderId를 URL에 삽입
await axios.patch(`${process.env.VUE_APP_API_BASE_URL}/drive/folder/${folderId}/update/name`, null, {
params: {
folderName: newFolderName, // 요청 파라미터로 폴더 이름 전달
},
});
alert('폴더 이름이 성공적으로 변경되었습니다.');
this.refreshFolderList(); // 목록 갱신
} catch (error) {
console.error('폴더 이름 변경 실패:', error);
alert('폴더 이름 변경 중 오류가 발생했습니다.');
}
},
// 폴더 탐색
async navigateToFolder(folderId) {
async navigateToFolder(folderId, recordHistory = true) {
if (recordHistory && this.currentFolderId !== folderId) {
this.backButtonHistory.push(this.currentFolderId); // 현재 폴더 ID를 기록
const selectedFolder = this.folderList.find(folder => folder.folderId === folderId); // 탐색할 폴더 찾기
if (selectedFolder) {
this.breadcrumb.push({
folderId: selectedFolder.folderId,
folderName: selectedFolder.folderName,
});
}
}
this.currentFolderId = folderId;
this.refreshFolderList();
await this.refreshFolderList();
},
},
created() {
// this.currentFolderId = this.currentFolderId || 1;
this.refreshFolderList();
},
};
Expand All @@ -285,6 +323,19 @@ export default {
padding: 20px;
}
.breadcrumb {
margin-bottom: 20px;
}
.breadcrumb span {
cursor: pointer;
color: blue;
}
.breadcrumb span:hover {
text-decoration: underline;
}
.toolbar {
display: flex;
gap: 10px;
Expand Down
4 changes: 2 additions & 2 deletions src/router/driveRouter.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// driveRouter.js
import FolderComponent from '@/components/drive/FolderComponent.vue';


export const driveRouter = [
{
path: '/drive',
path: '/channel/:id/drive', // URL에서 채널 ID를 받기 위해 :id 사용
name: 'FolderComponent',
component: FolderComponent,
props: true, // 채널 ID를 컴포넌트에 props로 전달
},
];

0 comments on commit 9fbf4cc

Please sign in to comment.