에디터 첨부파일 인덱스 업데이트 로직 추가
This commit is contained in:
parent
ae9c8735b1
commit
93953aedcc
@ -71,7 +71,8 @@
|
|||||||
const editor = ref(null); // 에디터 DOM 참조
|
const editor = ref(null); // 에디터 DOM 참조
|
||||||
const font = ref('nanum-gothic'); // 기본 폰트
|
const font = ref('nanum-gothic'); // 기본 폰트
|
||||||
const fontSize = ref('16px'); // 기본 폰트 크기
|
const fontSize = ref('16px'); // 기본 폰트 크기
|
||||||
const emit = defineEmits(['update:data']);
|
const emit = defineEmits(['update:data', 'update:uploadedImgList']);
|
||||||
|
const uploadedImgList = ref([]); // 에디터에 이미지 첨부시 업데이트 된 파일 인덱스 번호 리스트
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 툴바에서 선택할 수 있는 폰트 목록 설정
|
// 툴바에서 선택할 수 있는 폰트 목록 설정
|
||||||
@ -112,6 +113,13 @@
|
|||||||
quillInstance.format('size', fontSize.value);
|
quillInstance.format('size', fontSize.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 이미지 첨부 리스트가 변경 되었을때
|
||||||
|
watch(uploadedImgList, () => {
|
||||||
|
console.log(!23);
|
||||||
|
emit('update:uploadedImgList', uploadedImgList.value);
|
||||||
|
console.log('uploadedImgList.value: ', uploadedImgList.value);
|
||||||
|
});
|
||||||
|
|
||||||
// 초기 데이터가 있을 경우, HTML 형식으로 삽입
|
// 초기 데이터가 있을 경우, HTML 형식으로 삽입
|
||||||
if (props.initialData) {
|
if (props.initialData) {
|
||||||
quillInstance.setContents(JSON.parse(props.initialData));
|
quillInstance.setContents(JSON.parse(props.initialData));
|
||||||
@ -150,7 +158,15 @@
|
|||||||
|
|
||||||
// 이미지 서버에 업로드 후 URL 받기
|
// 이미지 서버에 업로드 후 URL 받기
|
||||||
uploadImageToServer(formData)
|
uploadImageToServer(formData)
|
||||||
.then(serverImageUrl => {
|
.then(data => {
|
||||||
|
const uploadImgIdx = data?.fileIndex; // 업로드 된 파일 DB 인덱스
|
||||||
|
const serverImageUrl = data?.fileUrl; // 업로드 된 파일 url
|
||||||
|
|
||||||
|
// 업로드 된 파일 인덱스 (게시글 저장 시 해당 인덱스 번호에 게시글 인덱스를 업데이트)
|
||||||
|
if (uploadImgIdx) {
|
||||||
|
uploadedImgList.value = [...uploadedImgList.value, uploadImgIdx];
|
||||||
|
}
|
||||||
|
|
||||||
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
|
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
|
||||||
const fullImageUrl = `${baseUrl}${serverImageUrl.replace(/\\/g, '/')}`;
|
const fullImageUrl = `${baseUrl}${serverImageUrl.replace(/\\/g, '/')}`;
|
||||||
|
|
||||||
@ -168,40 +184,40 @@
|
|||||||
|
|
||||||
// 이미지 서버 업로드
|
// 이미지 서버 업로드
|
||||||
async function uploadImageToServer(formData) {
|
async function uploadImageToServer(formData) {
|
||||||
try {
|
try {
|
||||||
// Make the POST request to upload the image
|
// Make the POST request to upload the image
|
||||||
const response = await $api.post('quilleditor/upload', formData, { isFormData: true });
|
const response = await $api.post('quilleditor/upload', formData, { isFormData: true });
|
||||||
|
|
||||||
// Check if the response contains the expected data
|
// Check if the response contains the expected data
|
||||||
if (response.data && response.data.data) {
|
if (response.data && response.data.data) {
|
||||||
const imageUrl = response.data.data;
|
const imageUrl = response.data.data;
|
||||||
return imageUrl; // Return the image URL received from the server
|
return imageUrl; // Return the image URL received from the server
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Image URL not returned from server');
|
throw new Error('Image URL not returned from server');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Log detailed error information for debugging purposes
|
||||||
|
console.error('Image upload failed:', error);
|
||||||
|
|
||||||
|
// Handle specific error cases (e.g., network issues, authorization issues)
|
||||||
|
if (error.response) {
|
||||||
|
// If the error is from the server (e.g., 4xx or 5xx error)
|
||||||
|
console.error('Error response:', error.response.data);
|
||||||
|
toastStore.onToast('서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.', 'e');
|
||||||
|
} else if (error.request) {
|
||||||
|
// If no response is received from the server
|
||||||
|
console.error('No response received:', error.request);
|
||||||
|
toastStore.onToast('네트워크 오류가 발생했습니다. 잠시 후 다시 시도해주세요.', 'e');
|
||||||
|
} else {
|
||||||
|
// If the error is due to something else (e.g., invalid request setup)
|
||||||
|
console.error('Error message:', error.message);
|
||||||
|
toastStore.onToast('파일 업로드 중 문제가 발생했습니다. 다시 시도해주세요.', 'e');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw the error so the caller knows something went wrong
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
// Log detailed error information for debugging purposes
|
|
||||||
console.error('Image upload failed:', error);
|
|
||||||
|
|
||||||
// Handle specific error cases (e.g., network issues, authorization issues)
|
|
||||||
if (error.response) {
|
|
||||||
// If the error is from the server (e.g., 4xx or 5xx error)
|
|
||||||
console.error('Error response:', error.response.data);
|
|
||||||
toastStore.onToast('서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.', 'e');
|
|
||||||
} else if (error.request) {
|
|
||||||
// If no response is received from the server
|
|
||||||
console.error('No response received:', error.request);
|
|
||||||
toastStore.onToast('네트워크 오류가 발생했습니다. 잠시 후 다시 시도해주세요.', 'e');
|
|
||||||
} else {
|
|
||||||
// If the error is due to something else (e.g., invalid request setup)
|
|
||||||
console.error('Error message:', error.message);
|
|
||||||
toastStore.onToast('파일 업로드 중 문제가 발생했습니다. 다시 시도해주세요.', 'e');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throw the error so the caller knows something went wrong
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 삭제된 이미지 확인
|
// 삭제된 이미지 확인
|
||||||
function checkForDeletedImages() {
|
function checkForDeletedImages() {
|
||||||
@ -216,4 +232,3 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@
|
|||||||
:value="computedValue"
|
:value="computedValue"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:maxLength="maxlength"
|
:maxLength="maxlength"
|
||||||
:minLength="minlength"
|
|
||||||
:placeholder="title"
|
:placeholder="title"
|
||||||
@blur="$emit('blur')"
|
@blur="$emit('blur')"
|
||||||
/>
|
/>
|
||||||
@ -30,7 +29,6 @@
|
|||||||
:value="computedValue"
|
:value="computedValue"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:maxLength="maxlength"
|
:maxLength="maxlength"
|
||||||
:minLength="minlength"
|
|
||||||
:placeholder="title"
|
:placeholder="title"
|
||||||
@blur="$emit('blur')"
|
@blur="$emit('blur')"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -57,6 +57,7 @@
|
|||||||
v-if="contentLoaded"
|
v-if="contentLoaded"
|
||||||
@update:data="content = $event"
|
@update:data="content = $event"
|
||||||
@update:imageUrls="imageUrls = $event"
|
@update:imageUrls="imageUrls = $event"
|
||||||
|
@update:uploadedImgList="handleUpdateEditorImg"
|
||||||
:initialData="content"
|
:initialData="content"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -115,7 +116,7 @@
|
|||||||
const attachFilesAlert = ref(false);
|
const attachFilesAlert = ref(false);
|
||||||
const isFileValid = ref(true);
|
const isFileValid = ref(true);
|
||||||
const delFileIdx = ref([]); // 제외할 기존 첨부파일 ID
|
const delFileIdx = ref([]); // 제외할 기존 첨부파일 ID
|
||||||
const additionalFiles = ref([]); // 새로 추가할 첨부파일
|
const editorUploadedImgList = ref([]);
|
||||||
|
|
||||||
// 게시물 데이터 로드
|
// 게시물 데이터 로드
|
||||||
const fetchBoardDetails = async () => {
|
const fetchBoardDetails = async () => {
|
||||||
@ -145,6 +146,10 @@
|
|||||||
contentLoaded.value = true;
|
contentLoaded.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUpdateEditorImg = item => {
|
||||||
|
editorUploadedImgList.value = item;
|
||||||
|
};
|
||||||
|
|
||||||
// 기존 첨부파일명을 노출
|
// 기존 첨부파일명을 노출
|
||||||
const addDisplayFileName = fileInfos =>
|
const addDisplayFileName = fileInfos =>
|
||||||
fileInfos.map(file => ({
|
fileInfos.map(file => ({
|
||||||
@ -247,6 +252,11 @@
|
|||||||
boardData.delFileIdx = [...delFileIdx.value];
|
boardData.delFileIdx = [...delFileIdx.value];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 에디터에 업로드 된 이미지 인덱스 목록
|
||||||
|
if (editorUploadedImgList.value && editorUploadedImgList.value.length > 0) {
|
||||||
|
boardData.editorUploadedImgList = [...editorUploadedImgList.value];
|
||||||
|
}
|
||||||
|
|
||||||
const fileArray = newFileFilter(attachFiles);
|
const fileArray = newFileFilter(attachFiles);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
|
|||||||
@ -83,7 +83,7 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label class="col-md-2 col-form-label"> 내용 <span class="text-danger">*</span> </label>
|
<label class="col-md-2 col-form-label"> 내용 <span class="text-danger">*</span> </label>
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<QEditor @update:data="content = $event" />
|
<QEditor @update:data="content = $event" @update:uploadedImgList="handleUpdateEditorImg" />
|
||||||
</div>
|
</div>
|
||||||
<div class="invalid-feedback mt-1" :class="contentAlert ? 'd-block' : 'd-none'">내용을 입력해주세요.</div>
|
<div class="invalid-feedback mt-1" :class="contentAlert ? 'd-block' : 'd-none'">내용을 입력해주세요.</div>
|
||||||
</div>
|
</div>
|
||||||
@ -127,6 +127,7 @@
|
|||||||
const maxFiles = 5;
|
const maxFiles = 5;
|
||||||
const maxSize = 10 * 1024 * 1024;
|
const maxSize = 10 * 1024 * 1024;
|
||||||
const fileError = ref('');
|
const fileError = ref('');
|
||||||
|
const editorUploadedImgList = ref([]);
|
||||||
|
|
||||||
const fetchCategories = async () => {
|
const fetchCategories = async () => {
|
||||||
const response = await axios.get('board/categories');
|
const response = await axios.get('board/categories');
|
||||||
@ -143,6 +144,10 @@
|
|||||||
|
|
||||||
const fileCount = computed(() => attachFiles.value.length);
|
const fileCount = computed(() => attachFiles.value.length);
|
||||||
|
|
||||||
|
const handleUpdateEditorImg = item => {
|
||||||
|
editorUploadedImgList.value = item;
|
||||||
|
};
|
||||||
|
|
||||||
const handleFileUpload = files => {
|
const handleFileUpload = files => {
|
||||||
const validFiles = files.filter(file => file.size <= maxSize);
|
const validFiles = files.filter(file => file.size <= maxSize);
|
||||||
if (files.some(file => file.size > maxSize)) {
|
if (files.some(file => file.size > maxSize)) {
|
||||||
@ -215,6 +220,11 @@
|
|||||||
LOCBRDTYP: categoryValue.value,
|
LOCBRDTYP: categoryValue.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 에디터에 업로드 된 이미지 인덱스 목록
|
||||||
|
if (editorUploadedImgList.value && editorUploadedImgList.value.length > 0) {
|
||||||
|
boardData.editorUploadedImgList = [...editorUploadedImgList.value];
|
||||||
|
}
|
||||||
|
|
||||||
const { data: boardResponse } = await axios.post('board', boardData);
|
const { data: boardResponse } = await axios.post('board', boardData);
|
||||||
const boardId = boardResponse.data;
|
const boardId = boardResponse.data;
|
||||||
// 첨부파일 업로드 (비동기 병렬 처리)
|
// 첨부파일 업로드 (비동기 병렬 처리)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user