
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
04-04
04-04
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,
'admin-style overflow-y': pageRole === 'adm',
'w1400 pt50 pb50': pageRole === 'portal',
}"
>
<div
:class="{
'admin-page-title point-font2 mb30': pageRole == 'adm',
'page-title point-font mb30':
pageRole == 'portal',
}"
>
<p>{{ bbsMng.bbsNm }}</p>
</div>
<table class="form-table mb30">
<colgroup>
<col width="10%" />
<col width="90%" />
</colgroup>
<tbody>
<tr>
<th
:class="{
'text-lf': true,
'point-font2': pageRole == 'adm',
'point-font': pageRole == 'portal',
}"
>
<span>제목</span>
</th>
<td>
<input
type="text"
class="full-input"
v-model="bbsCn.bbsNm"
placeholder="제목을 입력하세요."
/>
</td>
</tr>
<tr class="border-top">
<th
colspan="4"
:class="{
'text-lf': true,
'point-font2': pageRole == 'adm',
'point-font': pageRole == 'portal',
}"
>
<span>내용</span>
</th>
</tr>
<tr style="max-height: 600px">
<td colspan="4" style="height: 100%">
<!-- <textarea name="smart" id="smart" style="width:100%"></textarea> -->
<!-- <textarea name="editor4" id="editor4" style="width:100%"></textarea> -->
<ckeditorComponent
ref="ckeditor5"
:bbsCn.sync="bbsCn"
></ckeditorComponent>
</td>
</tr>
<tr v-if="bbsMng.atchFileUseYn === 'Y'" class="border-top">
<th
:class="{
'text-lf': true,
'point-font2': pageRole == 'adm',
'point-font': pageRole == 'portal',
}"
>
첨부파일
</th>
<td colspan="2">
<div class="gd-12 pr0">
<div class="gd-2 pl0 pr0">
<label
for="file"
:class="{
'large-btn text-ct': true,
'blue-border-btn': pageRole == 'adm',
'green-border-btn':
pageRole == 'portal',
}"
>파일찾기</label
>
<input
type="file"
id="file"
ref="file"
@change="fnFileInsert"
multiple
/>
</div>
<div class="gd-12 pl0 pr0" v-if="fileList.length > 0">
<ul>
<li
v-for="(file, idx) in fileList"
:key="idx"
class="pd10 mt10 border radius"
>
<div
v-if="file['fileId'] != null"
class="flex align-center justify-between file-wrap"
>
<p>{{ file["fileNm"] }}.{{ file["extnNm"] }}</p>
<button class="del-btn" @click="fnFileDelete(file, idx)">
X
</button>
</div>
<div
v-else
class="flex align-center justify-between file-wrap"
>
<p>{{ file.name }}</p>
<button class="del-btn" @click="fnFileDelete(file, idx)">
X
</button>
</div>
</li>
</ul>
</div>
</div>
</td>
</tr>
<tr v-if="bbsMng.ntcUseYn === 'Y'" class="border-top">
<th
:class="{
'text-lf': true,
'point-font2': pageRole == 'adm',
'point-font': pageRole == 'portal',
}"
>
공지글
</th>
<td colspan="3">
<div class="flex align-center no-gutters">
<div class="gd-4">
<input
type="radio"
name="notice"
id="notice-y"
class="mr5"
value="Y"
v-model="bbsCn.ntcPstYn"
/>
<label for="notice-y">사용</label>
</div>
<div class="gd-4">
<input
type="radio"
name="notice"
id="notice-n"
class="mr5"
value="N"
v-model="bbsCn.ntcPstYn"
/>
<label for="notice-n">미사용</label>
</div>
</div>
</td>
</tr>
<tr v-if="bbsCn.ntcPstYn === 'Y'" class="border-top">
<th
:class="{
'text-lf': true,
'point-font2': pageRole == 'adm',
'point-font': pageRole == 'portal',
}"
>
공지글 게시기간
</th>
<td colspan="3">
<div class="flex align-center no-gutters">
<div class="gd-4">
<input
type="datetime-local"
class="full-input ml0"
v-model="bbsCn.ntcBgngDt"
@change="checkDateValidity('ntcBgngDt', $event)"
/>
</div>
<div class="pd10">-</div>
<div class="gd-4">
<input
type="datetime-local"
class="full-input ml0"
v-model="bbsCn.ntcEndDt"
@change="checkDateValidity('ntcEndDt', $event)"
/>
</div>
</div>
</td>
</tr>
<tr v-if="bbsMng.prvtPstUseYn === 'Y'" class="border-top">
<th
:class="{
'text-lf': true,
'point-font2': pageRole == 'adm',
'point-font': pageRole == 'portal',
}"
>
비밀글
</th>
<td colspan="3">
<div class="flex align-center no-gutters">
<div class="gd-4">
<input
type="radio"
name="private"
id="private-y"
class="mr5"
value="Y"
v-model="bbsCn.prvtPstYn"
/>
<label for="private-y">사용</label>
</div>
<div class="gd-4">
<input
type="radio"
name="private"
id="private-n"
class="mr5"
value="N"
v-model="bbsCn.prvtPstYn"
/>
<label for="private-n">미사용</label>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<div class="flex justify-end align-center no-gutters">
<div class="gd-1 mr10">
<button
:class="{
'large-btn': true,
'blue-btn': pageRole == 'adm',
'green-btn': pageRole == 'portal',
}"
@click="fnInsert"
>
{{ bbsCn.bbsId == null ? "등록" : "수정" }}
</button>
</div>
<div class="gd-1">
<button class="large-btn gray-btn" @click="fnCancel">취소</button>
</div>
</div>
</div>
</template>
<script>
import { mdiClose } from "@mdi/js";
import { findByBbsCn } from "../../../../../../resources/api/bbsCn.js";
import queryParams from "../../../../../../resources/js/queryParams";
import defaultAxios from "../../../../../../resources/js/defaultAxios";
// ckditor5
import ckeditorComponent from "../../../../../component/ckeditor5/ckeditorComponent.vue";
export default {
mixins: [queryParams],
data() {
return {
file: null,
iconPath: mdiClose,
pageRole: this.$store.state.userType,
path: this.$store.state.path,
pageAuth: this.$store.state.pageAuth,
bbsMngId: null,
bbsCn: {},
bbsMng: {},
// 파일 업로드
files: null,
fileList: [],
deleteFileList: [],
//이미지 업로드
imgFiles: null,
imgFileList: [],
deleteImgFileList: [],
//스마트 에디터
editor: null,
};
},
created() {
this.fnBbsIdExtraction();
this.fnSelectOne();
},
methods: {
test() {
this.Validation();
},
// 취소 버튼 동작
fnCancel() {
if (!confirm("등록을 취소하시겠습니까?")) {
return;
}
if (this.bbsCn.bbsId == null || this.bbsCn.bbsId == 0) {
this.$router.push({
path: this.path + "/list.page",
});
} else {
this.$router.push({
path: this.path + "/view.page",
query: {
pageId: this.bbsCn.bbsId,
},
});
}
},
// 상세조회
async fnSelectOne() {
try {
const params = {
bbsId: this.$route.query.pageId,
bbsMngId: this.bbsMngId,
};
const res = await findByBbsCn(params);
if (res.status == 200) {
this.bbsCn = res.data.data.bbsCn;
this.bbsMng = res.data.data.bbsMng;
this.bbsMng.byteLmt = res.data.data.bbsMng.fileSzLmt * 1024 * 1024;
this.fileList = res.data.data.fileList;
this.$refs.ckeditor5.createEditor();
}
} catch (error) {
alert("에러가 발생했습니다.\n시스템관리자에게 문의하세요.");
}
},
// 첨부파일 등록
fnFileInsert() {
// files 개수 만큼 반복해서 type, size 체크
this.files = this.$refs.file.files;
for (let i = 0; i < this.files.length; i++) {
const file = this.files[i];
const extnNm = file.name.split(".").pop();
if (this.bbsMng.fileExtnNmList.length >= 1) {
if (!this.bbsMng.fileExtnNmList.includes(extnNm)) {
alert(
"첨부파일 확장자를 확인해주세요.\n등록가능 확장자: " +
this.bbsMng.fileExtnNmList
);
return;
}
}
if (this.bbsMng.byteLmt != 0 && this.bbsMng.byteLmt != null) {
if (file.size > this.bbsMng.byteLmt) {
alert(this.bbsMng.fileSzLmt + "MB 이하의 파일만 등록 가능합니다.");
return;
}
}
}
this.fileList = [...this.fileList, ...Array.from(this.files)];
},
// 첨부파일 삭제
fnFileDelete(file, index) {
if (file["fileId"] != null) {
this.deleteFileList.push(file);
}
this.fileList.splice(index, 1);
},
fnInsert() {
if (this.bbsCn.bbsId == null || this.bbsCn.bbsId == 0) {
this.fnSave();
} else {
this.fnUpdate();
}
},
// 등록
async fnSave() {
if (!this.Validation()) {
return;
}
// 폼데이터 생성
this.bbsCn.bbsMngId = this.bbsMngId;
var formData = new FormData();
const paramsToBlob = new Blob([JSON.stringify(this.bbsCn)], {
type: "application/json; charset=UTF-8",
});
formData.append("bbsCn", paramsToBlob);
for (const file of this.fileList) {
formData.append("multipartFileList", file);
}
for (const imgFile of this.imgFileList) {
formData.append("multipartImgList", imgFile);
}
// axios 호출
await defaultAxios({
url: "/sys/bbsCn/saveBbsCn.file",
method: "post",
headers: {
"Content-Type": "multipart/form-data; charset=UTF-8",
Authorization: this.$store.state.authorization,
},
data: formData,
})
.then((response) => {
const bbsId = response.data.data.bbsId;
alert("게시글이 등록되었습니다.");
this.$router.push({
// name: 'BoardManagementSelectListOne',
path: this.path + "/view.page",
query: {
pageId: bbsId,
},
});
})
.catch((error) => {
const message = error.response.data.message;
alert(message);
});
},
// 수정
async fnUpdate() {
if (!this.Validation()) {
return;
}
// 폼데이터 생성
this.bbsCn.bbsMngId = this.bbsMngId;
var formData = new FormData();
const paramsToBlob = new Blob([JSON.stringify(this.bbsCn)], {
type: "application/json; charset=UTF-8",
});
formData.append("params", paramsToBlob);
const deleteFileListToBlob = new Blob(
[JSON.stringify(this.deleteFileList)],
{
type: "application/json; charset=UTF-8",
}
);
formData.append("deleteFileList", deleteFileListToBlob);
// 추가 첨부파일
for (const file of this.fileList) {
if (file["fileId"] == null) {
formData.append("multipartFileList", file);
}
}
// 이미지 파일
const deleteImgFileListToBlob = new Blob(
[JSON.stringify(this.deleteImgFileList)],
{
type: "application/json; charset=UTF-8",
}
);
formData.append("deleteImgFileList", deleteImgFileListToBlob);
for (const imgFile of this.imgFileList) {
formData.append("multipartImgList", imgFile);
}
// axios 호출
defaultAxios({
url: "/sys/bbsCn/updateBbsCn.file",
method: "post",
headers: {
"Content-Type": "multipart/form-data; charset=UTF-8",
Authorization: this.$store.state.authorization,
},
data: formData,
})
.then((response) => {
const bbsId = response.data.data;
this.$router.push({
// name: 'BoardManagementSelectListOne',
path: this.path + "/view.page",
query: {
pageId: bbsId,
},
});
})
.catch((error) => {
const message = error.response.data.message;
alert(message);
});
},
// 유효성 검사
Validation() {
if (this.bbsCn.bbsNm == null || this.bbsCn.bbsNm.trim() == "") {
alert("게시판 제목을 입력해주세요.");
return false;
}
// const oEditors = this.oEditors;
// oEditors.getById["smart"].exec("UPDATE_CONTENTS_FIELD", []);
// // 스마트에디터의 iframe에 있는 내용을 textarea로.
// this.bbsCn.bbsCn = document.getElementById("smart").value;
// 내용 null검사
// if (!this.tagChecked() && (this.isEmpty(this.bbsCn.bbsCn) || this.removeHtmlAndSpace(this.bbsCn.bbsCn) === '')) {
// alert("내용을 입력하세요.");
// document.getElementById("smart").focus();
// return false;
// }
if (
!this.tagChecked() &&
(this.isEmpty(this.bbsCn.bbsCn) ||
this.removeHtmlAndSpace(this.bbsCn.bbsCn) === "")
) {
alert("게시판 내용을 입력해주세요.");
return false;
}
if (
this.bbsCn.ntcPstYn === "Y" &&
(this.bbsCn.ntcBgngDt === null || this.bbsCn.ntcEndDt === null)
) {
alert("공지기간을 올바르게 설정해주세요.");
return false;
}
return true;
},
// 태그 체크
tagChecked() {
const tag = this.bbsCn.bbsCn;
if (tag.indexOf("<img") != -1) {
return true;
} else {
return false;
}
},
/**
* 빈 객체 여부
*/
isEmpty: function (data) {
if (
data === undefined ||
data === null ||
data === "" ||
data.length === 0 ||
(data.constructor == Object && Object.keys(data).length === 0)
) {
return true;
} else {
return false;
}
},
removeHtmlAndSpace: function (str) {
return str
.replace(/<[^>]*>/g, "") // HTML 태그 제거
.replace(/ /gi, " ") // 를 공백으로 변환
.replace(/\s/g, ""); // 모든 공백 제거
},
// 공지기간 유효성 체크
checkDateValidity(changeDate, event) {
const val = event.target.value; // 변경된 날짜 값
// 시작일 변경 시
if (changeDate === "ntcBgngDt") {
if (this.bbsCn.ntcEndDt !== null && this.bbsCn.ntcEndDt < val) {
alert("시작일은 종료일보다 클 수 없습니다.");
this.bbsCn.ntcBgngDt = null; // 유효하지 않은 경우, 시작일을 초기화
} else {
this.bbsCn.ntcBgngDt = val;
}
}
// 종료일 변경 시
else if (changeDate === "ntcEndDt") {
if (this.bbsCn.ntcBgngDt !== null && this.bbsCn.ntcBgngDt > val) {
alert("종료일은 시작일보다 작을 수 없습니다.");
this.bbsCn.ntcEndDt = null; // 유효하지 않은 경우, 종료일을 초기화
} else {
this.bbsCn.ntcEndDt = val;
}
}
},
// // 에디터 생성
// createEditor: function () {
// // ck에디터 적용
// ClassicEditor
// .create(document.querySelector('#editor4'), {
// extraPlugins: [this.MyCustomUploadAdapterPlugin],
// removePlugins: ['MediaEmbedToolbar'],
// image: {
// toolbar: ['imageTextAlternative', '|', 'imageStyle:alignLeft', 'imageStyle:alignCenter', 'imageStyle:alignRight','|','resizeImage:50','resizeImage:75', 'resizeImage:original','resizeImage:custom',],
// resizeOptions: [
// {
// name: 'resizeImage:original',
// value: null,
// icon: 'original'
// },
// {
// name: 'resizeImage:custom',
// value: 'custom',
// icon: 'custom'
// },
// {
// name: 'resizeImage:50',
// value: '50',
// icon: 'medium'
// },
// {
// name: 'resizeImage:75',
// value: '75',
// icon: 'large'
// }
// ],
// },
// })
// .then(editor => {
// this.editor = editor;
// editor.setData(this.bbsCn.bbsCn);
// editor.model.document.on('change', () => {
// this.bbsCn.bbsCn = editor.getData();
// });
// })
// .catch(error => {
// console.error('There was a problem initializing the editor.', error);
// });
// },
// beforeDestroy: function() {
// if (this.editor) {
// this.editor.destroy()
// .then(() => {
// this.editor = null;
// });
// }
// },
// MyCustomUploadAdapterPlugin: function(editor) {
// editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
// console.log('loader', loader);
// return new UploadAdapter(loader);
// }
// }
},
watch: {
"bbsCn.ntcPstYn": function (val) {
if (val === "Y") {
const offset = new Date().getTimezoneOffset() * 60000;
const now = new Date(Date.now() - offset).toISOString().slice(0, 16);
this.bbsCn.ntcBgngDt =
this.bbsCn.ntcBgngDt == null ? now : this.bbsCn.ntcBgngDt;
this.bbsCn.ntcEndDt =
this.bbsCn.ntcEndDt == null ? now : this.bbsCn.ntcEndDt;
}
},
},
computed: {},
components: {
ckeditorComponent,
},
mounted() {},
};
</script>
<style scoped>
</style>