Merge remote-tracking branch 'origin/main' into board-0117

This commit is contained in:
kimdaae328 2025-01-20 16:15:11 +09:00
commit 62a63f2113
3 changed files with 73 additions and 19 deletions

49
src/common/common.js Normal file
View File

@ -0,0 +1,49 @@
/*
작성자 : 공현지
작성일 : 2025-01-17
수정자 :
수정일 :
설명 : 공통 스크립트
*/
import Quill from 'quill';
/*
*템플릿 사용법 : $common.변수
*setup() 사용법 :
const { appContext } = getCurrentInstance();
const $common = appContext.config.globalProperties.$common;
$common.변수
*/
const common = {
// JSON 문자열로 Delta 타입을 변환
contentToHtml(content) {
try {
if (content.startsWith('{') || content.startsWith('[')) {
// Delta 형식으로 변환
const delta = JSON.parse(content);
const quill = new Quill(document.createElement('div'));
quill.setContents(delta);
return quill.root.innerHTML; // HTML 반환
}
return content; // 이미 HTML일 경우 그대로 반환
} catch (error) {
console.error('콘텐츠 변환 오류:', error);
return content; // 오류 발생 시 원본 반환
}
},
// Delta 타입을 JSON 문자열로 변환
deltaAsJson(content) {
if (content && content.ops) {
return JSON.stringify(content.ops); // Delta 객체에서 ops 속성만 JSON 문자열로 변환
}
console.error('잘못된 Delta 객체:', content);
return null; // Delta 객체가 아니거나 ops가 없을 경우 null 반환
}
}
export default {
install(app) {
app.config.globalProperties.$common = common;
}
};

View File

@ -46,20 +46,27 @@
</div>
<!-- 에디터가 표시될 div -->
<div ref="editor"></div>
<!-- Alert 메시지 표시 -->
<div class="invalid-feedback" :class="isAlert ? 'd-block' : ''">내용을 확인해주세요.</div>
</div>
</template>
<script setup>
import Quill from 'quill';
import 'quill/dist/quill.snow.css';
import { onMounted, ref, watch, defineEmits } from 'vue';
import { onMounted, ref, watch, defineEmits, defineProps } from 'vue';
import $api from '@api';
const props = defineProps({
isAlert: {
type: Boolean,
default: false,
},
});
const editor = ref(null);
const font = ref('nanum-gothic');
const fontSize = ref('16px');
const emit = defineEmits(['update:data']);
onMounted(() => {
const Font = Quill.import('formats/font');
Font.whitelist = ['nanum-gothic', 'd2coding', 'consolas', 'serif', 'monospace'];
@ -83,21 +90,23 @@ onMounted(() => {
quillInstance.format('size', fontSize.value);
quillInstance.on('text-change', () => {
emit('update:data', quillInstance.root.innerHTML);
const delta = quillInstance.getContents(); // Get Delta format
emit('update:data', delta);
});
watch([font, fontSize], () => {
quillInstance.format('font', font.value);
quillInstance.format('size', fontSize.value);
});
//
let imageUrls = new Set();
// Handle image upload
let imageUrls = new Set();
quillInstance.getModule('toolbar').addHandler('image', () => {
selectLocalImage();
});
quillInstance.on('text-change', (delta, oldDelta, source) => {
emit('update:data', quillInstance.root.innerHTML);
// Emit Delta when content changes
emit('update:data', quillInstance.getContents());
delta.ops.forEach(op => {
if (op.insert && typeof op.insert === 'object' && op.insert.image) {
const imageUrl = op.insert.image;
@ -107,13 +116,11 @@ onMounted(() => {
}
});
});
async function selectLocalImage() {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = () => {
const file = input.files[0];
if (file) {
@ -129,22 +136,21 @@ onMounted(() => {
imageUrls.add(fullImageUrl);
}).catch(e => {
toastStore.onToast('잠시후 다시 시도해주세요.', 'e');
toastStore.onToast('잠시후 다시 시도해주세요.', 'e');
});
}
};
}
async function uploadImageToServer(formData) {
try {
const response = await $api.post('img/upload', formData, { isFormData: true });
const imageUrl = response.data.data;
return imageUrl;
const response = await $api.post('quilleditor/upload', formData, { isFormData: true });
const imageUrl = response.data.data;
return imageUrl;
} catch (error) {
toastStore.onToast('잠시후 다시 시도해주세요.', 'e');
throw error;
}
}
function checkForDeletedImages() {
const editorImages = document.querySelectorAll('#editor img');
const currentImages = new Set(Array.from(editorImages).map(img => img.src));
@ -156,14 +162,11 @@ onMounted(() => {
});
}
});
</script>
<style>
@import 'quill/dist/quill.snow.css';
.ql-editor {
min-height: 300px;
font-family: 'Nanum Gothic', sans-serif;
}
</style>
</style>

View File

@ -5,13 +5,15 @@ import App from './App.vue'
import router from '@/router'
import dayjs from '@p/dayjs'
import ToastModal from '@c/modal/ToastModal.vue';
import common from '@/common/common.js'
const pinia = createPinia()
pinia.use(piniaPersist)
const app = createApp(App)
app.use(router)
.use(pinia)
.use(common)
.use(dayjs)
.component('ToastModal',ToastModal)
.mount('#app')