
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="container" :style="isLoading ? { cursor: 'wait' } : {}">
<div v-if="isLoading" class="loading-overlay">
<div class="loading-div">
<span>LOADING </span>
<span class="anima">.</span>
<span class="anima">.</span>
<span class="anima">.</span>
</div>
</div>
<div class="page-titleZone flex justify-between align-center">
<p class="main-title flex80">파일 관리</p>
<PageNavigation />
</div>
<div class="content-wrap">
<div class="content-box flex justify-between">
<div class="flex20 content-box">
<div class="left-content flex100 content-box">
<div class="content-box">
<div class="mb10">
<div class="content-titleZone">
<p class="box-title">호스트 선택</p>
</div>
<div class="flex align-center justify-between no-gutter">
<div class="flex70">
<select name="" id="" class="only full-select" v-model="selectedHostCode">
<option :value="null" disabled>선택</option>
<option v-for="(host, idx) in hostList" :key="idx" :value="host.host_code">{{ host.host_nm + " - (" + host.host_ip + ")" }} </option>
</select>
</div>
<div class="flex25">
<button class="blue-btn large-btn" @click="connectionConfirm()">연결 </button>
</div>
</div>
</div>
<div class="file-tree-zone">
<div class="content-titleZone flex justify-between align-center">
<p class="box-title">폴더 리스트</p>
<button class="blue-border-btn small-btn" @click="openMkdirModal()">폴더추가 </button>
</div>
<div class="file-zone overflow-y">
<ul class="tree-wrap">
<TreeItem ref="treeItem" :connection="connection" :selectedNode="selectedNode" v-for="(item, idx) in nodes" :item="item" :idx="item.id" :key="idx" @selectFolder="selectFolder" @isLoading="handleIsLoading" @selectItem="handleSelectItem" />
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="flex80 content-box">
<div class="right-content flex100">
<div class="flex-column justify-between">
<div class="flex justify-between align-center no-gutter">
<div class="flex40">
<button class="blue-border-btn small-btn" @click="openTreeModal('copy')">선택복사</button>
<button class="blue-border-btn small-btn" @click="openTreeModal('move')">선택이동</button>
<button class="red-border-btn small-btn" @click="remove()">선택삭제</button>
</div>
<div class="flex justify-end flex60">
<div class="search-bar">
<div class="flex justify-end align-center">
<select name="" id="" class="square-select" v-model="searchType">
<option value="all">전체</option>
<option value="folder">현재폴더</option>
</select>
<div class="search-square">
<div class="flex justify-end align-center no-gutter">
<input type="text" class="square-input flex90" placeholder="Search File" v-model="searchText" @keyup.enter="searchFiles()" />
<button class="square-button blue-btn flex10">
<svg-icon type="mdi" :path="searchPath" class="square-icon" @click="searchFiles()"></svg-icon>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="content-zone" style="overflow-y: auto">
<div class="table-zone file-table">
<div class="list-info flex justify-between align-center">
<div class="count-zone">
<p>총 <span v-if="search.totalRows != 0">{{ search.totalRows }}</span>
<span v-else>0</span>건 중 <span>{{ selectedFiles.length }}</span>건 선택
</p>
<p>현재경로 : <span>{{ connection.path }}</span>
</p>
</div>
</div>
<table class="list-table">
<!-- col 꼭 너비 기재해야함! 그래야 100%로 차지함 -->
<colgroup>
<col style="width: 5%" />
<col style="width: 45%" />
<col style="width: 10%" />
<col style="width: 15%" />
<col style="width: 10%" />
<col style="width: 15%" />
</colgroup>
<thead>
<tr>
<th>
<input type="checkbox" @click="filesCheckAll" v-model="checkAll" />
</th>
<th>이름</th>
<th>타입</th>
<th>마지막 수정</th>
<th>크기</th>
<th>관리</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in fileList" :key="index" @click="selectFileList(file)">
<td v-if="file.text != '상위폴더로 이동'" @click.stop="">
<input type="checkbox" @click.stop="" v-model="selectedFiles" :value="{
folder: file.folder,
path: file.path,
fileName: file.text,
extension: file.extension,
}" name="files" />
</td>
<td v-else @click.stop=""></td>
<td>
<div class="text-lf">
<span v-if="file.extension === 'txt'"><img src="../../../resources/img/icon/txt.png" ref="" alt="" /></span>
<span v-else-if="file.extension === 'pdf'"><img src="../../../resources/img/icon/pdf.png" alt="" /></span>
<span v-else-if="file.extension === 'pptx' ||
file.extension === 'ppt'
"><img src="../../../resources/img/icon/ppt.png" alt="" /></span>
<span v-else-if="file.extension === 'hwp'"><img src="../../../resources/img/icon/hwp.png" alt="" /></span>
<span v-else-if="file.extension === 'xls' ||
file.extension === 'xlsx' || file.extension === 'csv'
"><img src="../../../resources/img/icon/xls.png" alt="" /></span>
<span v-else-if="file.extension === 'jpg'"><img src="../../../resources/img/icon/img.png" alt="" /></span>
<span v-else-if="file.extension === 'png'"><img src="../../../resources/img/icon/img.png" ref="" alt="" /></span>
<span>{{ " " + file.text }}</span>
</div>
</td>
<td>{{ file.extension }}</td>
<td>{{ file.lastUpdate }}</td>
<td v-if="file.size != 0">{{ $filters.bytesToSize(file.size) }} </td>
<td v-else></td>
<td>
<div v-if="!file.folder">
<button class="icon-btn orange-btn" title="미리보기" @click.stop="preview(file)">
<svg-icon type="mdi" :width="18" :height="18" :path="fileFindPath"></svg-icon>
</button>
<button class="icon-btn green-btn ml5" title="파일명 변경" @click.stop="openReNameModal(file)">
<svg-icon type="mdi" :width="18" :height="18" :path="fileNamePath"></svg-icon>
</button>
<button class="icon-btn blue-btn ml5" title="다운로드" @click.stop="download(file)">
<svg-icon type="mdi" :width="18" :height="18" :path="filedownPath"></svg-icon>
</button>
</div>
<div v-else-if="file.folder && file.text != '상위폴더로 이동'
">
<button class="icon-btn green-btn ml5" title="폴더명 변경" @click.stop="openReNameModal(file)">
<svg-icon type="mdi" :width="18" :height="18" :path="fileNamePath"></svg-icon>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="flex justify-end">
<button class="blue-btn small-btn" @click="setModal('typeSelected', 'small')">업로드 </button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 폴더 목록 모달 -->
<TreeModal :modalOpen="treeModalOpen" :modalConnection="modalConnection" :modalNodes="modalNodes" :selectType="selectModalType" @modalSelectFolder="modalSelectFolder" @closeTreeModal="closeTreeModal" @modalSubmit="fileConfirm" />
<!-- 데이터셋 미리보기 모달 -->
<div v-show="previewModalOpen" class="modal-wrapper" :style="isLoading ? { cursor: 'wait' } : {}">
<div v-if="isLoading" class="loading-overlay">
<div class="loading-div">
<span>LOADING </span>
<span class="anima">.</span>
<span class="anima">.</span>
<span class="anima">.</span>
</div>
</div>
<div class="modal-container list-modal">
<div class="modal-title">
<div class="flex justify-between align-center">
<h2>데이터 미리보기</h2>
<button class="close-btn" @click="previewModalClose()">X</button>
</div>
</div>
<div class="modal-content-monthly">
<FileDataRead v-if="previewModalOpen" v-model:isLoading="isLoading" :dataTable="dataTable" :preview="true">
</FileDataRead>
</div>
<div class="modal-end flex justify-end">
<button class="blue-btn small-btn" @click="previewModalClose()">확인 </button>
</div>
</div>
</div>
<!-- 폴더, 파일 이름변경 모달 -->
<div v-show="reNameModalOpen" class="modal-wrapper">
<div class="modal-container small-modal">
<div class="modal-title text-ct">
<h2>폴더(파일)명 변경</h2>
</div>
<div class="modal-content-monthly">
<div class="table-zone">
<table class="form-table2">
<!-- col 꼭 너비 기재해야함! 그래야 100%로 차지함 -->
<colgroup>
<col style="width: 25%" />
<col style="width: 75%" />
</colgroup>
<tbody>
<tr>
<th>현재 이름</th>
<td>{{ reNameObject.currentName }}</td>
</tr>
<tr>
<th>변경 이름</th>
<td>
<input type="text" class="full-input" v-model="reNameObject.changeName" @keyup.enter="rename()" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-end flex justify-between" style="flex-wrap: nowrap;">
<button class="gray-btn large-btn" @click="closeReNameModal()">취소 </button>
<button class="blue-btn large-btn" @click="rename()">확인</button>
</div>
</div>
</div>
<!-- 폴더추가 모달 -->
<div v-show="mkdirModalOpen" class="modal-wrapper">
<div class="modal-container small-modal">
<div class="modal-title text-ct">
<h2>폴더 추가</h2>
</div>
<div class="modal-content-monthly">
<div class="table-zone">
<table class="form-table2">
<!-- col 꼭 너비 기재해야함! 그래야 100%로 차지함 -->
<colgroup>
<col style="width: 25%" />
<col style="width: 75%" />
</colgroup>
<tbody>
<tr>
<th>현재경로</th>
<td>{{ connection.path }}</td>
</tr>
<tr>
<th>폴더명</th>
<td>
<input type="text" class="full-input" v-model="folderName" @keyup.enter="mkdir()" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-end flex justify-between" style="flex-wrap: nowrap;">
<button class="blue-btn large-btn" @click="mkdir()">확인</button>
<button class="gray-btn large-btn" @click="closeMkdirModal()">취소 </button>
</div>
</div>
</div>
<!-- 모달 -->
<div v-show="isModalOpen" class="modal-wrapper">
<div :class="{
'modal-container': true,
'small-modal': modalSize === 'small',
'large-modal': modalSize === 'large',
}">
<div class="modal-title text-ct" v-show="modalType === 'typeSelected'">
<div class="flex justify-between align-center">
<h2>업로드</h2>
<button class="close-btn" @click="closeModal">
<svg-icon type="mdi" :width="20" :height="20" :path="closePath"></svg-icon>
</button>
</div>
</div>
<!-- 업로드 타입 선택 -->
<div class="modal-content-monthly" v-show="modalType === 'typeSelected'">
<div class="flex justify-center align-center mb10">
<div class="flex50 pl0">
<button class="blue-border-btn large-btn" @click="setModal('file-modal', 'small')">파일</button>
</div>
<div class="flex50 pr0">
<button class="blue-border-btn large-btn" @click="setModal('db-modal', 'middle')">DB</button>
</div>
</div>
<div class="flex justify-center align-center">
<div class="flex50 pl0">
<button class="blue-border-btn large-btn" @click="setModal('api-modal', 'middle')">API</button>
</div>
<div class="flex50 pr0">
<button class="blue-border-btn large-btn" @click="setModal('ehojo-modal', 'middle')">차세대 API</button>
</div>
</div>
</div>
<!-- 파일 (file-modal) -->
<template v-if="modalType == 'file-modal'">
<div class="modal-title">
<div class="flex justify-between align-center">
<h2>파일 등록</h2>
<button class="close-btn" @click="closeModal">X</button>
</div>
</div>
<div class="modal-content-monthly">
<div class="table-zone">
<table class="form-table">
<colgroup>
<col style="width: 15%" />
<col style="width: 85%" />
</colgroup>
<tbody>
<tr>
<th>현재경로</th>
<td>{{ connection.path }}</td>
</tr>
<tr>
<th>파일명</th>
<td>
<input type="file" name="file" id="file" ref="fileInput" @change="fileInput()" />
</td>
</tr>
</tbody>
</table>
<div class="modal-end flex justify-between" style="flex-wrap: nowrap;">
<button class="blue-btn large-btn" @click="upload()">확인</button>
<button class="gray-btn large-btn" @click="closeModal()">취소</button>
</div>
</div>
</div>
</template>
<!-- DB (db-modal) -->
<DatabaseConnection v-if="modalType == 'db-modal'" openPopup="true" :jobItem="selectNode" @closePopup="closeModal" @saveNodeData="fnUpdateSetup" />
<!-- API (api-modal) -->
<apiConnection v-if="modalType == 'api-modal'" openPopup="true" :jobItem="selectNode" @fnCloseModal="closeModal" @fnSaveSetup="fnUpdateSetup" />
<!-- 차세대 API (ehojo-modal) -->
<EhojoConnection v-if="modalType == 'ehojo-modal'" openPopup="true" :jobItem="selectNode" @fnCloseModal="closeModal" @fnSaveSetup="fnUpdateSetup" />
<div class="modal-end flex justify-end" v-show="modalType == 'test-modal'" style="flex-wrap: nowrap;">
<button class="gray-border-btn small-btn" @click="closeModal">이전 </button>
<button class="blue-border-btn small-btn" @click="closeModal">확인 </button>
<button class="darkg-border-btn small-btn" @click="closeModal">닫기 </button>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import PageNavigation from "../../component/PageNavigation.vue";
import PaginationButton from "../../component/PaginationButton.vue";
import TreeItem from "../../component/FileTree.vue";
import TreeModal from "../../component/FileTreeModal.vue";
import SvgIcon from "@jamescoyle/vue-icon";
import DatabaseConnection from "../../component/connection/itm/databaseConnection.vue";
import apiConnection from "../../component/connection/itm/apiConnection.vue";
import EhojoConnection from "../../component/connection/EhojoConnection.vue";
import {
mdiMagnify,
mdiClose,
mdiFileCog,
mdiDownload,
mdiFileFind,
} from "@mdi/js";
import store from "../AppStore";
import FileDataRead from "../../component/connection/itm/fileDataRead.vue";
import * as XLSX from "xlsx";
export default {
data() {
return {
// 검색 객체
search: this.$getDefaultSerchVO(),
search_data: this.$getDefaultSerchItem(null, "String"),
searchPath: mdiMagnify,
closePath: mdiClose,
fileNamePath: mdiFileCog,
filedownPath: mdiDownload,
fileFindPath: mdiFileFind,
isModalOpen: false,
activeTab: "tab1",
modalType: "",
modalSize: "small",
mkdirModalOpen: false,
reNameModalOpen: false,
treeModalOpen: false,
selectedHost: {},
selectedHostCode: null,
// 호스트 목록
hostList: [],
// 부서-호스트 목록
deptHostList: [],
connection: {
host_code: null,
path: null,
depth: null,
type: null,
},
uploadObject: {
host_code: null,
path: null,
uploadFile: null,
confirm: false,
},
nodes: [],
fileList: [],
selectedNode: null,
folderName: null,
uploadFile: null,
reNameObject: {
currentPath: null,
parentPath: null,
currentName: null,
extension: null,
changeName: null,
},
checkAll: false,
selectedFiles: [],
modalNodes: [],
modalConnection: {
host_code: null,
path: null,
depth: null,
type: null,
},
modalSeletedNode: null,
selectModalType: 0,
searchType: "all",
searchText: null,
selectItem: null,
// 데이터 미리보기
isLoading: false,
previewModalOpen: false,
dataTable: {},
selectNode: {}, // 선택된 노드
};
},
methods: {
// 검색 객체 초기화
searchInit: function () {
this.search.searchObjectList.push(this.search_data);
},
searchFiles() {
const vm = this;
if (vm.searchText === null || vm.searchText === "") {
vm.$showAlert("파일 검색", "검색어를 입력해 주세요.");
return;
}
let path = vm.connection.path;
if (vm.searchType === "all") {
path = "#";
} else {
if (!path) {
vm.$showAlert("파일 검색", "폴더를 선택해 주세요.");
return;
}
}
vm.isLoading = true; // 로딩 시작
axios({
url: "/files/search/" + vm.connection.host_code,
method: "post",
headers: {},
data: {
searchType: vm.searchType,
searchText: vm.searchText,
path: path,
},
})
.then(function (response) {
vm.isLoading = false; // 로딩 해제
vm.fileList = response.data.resultData.fileList;
if (vm.fileList.length == 0) {
vm.$showAlert("파일 검색", "검색 결과가 없습니다.");
}
})
.catch(function (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"파일 검색",
"파일 검색 오류, 관리자에게 문의바랍니다."
);
});
},
// 로딩 상태 변경
handleIsLoading(isLoadingValue) {
this.isLoading = isLoadingValue; // 부모 컴포넌트의 데이터 업데이트
},
// 탭 변경
showTab: function (tabName) {
this.activeTab = tabName;
},
openModal: function () {
this.isModalOpen = true;
},
closeModal: function () {
this.selectNode = {}; // 초기화
this.modalType = null;
this.isModalOpen = false;
},
setModal: function (type, size) {
if (type == "typeSelected") {
if (this.connection.path == null || this.connection.path == "" || this.connection.path === undefined) {
this.$showAlert("폴더 추가", "폴더를 선택해 주세요.");
return;
}
} else if (type == "db-modal") {
this.fnCreateNode("DB_READ");
} else if (type == "api-modal") {
this.fnCreateNode("API_READ");
} else if (type == "ehojo-modal") {
this.fnCreateNode("EHOJO_READ");
}
this.modalType = type;
this.modalSize = size;
},
openMkdirModal() {
if (this.connection.path == null || this.connection.path == "" || this.connection.path === undefined) {
this.$showAlert("폴더 추가", "폴더를 선택해 주세요.");
return;
}
this.mkdirModalOpen = true;
},
closeMkdirModal() {
this.mkdirModalOpen = false;
},
openTreeModal(type) {
if (this.selectedFiles.length === 0) {
if (type === "move") {
this.$showAlert("파일 이동", "선택한 파일이 없습니다.");
} else if (type === "copy") {
this.$showAlert("파일 복사", "선택한 파일이 없습니다.");
}
return;
}
this.treeModalOpen = true;
this.selectModalType = type;
},
closeTreeModal() {
// this.modalNodes = [];
this.treeModalOpen = false;
this.modalSeletedNode = null;
},
openReNameModal(file) {
this.reNameObject.currentPath = file.path;
this.reNameObject.parentPath = file.parent;
this.reNameObject.currentName = file.text;
this.reNameObject.extension = file.extension;
this.reNameModalOpen = true;
},
closeReNameModal() {
this.reNameObject.changeName = null;
this.reNameModalOpen = false;
},
filesCheckAll() {
this.checkAll = !this.checkAll;
if (this.checkAll) {
this.fileList.forEach((file) => {
if (file.text != "상위폴더로 이동") {
this.selectedFiles.push({
folder: file.folder,
path: file.path,
fileName: file.text,
extension: file.extension,
});
}
});
} else {
this.selectedFiles = [];
}
},
// 선택한 호스트 연결
async connectionConfirm() {
const vm = this;
if (vm.selectedHostCode === null || vm.selectedHostCode === undefined) {
vm.$showAlert("파일시스템 연결", "호스트를 선택해 주세요.");
return;
}
// 이전에 선택한 호스트 코드가 있으면 저장
let tempHostCode = null;
let tempModalHostCode = null;
if (vm.connection.host_code) {
tempHostCode = _.cloneDeep(vm.connection.host_code);
tempModalHostCode = _.cloneDeep(vm.modalConnection.host_code);
}
vm.connection.host_code = vm.selectedHost.host_code;
vm.modalConnection.host_code = vm.selectedHost.host_code;
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.get("/files/connection", {
params: { host_code: vm.connection.host_code },
});
vm.isLoading = false; // 로딩 해제
if (response.data.status === 200) {
await this.fileTreeList();
} else {
// 이전에 선택한 호스트 코드로 변경
if (tempHostCode) {
vm.connection.host_code = tempHostCode;
vm.selectedHost.host_code = tempHostCode;
vm.selectedHostCode = tempHostCode;
}
}
this.selectedFiles = [];
this.checkAll = false;
vm.$showAlert("파일시스템 연결", response.data.message);
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"파일시스템 연결",
"파일시스템 연결 오류, 관리자에게 문의하세요."
);
this.selectedFiles = [];
this.checkAll = false;
// 이전에 선택한 호스트 코드로 변경
if (tempHostCode) {
vm.connection.host_code = tempHostCode;
vm.selectedHost.host_code = tempHostCode;
vm.selectedHostCode = tempHostCode;
}
}
},
// 호스트 목록 조회
selectHosts() {
const vm = this;
vm.isLoading = true; // 로딩 시작
axios({
url: "/files/hosts",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: {
userId: store.state.loginUser.user_id,
authList: store.state.loginUser.user_auth,
author: store.state.loginUser.user_auth[0],
dept_code: store.state.loginUser.dept_code,
},
})
.then((response) => {
vm.hostList = response.data.resultData.hostList;
vm.deptHostList = response.data.resultData.deptHostList;
// this.connection.host_code = this.hostList[this.hostList.length - 1].host_code
if (this.hostList.length > 0) {
vm.selectedHost = vm.hostList[0];
vm.selectedHostCode = vm.hostList[0].host_code;
for (let i = 0; i < vm.hostList.length; i++) {
for (let j = 0; j < vm.deptHostList.length; j++) {
if (vm.hostList[i].host_code === vm.deptHostList[j].host_code) {
vm.hostList[i].main_folder_path =
vm.deptHostList[j].main_folder_path;
}
}
}
vm.connectionConfirm();
} else {
vm.isLoading = false; // 로딩 해제
vm.selectedHost = {};
}
})
.catch((error) => {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"호스트 조회",
"호스트 조회 오류, 관리자에게 문의하세요."
);
});
},
// 폴더 리스트 조회
async fileTreeList() {
const vm = this;
vm.nodes = [];
vm.connection.path = vm.selectedHost.main_folder_path;
vm.connection.depth = 0;
vm.connection.type = "folder";
vm.modalNodes = [];
vm.modalConnection.path = vm.selectedHost.main_folder_path;
vm.modalConnection.depth = 0;
vm.modalConnection.type = "folder";
vm.modalConnection.host_code = vm.connection.host_code;
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.get("/files/tree", {
params: vm.connection,
});
vm.nodes = response.data.resultData.fileTree;
vm.modalNodes = response.data.resultData.fileTree;
vm.connection.path = null;
vm.fileList = [];
this.checkAll = false;
vm.isLoading = false; // 로딩 해제
} catch (error) {
vm.connection.path = null;
vm.fileList = [];
this.checkAll = false;
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"파일리스트 조회",
"파일리스트 조회 오류, 관리자에게 문의하세요."
);
}
},
modalFileTreeList() {
const vm = this;
vm.modalNodes = [];
vm.modalConnection.host_code = vm.connection.host_code;
vm.modalConnection.path = "#";
vm.modalConnection.depth = 0;
vm.modalConnection.type = "folder";
axios
.get("/files/tree", { params: vm.modalConnection })
.then((response) => {
vm.modalNodes = response.data.resultData.fileTree;
})
.catch((error) => {
vm.$showAlert(
"파일리스트 조회",
"파일리스트 조회 오류, 관리자에게 문의하세요."
);
});
},
selectFolder(path) {
if (path === null || path === undefined) {
this.isLoading = false;
}
this.connection.path = path;
this.fileSelectList();
},
handleSelectItem(item) {
this.selectItem = item;
},
modalSelectFolder(path) {
this.modalSeletedNode = path;
},
selectFileList(item) {
// 폴더가 선택된 경우, 선택된 노드와 경로를 업데이트하고 파일 리스트 조회
if (item.extension === "폴더" || item.extension === "") {
this.selectedNode = item.id;
this.connection.path = item.id;
this.fileSelectList();
} else {
}
},
// 파일 리스트 조회
async fileSelectList() {
const vm = this;
if (vm.connection.path === null || vm.connection.path === "") {
vm.fileList = null;
return;
}
vm.connection.type = "all";
vm.connection.depth = 1;
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.get("/files/list", {
params: vm.connection,
});
vm.fileList = response.data.resultData.fileList;
vm.search.totalRows = response.data.resultData.totalRow;
vm.selectedFiles = [];
vm.checkAll = false;
vm.isLoading = false; // 로딩 해제
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"파일리스트 조회",
"파일리스트 조회 오류, 관리자에게 문의하세요."
);
vm.selectedFiles = [];
vm.checkAll = false;
}
},
// 폴더 추가
async mkdir() {
const vm = this;
if (vm.connection.path === null || vm.connection.path === "") {
vm.$showAlert(
"폴더 추가",
"선택된 경로가 없습니다.\n 경로 선택 후 다시 시도해주세요."
);
vm.closeMkdirModal();
vm.folderName = null;
return;
}
const mkdirVO = {};
mkdirVO.host_code = vm.connection.host_code;
mkdirVO.path = vm.connection.path;
mkdirVO.folderName = vm.folderName;
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.post("/files/mkdir", mkdirVO);
vm.isLoading = false; // 로딩 해제
vm.getChildren(vm.selectItem.id, vm.selectItem.children); // 자식 폴더 리스트 업데이트
await vm.fileSelectList();
vm.$showAlert("폴더 추가", response.data.message);
vm.closeMkdirModal();
vm.folderName = null;
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert("폴더 추가", "폴더 추가 오류, 관리자에게 문의하세요.");
vm.folderName = null;
}
},
// 자식 파일 정보 조회
getChildren(path, children) {
const vm = this;
vm.connection.path = path;
vm.connection.type = "folder";
vm.connection.depth = 1;
axios
.get("/files/list", { params: vm.connection })
.then((response) => {
let childrenList = response.data.resultData.fileList;
// 기존 배열 초기화
children.length = 0;
// 새로운 배열의 요소들을 기존 배열에 추가
Array.prototype.push.apply(children, childrenList);
})
.catch((error) => { });
},
//파일업로드
fileInput() {
this.uploadFile = this.$refs.fileInput.files[0];
},
async upload() {
const vm = this;
vm.uploadObject.path = vm.connection.path;
vm.uploadObject.host_code = vm.connection.host_code;
vm.uploadObject.uploadFile = vm.uploadFile;
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.post("/files/upload", vm.uploadObject, {
headers: {
"Content-Type": "multipart/form-data",
},
});
vm.isLoading = false; // 로딩 종료
if (response.data.status === 200) {
document.getElementById("file").value = "";
await vm.fileSelectList();
vm.$showAlert("파일 업로드", response.data.message);
} else if (response.data.status === 100) {
if (!(await vm.$showConfirm("파일 업로드", response.data.message))) {
document.getElementById("file").value = "";
return;
} else {
vm.uploadObject.confirm = true;
await vm.reUpload();
}
}
vm.closeModal();
} catch (error) {
vm.isLoading = false; // 로딩 종료
vm.$showAlert(
"파일 업로드",
"파일 업로드 오류, 관리자에게 문의하세요."
);
vm.uploadObject.confirm = false;
document.getElementById("file").value = "";
}
},
async reUpload() {
const vm = this;
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.post("/files/upload", vm.uploadObject, {
headers: {
"Content-Type": "multipart/form-data",
},
});
vm.isLoading = false; // 로딩 종료
await vm.fileSelectList();
vm.$showAlert("파일 업로드", response.data.message);
vm.uploadObject.confirm = false;
document.getElementById("file").value = "";
} catch (error) {
vm.isLoading = false; // 로딩 종료
vm.$showAlert(
"파일 업로드",
"파일 업로드 오류, 관리자에게 문의하세요."
);
vm.uploadObject.confirm = false;
document.getElementById("file").value = "";
}
},
download(file) {
const vm = this;
vm.isLoading = true; // 로딩 시작
axios
.post("/files/download", {
host_code: vm.connection.host_code,
path: file.parent,
fileName: file.text,
})
.then((response) => {
vm.isLoading = false; // 로딩 해제
vm.$showAlert("파일 다운로드", response.data.message);
})
.catch((error) => {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"파일 다운로드",
"파일 다운로드 오류, 관리자에게 문의하세요."
);
});
},
async rename() {
const vm = this;
if (vm.reNameObject.changeName === null) {
vm.$showAlert("이름 바꾸기", "변경할 이름을 입력해주세요.");
return;
}
let fullName =
vm.reNameObject.changeName + "." + vm.reNameObject.extension;
if (vm.reNameObject.extension === "폴더") {
fullName = vm.reNameObject.changeName;
}
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.put("/files/rename", {
host_code: vm.connection.host_code,
currentPath: vm.reNameObject.currentPath,
changePath: vm.reNameObject.parentPath + "/" + fullName,
});
vm.isLoading = false; // 로딩 해제
vm.reNameObject.changeName = null;
await vm.fileSelectList();
vm.$showAlert("이름 바꾸기", response.data.message);
vm.closeReNameModal();
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"이름 바꾸기",
"이름 바꾸기 오류, 관리자에게 문의하세요."
);
vm.closeReNameModal();
vm.reNameObject.changeName = null;
}
},
async remove() {
const vm = this;
if (vm.selectedFiles.length === 0) {
vm.$showAlert("파일 삭제", "선택한 파일이 없습니다.");
return;
}
if (
!(await vm.$showConfirm("파일 삭제", "선택한 파일을 삭제하시겠습니까?"))
) {
return;
}
vm.selectedFiles.forEach((file) => {
delete file.fileName;
delete file.extension;
});
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.delete(
`/files/${vm.connection.host_code}`,
{ data: vm.selectedFiles }
);
vm.isLoading = false;
vm.getChildren(vm.selectItem.id, vm.selectItem.children); // 자식 폴더 리스트 업데이트
await vm.fileSelectList();
vm.$showAlert("파일 삭제", response.data.message);
vm.checkAll = false;
vm.selectedFiles = [];
} catch (error) {
vm.isLoading = false;
vm.$showAlert("파일 삭제", "파일 삭제 오류, 관리자에게 문의하세요.");
vm.checkAll = false;
vm.selectedFiles = [];
}
},
async fileConfirm(type) {
const vm = this;
if (
!(await vm.$showConfirm(
"파일 " + type,
"선택한 파일을 " + type + " 하시겠습니까?"
))
) {
return;
}
let file = vm.selectedFiles[0];
let index = file.path.lastIndexOf("/");
if (file.path.substring(0, index) === file.movePath) {
vm.$showAlert(
"파일 " + type,
"현재 파일 경로와 동일합니다. 다른 경로를 선택해주세요."
);
return;
}
if (type === "복사") {
vm.copy(vm.selectedFiles, "confirm", false);
} else {
vm.move(vm.selectedFiles, [], "confirm", false);
}
},
async move(fileList, removeFolderList, type, check) {
const vm = this;
fileList.forEach((file) => {
if (!file.movePath) {
file.movePath = vm.modalSeletedNode;
}
});
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.put(
"/files/move/" + vm.connection.host_code,
{
fileList: fileList,
removeFolder: removeFolderList,
type: type,
check: check,
}
);
vm.isLoading = false; // 로딩 해제
if (response.data.checkMessage.status === 100) {
let returnFileList = response.data.resultData.fileList;
let folderList = response.data.resultData.removeFolderList;
const moveOrCopy = await vm.$showRadioConfirm(
"파일 이동",
response.data.checkMessage.message
);
vm.move(
returnFileList,
folderList,
moveOrCopy.type,
moveOrCopy.checkBox
);
} else {
let folderList = response.data.resultData.removeFolderList;
vm.checkAll = false;
vm.selectedFiles = [];
if (folderList.length != 0) {
vm.removeFolder(folderList);
} else {
await vm.fileSelectList();
}
vm.$showAlert("파일 이동", response.data.checkMessage.message);
vm.closeTreeModal();
}
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert("파일 이동", "파일 이동 오류, 관리자에게 문의하세요.");
vm.checkAll = false;
vm.selectedFiles = [];
vm.closeTreeModal();
}
},
async copy(fileList, type, check) {
const vm = this;
fileList.forEach((file) => {
if (!file.movePath) {
file.movePath = vm.modalSeletedNode;
}
});
vm.isLoading = true; // 로딩 시작
try {
const response = await axios.put(
"/files/copy/" + vm.connection.host_code,
{ fileList: fileList, type: type, check: check }
);
vm.isLoading = false; // 로딩 해제
if (response.data.checkMessage.status === 100) {
let returnFileList = response.data.resultData.fileList;
const moveOrCopy = await vm.$showRadioConfirm(
"파일 복사",
response.data.checkMessage.message
);
vm.copy(returnFileList, moveOrCopy.type, moveOrCopy.checkBox);
} else {
vm.$showAlert("파일 복사", response.data.checkMessage.message);
vm.checkAll = false;
vm.selectedFiles = [];
vm.closeTreeModal();
}
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert("파일 복사", "파일 이동 오류, 관리자에게 문의하세요.");
vm.checkAll = false;
vm.selectedFiles = [];
vm.closeTreeModal();
}
},
async removeFolder(folderList) {
const vm = this;
vm.isLoading = false; // 로딩 해제
try {
const response = await axios.delete(
"/files/folder/" + vm.connection.host_code,
{ data: folderList }
);
vm.isLoading = false; // 로딩 해제
vm.getChildren(vm.selectItem.id, vm.selectItem.children); // 자식 폴더 리스트 업데이트
await vm.fileSelectList();
if (response.data.status === 500) {
vm.$showAlert("파일 이동", response.data.message);
}
} catch (error) {
vm.isLoading = false; // 로딩 해제
vm.$showAlert(
"파일 이동",
"원본 폴더 삭제 오류, 관리자에게 문의하세요."
);
}
},
// 미리보기 모달 닫기
previewModalClose() {
this.previewModalOpen = false;
this.dataTable = {};
},
// 파일 미리보기
preview(file) {
if (
file.extension != "xlsx" &&
file.extension != "xls" &&
file.extension != "csv"
) {
this.$showAlert("파일 미리보기", "엑셀 파일만 읽을 수 있습니다.");
return;
}
this.previewModalOpen = true;
this.fileRead(file);
},
// 파일 미리보기 - 읽기
async fileRead(file) {
const vm = this;
vm.isLoading = true;
axios
.post("/files/read/" + vm.connection.host_code, {
path: file.path,
fileName: file.text,
extension: file.extension,
type: "file",
datasetId: "",
viewMode: true,
})
.then((response) => {
vm.dataTable = response.data.resultData.dataTableMap;
})
.catch(() => {
vm.isLoading = false;
});
},
// 노드 설정 저장 후 닫기
fnUpdateSetup(jobItem) {
if (!jobItem.dataTable.rowData || jobItem.dataTable.rowData.length === 0) {
// rowData가 null이거나 빈 리스트일 때 실행할 코드
this.$showAlert("엑셀 생성 실패", "저장된 데이터가 없습니다.");
} else {
this.selectNode = jobItem;
this.exportToCSV();
this.closeModal(); // 괄호 추가
}
},
async exportToCSV() {
const vm = this;
// 컬럼 헤더 생성
const header = this.selectNode.dataTable.columnDatas.map(col => col.displyColumnNm);
// 데이터 준비 (rowData를 객체로 변환)
const data = this.selectNode.dataTable.rowData.map(row => {
const rowObject = {};
this.selectNode.dataTable.columnDatas.forEach((col, index) => {
rowObject[col.displyColumnNm] = row[index]; // displyColumnNm을 키로 사용
});
return rowObject;
});
// CSV 데이터 생성
const csvContent = [
header.join(","), // 헤더 추가
...data.map(row => header.map(col => row[col]).join(",")) // 각 행을 CSV 형식으로 변환
].join("\n");
// Blob으로 생성
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
// 파일 이름 설정
let fileName = vm.selectNode.node_type + '_' + vm.$getFullFileTime(new Date) + '.csv';
// 서버에 업로드
const formData = new FormData();
formData.append("uploadFile", blob, fileName); // 파일 이름을 지정해 줍니다.
formData.append("path", this.connection.path);
formData.append("host_code", this.connection.host_code);
try {
const response = await axios.post("/files/formDataUpload", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
vm.$showAlert("업로드", response.data.message);
vm.fileSelectList();
} catch (error) {
vm.$showAlert(
"업로드",
"업로드 오류, 관리자에게 문의하세요."
);
}
},
// 노드 생성
fnCreateNode(type) {
let node = Object.assign({}, this.$getDefaultJobGroup().node);
node.id = Math.floor(Math.random() * 1000) + 1;
node.node_id = node.id;
node.label = type;
node.node_name = type;
node.node_type = type;
node.position = {
x: Math.floor(Math.random() * 500) + 1,
y: Math.floor(Math.random() * 500) + 1,
};
let tempData = JSON.parse(JSON.stringify(node));
tempData.data = null;
node.data = tempData;
switch (type) {
case "DB_READ":
node.itm = Object.assign({}, this.$getDefaultJobGroup().connectionDb);
node.itm.type = "dbConnection";
break;
case "API_READ":
node.itm = Object.assign({}, this.$getDefaultJobGroup().connectionApi);
break;
case "EHOJO_READ":
node.itm = Object.assign({}, this.$getDefaultJobGroup().connectionEhojo);
break;
}
this.selectNode = node;
},
},
watch: {
// 모달타입에 맞는 모달창 화면 보여주기
modalType: function (newValue, oldValue) {
if (this.modalType != null) {
this.openModal(newValue);
}
},
selectedHostCode: function (newValue, oldValue) {
for (let i = 0; i < this.hostList.length; i++) {
if (this.hostList[i].host_code === newValue) {
this.selectedHost = this.hostList[i];
break;
}
}
},
},
components: {
PageNavigation: PageNavigation,
SvgIcon: SvgIcon,
PaginationButton: PaginationButton,
TreeItem: TreeItem,
TreeModal: TreeModal,
FileDataRead: FileDataRead,
DatabaseConnection: DatabaseConnection,
apiConnection: apiConnection,
XLSX: XLSX,
EhojoConnection: EhojoConnection,
},
mounted() {
this.selectHosts();
this.searchInit();
},
};
</script>