169 lines
6.4 KiB
Vue
169 lines
6.4 KiB
Vue
<template>
|
|
<div class="container-xxl flex-grow-1 container-p-y">
|
|
<div class="card">
|
|
<div class="pb-4 rounded-top">
|
|
<div class="container py-12 px-xl-10 px-4" style="padding-bottom: 0px !important">
|
|
<h3 class="text-center mb-2 mt-4">글 작성</h3>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-12">
|
|
<div class="card-body">
|
|
<FormInput
|
|
title="제목"
|
|
name="title"
|
|
:is-essential="true"
|
|
:is-alert="titleAlert"
|
|
v-model="title"
|
|
/>
|
|
|
|
<!-- 카테고리 선택 -->
|
|
<div class="mb-4 d-flex align-items-center">
|
|
<label class="col-md-2 col-form-label">카테고리 <span class="text-danger">*</span></label>
|
|
<div class="d-flex flex-wrap align-items-center mt-3 ms-1">
|
|
<div
|
|
v-for="(categoryName, index) in categoryList"
|
|
:key="index"
|
|
class="form-check me-3"
|
|
>
|
|
<input
|
|
class="form-check-input"
|
|
type="radio"
|
|
:id="`category-${index}`"
|
|
:value="index"
|
|
v-model="category"
|
|
/>
|
|
<label class="form-check-label" :for="`category-${index}`">
|
|
{{ categoryName }}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 비밀번호 필드 -->
|
|
<div v-if="category === 1" class="mb-4">
|
|
<FormInput
|
|
title="비밀번호"
|
|
name="pw"
|
|
type="password"
|
|
:is-essential="true"
|
|
:is-alert="passwordAlert"
|
|
v-model="password"
|
|
/>
|
|
</div>
|
|
|
|
<FormFile
|
|
title="첨부파일"
|
|
name="files"
|
|
:is-alert="attachFilesAlert"
|
|
@update:data="attachFiles = $event"
|
|
@update:isValid="isFileValid = $event"
|
|
/>
|
|
|
|
<div class="mb-4">
|
|
<label for="html5-tel-input" class="col-md-2 col-form-label">
|
|
내용
|
|
<span class="text-danger">*</span>
|
|
<div class="invalid-feedback" :class="contentAlert ? 'display-block' : ''">내용을 확인해주세요.</div>
|
|
</label>
|
|
<div class="col-md-12">
|
|
<QEditor @update:data="content = $event" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-4 d-flex justify-content-end">
|
|
<button type="button" class="btn btn-info" @click="goList">
|
|
<i class="bx bx-left-arrow-alt"></i>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-primary ms-1"
|
|
@click="write"
|
|
:disabled="!isFileValid"
|
|
>
|
|
<i class="bx bx-check"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import QEditor from '@c/editor/QEditor.vue';
|
|
import FormInput from '@c/input/FormInput.vue';
|
|
import FormFile from '@c/input/FormFile.vue';
|
|
import { getCurrentInstance, ref } from 'vue';
|
|
import router from '@/router';
|
|
import axios from '@api';
|
|
|
|
const categoryList = ['자유', '익명', '공지사항']; // 카테고리 이름
|
|
const title = ref('');
|
|
const password = ref('');
|
|
const category = ref(0); // 기본값 0
|
|
const content = ref('');
|
|
const attachFiles = ref(null);
|
|
const isFileValid = ref(true); // 파일 유효성 상태 추가
|
|
|
|
const titleAlert = ref(false);
|
|
const passwordAlert = ref(false);
|
|
const contentAlert = ref(false);
|
|
const attachFilesAlert = ref(false);
|
|
|
|
const { appContext } = getCurrentInstance();
|
|
const $common = appContext.config.globalProperties.$common; // $common에 접근
|
|
|
|
const goList = () => {
|
|
router.push('/board');
|
|
};
|
|
|
|
const write = async () => {
|
|
titleAlert.value = !title.value;
|
|
passwordAlert.value = category.value === 1 && !password.value;
|
|
contentAlert.value = !content.value;
|
|
|
|
if (titleAlert.value || passwordAlert.value || contentAlert.value || !isFileValid.value) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const boardData = {
|
|
LOCBRDTTL: title.value,
|
|
LOCBRDCON: $common.deltaAsJson(content.value),
|
|
LOCBRDPWD: category.value === 1 ? password.value : null,
|
|
LOCBRDTYP: category.value === 1 ? 'S' : 'F',
|
|
};
|
|
|
|
const { data: boardResponse } = await axios.post('board', boardData);
|
|
const boardId = boardResponse.data;
|
|
|
|
if (attachFiles.value && attachFiles.value.length > 0) {
|
|
for (const file of attachFiles.value) {
|
|
const formData = new FormData();
|
|
const fileNameWithoutExt = file.name.replace(/\.[^/.]+$/, '');
|
|
|
|
formData.append('CMNBRDSEQ', boardId);
|
|
formData.append('CMNFLEORG', fileNameWithoutExt);
|
|
formData.append('CMNFLEEXT', file.name.split('.').pop());
|
|
formData.append('CMNFLESIZ', file.size);
|
|
formData.append('CMNFLEPAT', 'boardfile');
|
|
formData.append('file', file);
|
|
|
|
await axios.post(`board/${boardId}/attachments`, formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
alert('게시물이 작성되었습니다.');
|
|
goList();
|
|
} catch (error) {
|
|
console.error(error);
|
|
alert('게시물 작성 중 오류가 발생했습니다.');
|
|
}
|
|
};
|
|
</script>
|