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
File name
Commit message
Commit date
<template>
<div :class="{
'content': true,
' overflow-y': this.$route.path.startsWith('/kdm')
}">
<div class="admin-page-title mb30" v-if="this.$route.path.startsWith('/kdm')">
<p>기술문서</p>
</div>
<div :class="{ 'top-banner banner guide-banner': true, [bannerId]: true }"
v-else-if="this.$route.path.startsWith('/aidt')">
<div class="flex-column align-center justify-center content">
<h1 class="banner-title text-ct white">{{ $getMenuInfo().menuNm }}</h1>
<p class="box-title text-ct white">{{ $getMenuInfo().menuCn }}</p>
</div>
</div>
<PageNavigationBar v-if="this.$route.path.startsWith('/aidt')" />
<div :class="{ 'w1280 pt100 pb100': this.$route.path.startsWith('/aidt') }">
<table class="detail-table mb30 admin-detail tec-detail">
<caption class="visually-hidden">{{ techDocVer.techDocNm }} 내용</caption>
<colgroup>
<col width="10%" />
<col width="90%" />
</colgroup>
<tbody>
<tr class="detail-title">
<td colspan="2" class="pd15">
<div class="flex justify-between align-end">
<div>
<span class="tech-category pd10 pt5 pb5 small-text mb5 inline-block">{{
techDocVer.techDocCtgryNm }}</span>
<h2 class="detail-table-title">{{ techDocVer.techDocNm }}</h2>
</div>
<p>
<span class="inline-block ml10">등록일 {{ $yyyymmdd(techDocVer.frstRegDt)
}}</span><span class="inline-block ml10">조회수 {{ techDocVer.inqCnt }}</span>
</p>
</div>
</td>
</tr>
<tr>
<td colspan="2" class="pd15">
<div class="flex align-center detail-content" style="background-color: #f8f8f8;">
<div class="detail-img-zone pd30">
<img src="/client/resources/img/no_img.png" class="inline-block radius"
v-if="imgFile.fileId === null" :alt="techDocVer.bbsTtl + '대체 썸네일'"/>
<img :src="$replaceImagePath(imgFile.ablstPathNm)" :alt="techDocVer.bbsTtl + '썸네일'" class="radius"
v-else @error="handleImageError">
</div>
<div class="text-zone gd-7 ml20">
<div class="flex-column justify-between align-start" style="height: 43rem;">
<div class="pb30">
<h3 class="middle-title mb20">{{ techDocVer.bbsTtl }}</h3>
<p class="content-sub-title mb10">문서번호 : {{ techDocVer.bbsDocNo }}</p>
<p class="content-sub-title mb10">버전 : {{ techDocVer.bbsVerNo }}</p>
<p class="content-sub-title mb10">배포날짜 : {{ $yyyymmdd(techDocVer.bbsCrltnDt)
}}</p>
<p class="content-sub-title mb10">주요내용 : {{ techDocVer.bbsMainCn }}</p>
<p class="content-sub-title mb10">키워드</p>
<div class="flex tec-keyword" v-if="techDocVer.bbsKywdNm">
<div class="mr5 pd5"
v-for="(keyword, keywordIndex) in techDocVer.bbsKywdNm.split(',')"
:key="keywordIndex">
<p class="keyword text-ct"> {{ keyword }}</p>
</div>
</div>
</div>
<div class="pd0">
<button class="small-btn black-btn" title="다운로드"
@click="$downloadFile(file, pageAuth)">다운로드</button>
</div>
</div>
</div>
</div>
</td>
</tr>
<tr class="border-b">
<td colspan="2" class="pd15">
<div style="min-height:35rem">
<div id="viewer" ref="viewer" class="viewer"></div>
</div>
</td>
</tr>
</tbody>
</table>
<div class="flex justify-end align-center mb30" v-if="this.$route.path.startsWith('/kdm')">
<div class="gd-1 pr0">
<button class="large-btn gray-border-btn" @click="fnList">목록</button>
</div>
<div class="gd-1 pr0">
<button class="large-btn green-border-btn" @click="isModalOpen">수정</button>
</div>
<div class="gd-1 pr0">
<button class="large-btn blue-border-btn" @click="fnUpdate">버전관리</button>
</div>
<div class="gd-1 pr0">
<button class="large-btn red-border-btn" @click="fnDelete">삭제</button>
</div>
</div>
<div class="flex justify-end align-center mb30" v-else>
<div class="gd-1 pr0">
<button class="large-btn gray-border-btn" title="목록" @click="fnList">목록</button>
</div>
</div>
<ul class="flex border-t border-b pt10 pb10 board-navigation">
<li class="gd-6 border-r">
<p class="text-lf detail-bold mb10"> <svg-icon type="mdi" :width="18" :height="18" :path="leftPath"
aria-hidden="true"></svg-icon>이전글</p>
<router-link to="#" v-if="prevVer != null" class="text-lf detail-text cursor"
@click.prevent="fnMoveTechDoc(prevVer.bbsId)"
@keydown.enter.space="fnMoveTechDoc(prevVer.bbsId)">{{ prevVer.techDocNm }}</router-link>
<p v-else class="text-lf detail-text">이전글이 없습니다</p>
</li>
<li class="gd-6">
<p class="text-rg detail-bold mb10">다음글 <svg-icon type="mdi" :width="18" :height="18"
:path="rightPath" aria-hidden="true"></svg-icon></p>
<router-link to="#" v-if="nextVer != null" class="text-rg detail-text cursor"
@click.prevent="fnMoveTechDoc(nextVer.bbsId)"
@keydown.enter.space="fnMoveTechDoc(nextVer.bbsId)">{{ nextVer.techDocNm }}</router-link>
<p v-else class="text-rg detail-text">다음글이 없습니다</p>
</li>
</ul>
</div>
</div>
<!-- 모달: 비밀번호 변경 -->
<Modal :showModal="isModal" :className="'medium-modal auto-height'">
<template v-slot:header>
<p class="page-sub-title">기술문서 정보 변경</p>
<button class="close-btn" @click="isModal = false">
<svg-icon type="mdi" :path="closePath"></svg-icon>
</button>
</template>
<div class="table-zone">
<table>
<colgroup>
<col width="110px" />
<col width="100%" />
</colgroup>
<tbody>
<tr>
<th class="text-rg pd10">기술문서 명</th>
<td class="text-lf">
<input type="text" class="full-input" id="newPw" autocomplete="off"
v-model="modalTechDocNm" />
</td>
</tr>
<tr>
<th class="text-rg pd10">카테고리</th>
<td class="text-lf">
<select name="" id="" class="half-select ml0" v-model="modalTechDocCtgryCd">
<option :value=null disabled>선택하세요</option>
<option v-for="(ctgryCd, idx) in ctgryCdList" :key="idx" :value=ctgryCd.cdId
@change="findAllTechDoc">{{ ctgryCd.cdNm }}</option>
</select>
</td>
</tr>
<tr>
<th class="text-rg pd10">메인공개여부</th>
<td class="text-lf">
<div class="flex align-center no-gutters" style="height: 4rem;">
<div class="gd-4">
<input type="radio" name="code" id="y" class="mr5" value="Y" v-model="modalRlsYn" />
<label for="y">공개</label>
</div>
<div class="gd-4">
<input type="radio" name="code" id="n" class="mr5" value="N" v-model="modalRlsYn" />
<label for="n">비공개</label>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<template v-slot:footer>
<div class="gd-2 pr0">
<button class="large-btn red-border-btn" @click="isModal = false">
취소
</button>
</div>
<div class="gd-2 pr0">
<button class="large-btn blue-border-btn" @click="techDocUpdate">
변경
</button>
</div>
</template>
</Modal>
</template>
<script>
import PaginationButton from '../../../../component/pagination/PaginationButton.vue';
import Viewer from '@toast-ui/editor/dist/toastui-editor-viewer';
import '@toast-ui/editor/dist/toastui-editor.css';
import '@toast-ui/editor/dist/i18n/ko-kr';
import { findByVer, techDocUpdate, techDocDelete } from "../../../../../resources/api/techDoc.js"
import { updateVwCnt } from '../../../../../resources/api/bbsCn.js'
import axios from "axios";
import { mdiChevronRight, mdiChevronLeft, mdiWindowClose } from '@mdi/js';
import Modal from "../../../../component/modal/Modal.vue";
import PageNavigationBar from '../../../../component/pagenavigationbar/PageNavigationBar.vue';
export default {
data() {
return {
closePath: mdiWindowClose,
rightPath: mdiChevronRight,
leftPath: mdiChevronLeft,
pageAuth: this.$store.state.pageAuth,
// id
pageId: this.$route.query.pageId,
//path
path: this.$store.state.path,
//기술문서 수정 모달
isModal: false,
// 상세조회 정보 담는 객체
techDocVer: {
bbsId: this.pageId,
bbsTtl: null,
bbsCn: null,
inqCnt: null,
fileMngId: null,
frstRegUid: null,
frstRegDt: null,
bbsVerNo: null,
bbsDocNo: null,
imgFileMngId: null,
bbsKywdNm: null,
bbsCrltnDt: null,
bbsMainCn: null,
techDocId: null,
techDocNm: null,
techDocCtgryCd: null,
techDocCtgryNm: null,
rlsTechDocId: null,
mbrEncptFlnm: null,
rlsYn: null,
},
// 이전글 다음글
prevVer: {},
nextVer: {},
//카테고리 리스트
ctgryCdList: [],
//첨부 파일
imgFile: {},
file: {},
//모달 데이터
modalTechDocNm: null,
modalTechDocCtgryCd: null,
modalRlsYn: null,
errorImages: new Set(),
}
},
created() {
this.updateVwCnt();
this.init();
},
methods: {
// 조회수 증가
async updateVwCnt() {
try {
const params = {
'bbsId': this.pageId,
}
const res = await updateVwCnt(params);
} catch (error) {
// alert('에러가 발생했습니다.\n시스템관리자에게 문의하세요.');
alert(this.$getCmmnMessage('err005'));
}
},
isModalOpen() {
this.isModal = true;
this.modalTechDocNm = this.techDocVer.techDocNm;
this.modalTechDocCtgryCd = this.techDocVer.techDocCtgryCd;
this.modalRlsYn = this.techDocVer.rlsYn;
},
async init() {
this.findByVer();
this.ctgryCdList = await this.$getCommonCode('techDocCtgryCd');
},
fnList() {
this.$router.push({
path: this.path + '/list.page'
});
},
fnUpdate() {
this.$router.push({
path: this.path + '/insert.page', query: { 'pageId': this.techDocVer.techDocId }
// name: 'admTechnicalDocumentInsert' ,params : {'pageId' : this.techDocVer.techDocId}
});
},
// 기술 문서 버전 상세 조회
async findByVer() {
// 데이터 세팅
const data = { rlsTechDocId: this.pageId };
try {
const response = await findByVer(data);
this.techDocVer = response.data.data.techDoc;
this.imgFile = response.data.data.imgFileList[0];
this.file = response.data.data.fileList[0];
this.prevVer = response.data.data.prevVer;
this.nextVer = response.data.data.nextVer;
this.getViewer(this.techDocVer.bbsCn);
} catch (error) {
console.log(error)
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
alert(error.response.data.message);
} else {
// alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
alert(this.$getCmmnMessage('err005'));
}
}
},
//수정
async techDocUpdate() {
if (!confirm(this.$getCmmnMessage("cnf004"))) return
// 데이터 세팅
const data = {
'techDocId': this.techDocVer.techDocId
, 'bbsId': this.pageId
, 'rlsTechDocId': this.techDocVer.rlsTechDocId
, 'techDocNm': this.modalTechDocNm
, 'techDocCtgryCd': this.modalTechDocCtgryCd
, 'rlsYn': this.modalRlsYn
}
try {
const response = await techDocUpdate(data);
this.techDocVer = response.data.data.techDoc;
this.imgFile = response.data.data.imgFileList[0];
this.file = response.data.data.fileList[0];
this.getViewer(this.techDocVer.bbsCn);
alert(this.$getCmmnMessage('msg002'));
this.isModal = false;
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
alert(error.response.data.message);
} else {
// alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
alert(this.$getCmmnMessage('err005'));
}
}
},
// 삭제
async fnDelete() {
if (!confirm(this.$getCmmnMessage("cnf002"))) return
// 데이터 세팅
const data = this.techDocVer;
try {
const response = await techDocDelete(data);
alert(this.$getCmmnMessage('msg003'));
this.fnList();
} catch (error) {
console.log(error)
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
alert(error.response.data.message);
} else {
// alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
alert(this.$getCmmnMessage('err005'));
}
}
},
// 페이지 이동
fnMoveTechDoc(bbsId) {
this.$router.push({
path: this.path + '/view.page',
query: {
pageId: bbsId
},
});
},
getViewer(data) {
this.viewer = new Viewer({
el: this.$refs.viewer,
initialEditType: 'wysiwyg',
previewStyle: 'vertical',
initialValue: data,
customHTMLRenderer: {
htmlBlock: {
iframe(node) {
return [
{ type: 'openTag', tagName: 'iframe', outerNewLine: true, attributes: node.attrs },
{ type: 'html', content: node.childrenHTML },
{ type: 'closeTag', tagName: 'iframe', outerNewLine: true },
];
},
}
},
});
},
handleImageError(event) {
if (!this.errorImages.has(event.target.id)) {
this.errorImages.add(event.target.id);
event.target.src = require('/client/resources/img/no_img.png'); // 대체 이미지 경로
}
},
},
watch: {
$route(to, from) {
if (to.query.pageId != from.query.pageId) {
this.pageId = to.query.pageId;
this.init();
}
},
},
components: {
'PaginationButton': PaginationButton,
'Modal': Modal,
'PageNavigationBar': PageNavigationBar
},
mounted() {
}
}
</script>