
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<div class="content">
<div class="sub-title-area mb-30">
<h2>사진 기록물</h2>
<div class="breadcrumb-list">
<ul>
<li>
<img :src="homeicon" alt="Home Icon">
<p>기록물</p>
</li>
<li><img :src="righticon" alt=""></li>
<li>사진 기록물</li>
</ul>
</div>
</div>
<form class="gallery-form mb-40" @submit.prevent>
<dl class="mb-20">
<dd>
<p>{{ findResult.sj }}</p>
<div class="date flex align-center">
<img :src="calendaricon" alt="">
<span>{{ $dotFormatDate(findResult.rgsde) }}</span>
</div>
</dd>
</dl>
<div>
<div class="gallery">
<div class="main-swiper">
<swiper :style="{ '--swiper-navigation-color': '#fff', '--swiper-pagination-color': '#fff' }" :loop="true" :spaceBetween="10" :thumbs="{ swiper: thumbsSwiper }" :modules="modules" class="mySwiper2" @slideChange="handleMainSlideChange">
<swiper-slide v-for="(item, idx) of findResult.files" :key="idx">
<img :src="item.filePath" :alt="item.fileNm" />
</swiper-slide>
</swiper>
</div>
<div class="thumbnail">
<swiper @swiper="setThumbsSwiper" :spaceBetween="20" :slidesPerView="4" :freeMode="true" :watchSlidesProgress="true" :modules="modules" :navigation="true" class="mySwiper">
<swiper-slide v-for="(item, idx) of findResult.files" :key="idx" :class="{ 'active-thumb': activeIndex === idx }">
<input type="checkbox" :id="'photo_' + idx" :value="item" v-model="selectedFiles" @click.stop />
<img :src="item.filePath" :alt="item.fileNm" />
</swiper-slide>
</swiper>
</div>
</div>
<div class="btn-group">
<button class="select-down" @click="fnDownload('selected')">선택 다운로드</button>
<button class="all-down" @click="fnDownload('all')">전체 다운로드</button>
<div v-if="loading" class="loading-overlay">
<div class="loading-spinner"></div>
<div>
<p>다운로드 중입니다</p>
<p>잠시만 기다려주세요</p>
</div>
</div>
</div>
</div>
</form>
<h3>내용</h3>
<form class="info-form mb-50" @submit.prevent>
<dl>
<dd>
<ViewerComponent :content="findResult.cn" />
</dd>
</dl>
</form>
<h3>기본정보</h3>
<form class="info-form mb-50" @submit.prevent>
<dl>
<dd class="mb-20">
<img :src="addressicon" alt="">
<span>주소</span>
<p>{{ findResult.adres }}</p>
</dd>
<dd class="mb-20">
<img :src="yearicon" alt="">
<span>생산연도</span>
<p>{{ $dotFormatDate(findResult.prdctnYear) }}</p>
</dd>
<dd>
<img :src="categoryicon" alt="">
<span>카테고리</span>
<ul class="category">
<li v-for="(item, idx) of findResult.ctgrys" :key="idx" class="category">{{ item.ctgryNm }}</li>
</ul>
</dd>
</dl>
</form>
<div class="btn-group flex-center">
<button v-if="isRegister" class="red-line " type="button" @click="fnDelete">삭제</button>
<button v-if="isRegister" class="blue-line " type="button" @click="fnMoveTo('edit', pageId)">수정</button>
<button class="gray-line-bg " type="button" @click="fnMoveTo('list')">목록</button>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
// Import Swiper Vue components
import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
// Import Swiper styles
import 'swiper/css';
import 'swiper/css/free-mode';
import 'swiper/css/navigation';
import 'swiper/css/thumbs';
// import required modules
import { FreeMode, Navigation, Thumbs } from 'swiper/modules';
// COMPONENT
import ViewerComponent from '../../../component/editor/ViewerComponent.vue';
// API
import { findDcryProc, deleteDcryProc } from '@/resources/api/dcry';
import { fileDownloadProc, multiFileDownloadProc } from '@/resources/api/file';
export default {
components: {
PauseOutlined,
CaretRightOutlined,
Swiper,
SwiperSlide,
ViewerComponent,
},
setup() {
const thumbsSwiper = ref(null);
const setThumbsSwiper = (swiper) => {
thumbsSwiper.value = swiper;
};
return {
thumbsSwiper,
setThumbsSwiper,
modules: [FreeMode, Navigation, Thumbs],
};
},
data() {
return {
// ICON
calendaricon: 'client/resources/images/icon/calendaricon.png',
homeicon: 'client/resources/images/icon/home.png',
erroricon: 'client/resources/images/icon/error.png',
righticon: 'client/resources/images/icon/right.png',
addressicon: 'client/resources/images/icon/addressicon.png',
yearicon: 'client/resources/images/icon/yearicon.png',
categoryicon: 'client/resources/images/icon/categoryicon.png',
pageId: null,
findResult: {},
selectedFiles: [],
loading: false,
activeIndex: 0,
isRegister: false,
};
},
created() {
this.pageId = this.$route.query.id;
if (this.$isEmpty(this.pageId)) {
alert("게시물 존재하지 않습니다.");
this.fnMoveTo('list');
}
},
mounted() {
this.fnFindDcry(); // 상세 조회
},
methods: {
handleMainSlideChange(swiper) {
this.activeIndex = swiper.realIndex;
},
// 상세 조회
async fnFindDcry() {
try {
const response = await findDcryProc(this.pageId);
this.findResult = response.data.data.dcry;
if (this.findResult.ty !== 'P') {
alert('올바른 접근이 아닙니다.');
this.fnMoveTo('list'); // 목록으로 이동
}
this.isRegister = this.$registerChk(this.findResult.register);
} catch (error) {
alert('조회중 오류가 발생했습니다.');
this.fnMoveTo('list');
if (error.response) {
alert(error.response.data.message);
}
console.error(error.message);
}
},
// 파일 다운로드
async fnDownload(type) {
// Set loading to true when download starts
this.loading = true;
// 유효성 검사
if (type === 'selected') {
if (this.selectedFiles.length === 0) {
alert("파일을 1개 이상 선택하거나 전체 다운로드를 클릭해주세요.");
this.loading = false; // Hide loading if validation fails
return;
}
}
let url = null;
let link = null;
try {
let fileList;
if (type === 'selected') {
fileList = this.selectedFiles;
} else if (type === 'all') {
fileList = this.findResult.files;
}
let isMultiple = fileList.length > 1;
let files = isMultiple ? fileList : fileList[0];
// Call the API to get the file data
const response = isMultiple ? await multiFileDownloadProc(files) : await fileDownloadProc(files);
// 파일명 추출 부분 수정
let filename = isMultiple ? 'downloadFile.zip' : 'downloadFile.bin';
const disposition = response.headers['content-disposition'];
if (disposition && disposition.includes('filename=')) {
const filenameRegex = /filename=["']?([^"';\n]*)["']?/i;
const matches = disposition.match(filenameRegex);
if (matches && matches[1]) {
filename = decodeURIComponent(matches[1]);
}
}
// 파일 다운로드 처리
const blob = new Blob([response.data]);
const downloadUrl = window.URL.createObjectURL(blob);
const downloadLink = document.createElement('a');
downloadLink.href = downloadUrl;
downloadLink.setAttribute('download', filename);
document.body.appendChild(downloadLink);
downloadLink.click();
} catch (error) {
alert('파일 다운로드 중 오류가 발생했습니다.');
} finally {
// Hide loading spinner and clean up
setTimeout(() => {
this.loading = false; // Hide loading spinner
if (url) {
window.URL.revokeObjectURL(url);
}
if (link && link.parentNode) {
document.body.removeChild(link);
}
}, 100);
}
},
// 삭제
async fnDelete() {
let isCheck = confirm("해당 페이지를 삭제하시겠습니까?");
if (!isCheck) {
return;
}
try {
const response = await deleteDcryProc(this.pageId);
alert('해당 페이지를 삭제했습니다.');
this.fnMoveTo('list');
} catch (error) {
if (error.response) {
alert(error.response.data.message);
}
console.error(error.message);
}
},
// 페이지 이동
fnMoveTo(type, id) {
const routes = {
'list': { name: 'PicHistorySearch' },
'view': { name: 'PicHistoryDetail', query: { id } },
'edit': { name: 'PicHistoryInsert', query: this.$isEmpty(id) ? {} : { id } },
};
if (routes[type]) {
this.$router.push(routes[type]);
} else {
alert("올바르지 않은 경로를 요청하여 목록으로 이동합니다.");
this.$router.push(routes['list']);
}
},
},
};
</script>