
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">OpenAPI 상세보기</p>
<PageNavigation />
</div>
<div class="content-wrap">
<div class="content content-box flex100">
<div>
<div class="flex justify-start align-center mb20">
<p class="box-title">{{ apiInfo.export_ttl }}</p>
<button class="small-btn blue-border-btn"> {{ apiInfo.api_type }} </button>
<button v-if="apiInfo.data_format_type != null" class="small-btn blue-border-btn"> {{ apiInfo.data_format_type }} </button>
</div>
</div>
<div class="mb30">
<div class="content-titleZone2">
<p class="box-title pl10">OPEN API</p>
</div>
<div class="table-zone">
<table class="form-table">
<colgroup>
<col width="15%" />
<col width="35%" />
<col width="15%" />
<col width="35%" />
</colgroup>
<tbody>
<tr>
<th colspan="4">{{ apiInfo.export_ttl }}</th>
</tr>
<tr>
<th>OPEN API 국문명</th>
<td>{{ apiInfo.export_kor_nm }}</td>
<th>OPEN API 영문명</th>
<td>{{ apiInfo.export_kor_nm }}</td>
</tr>
<tr>
<th>공공데이터포털 사용 유무</th>
<td>{{ apiInfo.public_potal_is_use ? "사용" : "미사용" }}</td>
<th>데이터 사용유무</th>
<td>{{ apiInfo.data_is_use ? "사용" : "미사용" }}</td>
</tr>
<tr>
<th>API 유형</th>
<td>{{ apiInfo.api_type }}</td>
<th>데이터 포맷</th>
<td> {{ apiInfo.data_format_type ? apiInfo.data_format_type : "-" }} </td>
</tr>
<tr>
<th>등록일</th>
<td>{{ apiInfo.export_creat_dt }}</td>
<th>수정일</th>
<td> {{ apiInfo.export_mdfcn_dt ? apiInfo.export_mdfcn_dt : "-" }} </td>
</tr>
<tr>
<th>검색키워드</th>
<td>{{ apiInfo.keyword }}</td>
<th>첨부파일</th>
<td v-if="apiInfo.file_manager_id">
<ul>
<li v-for="(file, i) in fileList" :key="i">
<span>{{ file.name }}</span>
<button @click="downloadFile(file)" class="green-border-btn small-btn"> 파일 다운로드 </button>
</li>
</ul>
</td>
<td v-else>등록된 첨부파일이 없습니다.</td>
</tr>
<tr>
<th>공공데이터포털 URL</th>
<td colspan="3">등록된 URL이 없습니다.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="tabs">
<ul class="tabnav">
<li v-for="(tab, index) in apiInfo.apiExportList" :key="index" @click="clickTab(index)" :class="{ active: selectApiData.index == index + 1 }"> {{ tab.api_detail_kor_nm }} </li>
</ul>
</div>
<div class="mb30">
<div class="content-titleZone2">
<p class="box-title pl10">API 상세</p>
</div>
<div class="table-zone">
<table class="form-table">
<colgroup>
<col width="15%" />
<col width="35%" />
<col width="15%" />
<col width="35%" />
</colgroup>
<tbody>
<tr>
<th colspan="4"></th>
</tr>
<tr>
<th>OPEN API 상세 국문명</th>
<td>{{ selectApiData.api_detail_kor_nm }}</td>
<th>OPEN API 상세 영문명</th>
<td>{{ selectApiData.api_detail_eng_nm }}</td>
</tr>
<tr>
<th>데이터명</th>
<td> {{ selectApiData.datasetPost.post_sj }} <button @click="moveDataset" class="blue-btn small-btn"> 상세조회 </button>
</td>
<th>상태</th>
<td>서비스가능</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="mb30">
<div class="content-titleZone2">
<p class="box-title pl10">데이터 요청 url</p>
</div>
<div class="pd10 overflow-y" style="background-color: #f8f8f8">
<p class="detail-text mb5">
<span class="detail-bold">OPEN API URL - </span> {{ systemURL }}/export/openapi/{{ selectApiData.datasetPost.dataset_post_id }}/{{ dataTable.datasetId }}/{{ selectApiData.export_id }}/getData <button class="small-btn blue-border-btn" @click="copyUrl2"> url복사 </button>
</p>
<p class="detail-text mb5">
<span class="detail-bold">데이터 요청 메소드 - </span>GET, POST
</p>
</div>
</div>
<div class="mb30">
<div class="content-titleZone2">
<p class="box-title pl10">데이터 요청 변수</p>
</div>
<div class="table-zone" style="max-height: 380px; overflow-y: scroll">
<table class="form-table">
<colgroup>
<col width="14%" />
<col width="15%" />
<col width="15%" />
<col width="14%" />
<col width="14%" />
<col width="14%" />
<col width="14%" />
</colgroup>
<thead>
<tr>
<th>index</th>
<th>항목명(국문)</th>
<th>항목명(영문)</th>
<th>데이터 타입</th>
<th>데이터 크기</th>
<th>필수여부</th>
<th>기본요청값</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, idx) in defaultRequestParamList" :key="idx">
<td>{{ idx + 1 }}</td>
<td>{{ item.displayColumnName }}</td>
<td>{{ item.columnName }}</td>
<td>{{ dataTypeList[item.dataType] }}</td>
<td>{{ item.size }}</td>
<td>{{ item.isOption }}</td>
<td>{{ item.defaultValue }}</td>
</tr>
<tr v-for="(item, idx) in dataTable.columnDatas" :key="idx">
<td>{{ idx + defaultRequestParamList.length + 1 }}</td>
<td>{{ item.displyColumnNm }}</td>
<td>{{ item.columnNm }}</td>
<td>{{ dataTypeList[item.dataTy] }}</td>
<td>{{ item.dataSize }}</td>
<td>옵션</td>
<td>NULL</td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<div class="content-titleZone2">
<div class="flex align-center">
<p class="box-title pl10">데이터 출력과 결과</p>
<button class="small-btn blue-border-btn" @click="showDataPost"> 데이터 미리보기 </button>
<button class="small-btn darkg-border-btn" @click="urlPreview"> url요청 미리보기 </button>
</div>
</div>
<div v-if="!showDataview" class="pd10 overflow-y" style="background-color: #f8f8f8">
<p class="detail-text mb5"> 데이터 미리보기를 클릭하면 결과를 미리 확인할 수 있습니다. </p>
</div>
<div v-else class="overflow-y overflow-x mb20">
<div class="table-zone">
<table class="list-table">
<thead>
<th v-for="(itm, indx) in dataTable.columnDatas" :key="indx"> {{ itm.columnNm }} </th>
</thead>
<tbody>
<tr v-for="(row, rows) in dataTable.rowData" :key="rows">
<td v-for="(itm, indx) in row" :key="indx" style="
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
"> {{ itm }} </td>
</tr>
</tbody>
</table>
<PaginationButton v-model:currentPage="postSearch.currentPage" :perPage="postSearch.perPage" :totalCount="postSearch.totalRows" :maxRange="5" :click="dataView" />
</div>
</div>
</div>
<div class="flex justify-end mt10">
<!-- <button class="blue-border-btn small-btn" @click="">수정</button> -->
<button v-if="isAuth" class="red-border-btn small-btn" @click="openApiDel">삭제</button>
<button class="blue-border-btn small-btn" @click="moveList">목록</button>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import PageNavigation from "../../component/PageNavigation.vue";
import PaginationButton from "../../component/PaginationButton.vue";
import SvgIcon from "@jamescoyle/vue-icon";
import _ from "lodash";
export default {
data() {
return {
openModal: false,
export_id: "",
apiInfo: this.$getDefaultJobGroup().openApiInfo,
selectApiData: this.$getDefaultJobGroup().apiExport,
showDataview: false,
dataTable: [],
postSearch: this.$getDefaultSerchVO(),
postSearch_data: this.$getDefaultSerchItem(null, "string"),
defaultRequestParamList: [
{
displayColumnName: "페이지 번호",
columnName: "currentPage",
dataType: "LONG",
size: 8,
isOption: "옵션",
defaultValue: "1",
},
{
displayColumnName: "한 페이지 결과 수",
columnName: "perPage",
dataType: "LONG",
size: 8,
isOption: "옵션",
defaultValue: "10",
},
{
displayColumnName: "페이지 번호",
columnName: "startIndex",
dataType: "LONG",
size: 8,
isOption: "옵션",
defaultValue: "1",
},
{
displayColumnName: "한 페이지 결과 수",
columnName: "pagingCnt",
dataType: "LONG",
size: 8,
isOption: "옵션",
defaultValue: "10",
},
],
dataTypeList: {
STRING: "문자열",
LONG: "정수",
DOUBLE: "실수",
DATE: "날짜",
DATETIME: "날짜시간",
},
systemURL: "",
fileList: [],
isLoading: true,
isAuth: this.authCheck(),
};
},
methods: {
moveList: function () {
this.$router.push({ path: "/openApiList.page", query: {} });
},
datasetListOpen: function () {
this.openModal = true;
},
closeModal: function () {
this.openModal = false;
},
clickTab: function (index) {
this.selectApiData = this.apiInfo.apiExportList[index];
this.showDataview = false;
this.postSearch.currentPage = 1;
this.dataView();
},
showDataPost: function () {
this.showDataview = true;
},
moveDataset: function () {
const dataset_post_id = this.selectApiData.datasetPost.dataset_post_id;
this.$router.push({
path: "/dataPostDetail.page",
query: { datapost: dataset_post_id },
});
},
dataView: function () {
this.isLoading = true;
let vm = this;
axios({
url: "/dataset/selectDataPost.json",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: {
datapost_id: vm.selectApiData.datasetPost.dataset_post_id,
search: vm.postSearch,
},
})
.then(function (response) {
let res = response.data.resultData;
if (response.data.checkMessage.success) {
vm.dataTable = res.dataTable;
// 페이징 정보 설정
vm.postSearch.totalRows = vm.dataTable.totalRows;
vm.postSearch.perPage = vm.dataTable.perPage;
vm.postSearch.currentPage = vm.dataTable.currentPage;
vm.isLoading = false;
}
})
.catch(function (error) {
this.$showAlert(
"에러 발생",
"에러가 발생했습니다. 관리자에게 문의해 주세요."
);
});
},
getOneOpenApi: function () {
let vm = this;
axios({
url: "/export/openApiOneSelect/" + vm.export_id,
method: "get",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
})
.then(function (response) {
if (response.data.checkMessage.success) {
vm.apiInfo = response.data.resultData.apiInfo;
vm.selectApiData = vm.apiInfo.apiExportList[0];
vm.fileList = response.data.resultData.fileList;
vm.dataView();
}
})
.catch(function (error) {
this.$showAlert(
"에러 발생",
"에러가 발생했습니다. 관리자에게 문의해 주세요."
);
});
},
getExportUrl: function () {
this.systemURL = window.location.protocol + "//" + window.location.host;
},
copyUrl: function () {
let vm = this;
let url =
vm.systemURL +
"/export/openAPI/" +
vm.selectApiData.datasetPost.dataset_post_id +
"/" +
vm.dataTable.datasetId +
"/" +
vm.selectApiData.export_id +
"/getData";
navigator.clipboard.writeText(url).then(
function () {
vm.$showAlert("메세지", "url이 복사되었습니다.");
},
function (err) {
console.error("Async: Could not copy text: ", err);
}
);
},
copyUrl2: function () {
let vm = this;
let url =
vm.systemURL +
"/export/openapi/" +
vm.selectApiData.datasetPost.dataset_post_id +
"/" +
vm.dataTable.datasetId +
"/" +
vm.selectApiData.export_id +
"/getData";
navigator.clipboard.writeText(url).then(
function () {
vm.$showAlert("메세지", "url이 복사되었습니다.");
},
function (err) {
console.error("Async: Could not copy text: ", err);
}
);
},
urlPreview: function () {
let vm = this;
let url =
vm.systemURL +
"/export/openapi/" +
vm.selectApiData.datasetPost.dataset_post_id +
"/" +
vm.dataTable.datasetId +
"/" +
vm.selectApiData.export_id +
"/getDataSample.json";
window.open(url);
},
// 파일 다운로드
downloadFile(file) {
axios({
url: "/fileManage/download",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: { fileManagerId: file.fileManagerId },
responseType: "blob",
})
.then(function (response) {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", file.name);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(function (error) {
this.$showAlert(
"에러 발생",
"에러가 발생했습니다. 관리자에게 문의해 주세요."
);
});
},
openApiDel: async function () {
let vm = this;
if (
await this.$showConfirm(
"삭제",
"OPEN API를 삭제하면 해당 데이터에 대한 서비스를 사용할 수 없습니다.<br>해당 OPEN API를 삭제하시겠습니까?"
)
) {
axios({
url: "/export/openApiDelete",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: { export_id: vm.export_id },
})
.then(function (response) {
if (response.data.checkMessage.success) {
vm.$showAlert("메세지", "삭제되었습니다.");
vm.moveList();
} else {
vm.$showAlert("메세지", response.data.checkMessage.message);
}
})
.catch(function (error) {
this.$showAlert(
"에러 발생",
"에러가 발생했습니다. 관리자에게 문의해 주세요."
);
});
}
},
authCheck() {
let authList = this.$store.state.loginUser.user_auth;
for (let auth of authList) {
if (auth == "ROLE_ADMIN") {
return true;
}
}
return false;
},
},
watch: {
selectApiData: function () {
this.dataView();
},
},
components: {
PageNavigation,
PaginationButton,
SvgIcon,
},
mounted() {
this.export_id = this.$route.query.export_id;
this.getOneOpenApi();
this.getExportUrl();
},
};
</script>
<style scoped>
.redfont {
color: #eb3939;
}
.del-btn {
width: 20px;
height: 20px;
cursor: pointer;
}
.tabnav li {
padding: 10px 20px;
border: 1px solid #e0e0e0;
font-size: 14px;
display: inline-block;
cursor: pointer;
}
.tabnav li.active {
background-color: #f8f8f8;
border-bottom: 1px solid #f8f8f8;
}
</style>