diff --git a/.env.dev b/.env.dev
index 4da29f6..3d83355 100644
--- a/.env.dev
+++ b/.env.dev
@@ -3,4 +3,5 @@ VITE_DOMAIN = https://192.168.0.251:5173/
VITE_SERVER = https://192.168.0.251:10300/
VITE_API_URL = https://192.168.0.251:10300/api/
VITE_TEST_URL = https://192.168.0.251:10300/test/
+VITE_SERVER_IMG_URL = https://192.168.0.251:10300/upload/img/
VITE_KAKAO_MAP_KEY=6f092e8f45ee81186bb6d8408f66a492
\ No newline at end of file
diff --git a/.env.mine b/.env.mine
index 07aa984..3eb811c 100644
--- a/.env.mine
+++ b/.env.mine
@@ -3,4 +3,5 @@ VITE_DOMAIN = http://localhost:5173/
VITE_SERVER = http://localhost:10325/
VITE_API_URL = http://localhost:10325/api/
VITE_TEST_URL = http://localhost:10325/test/
+VITE_SERVER_IMG_URL = http://localhost:10325/upload/img/
VITE_KAKAO_MAP_KEY=6f092e8f45ee81186bb6d8408f66a492
\ No newline at end of file
diff --git a/src/components/editor/QEditor.vue b/src/components/editor/QEditor.vue
index 86deeba..b805c9d 100644
--- a/src/components/editor/QEditor.vue
+++ b/src/components/editor/QEditor.vue
@@ -45,7 +45,7 @@
-
+
내용을 확인해주세요.
@@ -71,8 +71,10 @@
const editor = ref(null); // 에디터 DOM 참조
const font = ref('nanum-gothic'); // 기본 폰트
const fontSize = ref('16px'); // 기본 폰트 크기
- const emit = defineEmits(['update:data', 'update:uploadedImgList']);
+ const emit = defineEmits(['update:data', 'update:uploadedImgList', 'update:deleteImgIndexList']);
const uploadedImgList = ref([]); // 에디터에 이미지 첨부시 업데이트 된 파일 인덱스 번호 리스트
+ const initImageIndex = ref([]); // 에디터 로드 시 이미지 인덱스 정보
+ const deleteImgIndexList = ref([]); // 에디터의 이미지 파일 수정 및 삭제 시 해당 이미지 인덱스 목록
onMounted(() => {
// 툴바에서 선택할 수 있는 폰트 목록 설정
@@ -113,16 +115,20 @@
quillInstance.format('size', fontSize.value);
});
- // 이미지 첨부 리스트가 변경 되었을때
+ // 이미지 추가 항목 체크
watch(uploadedImgList, () => {
- console.log(!23);
emit('update:uploadedImgList', uploadedImgList.value);
- console.log('uploadedImgList.value: ', uploadedImgList.value);
+ });
+
+ // 이미지 첨부 리스트가 변경(삭제) 되었을때
+ watch(deleteImgIndexList, () => {
+ emit('update:deleteImgIndexList', deleteImgIndexList.value);
});
// 초기 데이터가 있을 경우, HTML 형식으로 삽입
if (props.initialData) {
quillInstance.setContents(JSON.parse(props.initialData));
+ initCheckImageIndex();
}
// 이미지 업로드 기능 처리
@@ -141,6 +147,8 @@
checkForDeletedImages(); // 삭제된 이미지 확인
}
});
+
+ checkDeletedImages();
emit('update:data', quillInstance.getContents());
});
@@ -165,10 +173,12 @@
// 업로드 된 파일 인덱스 (게시글 저장 시 해당 인덱스 번호에 게시글 인덱스를 업데이트)
if (uploadImgIdx) {
uploadedImgList.value = [...uploadedImgList.value, uploadImgIdx];
+ initImageIndex.value = [...initImageIndex.value, uploadImgIdx];
}
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
- const fullImageUrl = `${baseUrl}${serverImageUrl.replace(/\\/g, '/')}`;
+ //const fullImageUrl = `${baseUrl}${serverImageUrl.replace(/\\/g, '/')}`;
+ const fullImageUrl = `${baseUrl}${serverImageUrl.replace(/\\/g, '/')}?imgIndex=${uploadImgIdx}`; // 이미지 경로에 index 정보 추가
const range = quillInstance.getSelection();
quillInstance.insertEmbed(range.index, 'image', fullImageUrl); // 선택된 위치에 이미지 삽입
@@ -221,7 +231,7 @@
// 삭제된 이미지 확인
function checkForDeletedImages() {
- const editorImages = document.querySelectorAll('#editor img');
+ const editorImages = document.querySelectorAll('#qEditor img');
const currentImages = new Set(Array.from(editorImages).map(img => img.src)); // 현재 에디터에 있는 이미지들
imageUrls.forEach(url => {
@@ -230,5 +240,41 @@
}
});
}
+
+ // 초기 에디터 로드 시 이미지 인덱스 정보 추출
+ function initCheckImageIndex() {
+ const editorImages = document.querySelectorAll('#qEditor img');
+ const currentImages = new Set(Array.from(editorImages).map(img => img.src)); // 현재 에디터에 있는 이미지들
+
+ currentImages.forEach(url => {
+ const index = getImgIndex(url);
+ if (index) {
+ initImageIndex.value.push(Number(index));
+ }
+ });
+ }
+
+ // 이미지에서 index 정보 추출
+ function getImgIndex(url) {
+ const params = new URLSearchParams(url.split('?')[1]);
+ return params.get('imgIndex');
+ }
+
+ // 에디터 이미지 수정 시 삭제 인덱스 확인
+ function checkDeletedImages() {
+ const editorImages = document.querySelectorAll('#qEditor img');
+ const currentImages = new Set(Array.from(editorImages).map(img => img.src));
+
+ // init 이미지 인덱스와 수정 된 이미지 값을 비교
+ const tempDeleteImgIndex = [...initImageIndex.value];
+ currentImages.forEach(url => {
+ const imgIndex = getImgIndex(url);
+ if (imgIndex) {
+ const index = tempDeleteImgIndex.indexOf(imgIndex);
+ tempDeleteImgIndex.splice(index, 1);
+ }
+ });
+ deleteImgIndexList.value = tempDeleteImgIndex;
+ }
});
diff --git a/src/views/board/BoardEdit.vue b/src/views/board/BoardEdit.vue
index 0c51296..ca83d6e 100644
--- a/src/views/board/BoardEdit.vue
+++ b/src/views/board/BoardEdit.vue
@@ -58,6 +58,7 @@
@update:data="content = $event"
@update:imageUrls="imageUrls = $event"
@update:uploadedImgList="handleUpdateEditorImg"
+ @update:deleteImgIndexList="handleDeleteEditorImg"
:initialData="content"
/>
@@ -117,6 +118,7 @@
const isFileValid = ref(true);
const delFileIdx = ref([]); // 제외할 기존 첨부파일 ID
const editorUploadedImgList = ref([]);
+ const editorDeleteImgList = ref([]);
// 게시물 데이터 로드
const fetchBoardDetails = async () => {
@@ -150,6 +152,10 @@
editorUploadedImgList.value = item;
};
+ const handleDeleteEditorImg = item => {
+ editorDeleteImgList.value = item;
+ };
+
// 기존 첨부파일명을 노출
const addDisplayFileName = fileInfos =>
fileInfos.map(file => ({
@@ -231,11 +237,6 @@
titleAlert.value = title.value.trim().length === 0;
};
- /** `content` 변경 감지하여 자동 유효성 검사 실행 */
- // watch(content, () => {
- // contentAlert.value = $common.isNotValidContent(content);
- // });
-
// 게시물 수정
const updateBoard = async () => {
if (checkValidation()) return;
@@ -257,6 +258,11 @@
boardData.editorUploadedImgList = [...editorUploadedImgList.value];
}
+ // 삭제할 에디터 이미지 인덱스
+ if (editorDeleteImgList.value && editorDeleteImgList.value.length > 0) {
+ boardData.editorDeleteImgList = [...editorDeleteImgList.value];
+ }
+
const fileArray = newFileFilter(attachFiles);
const formData = new FormData();
diff --git a/src/views/board/BoardWrite.vue b/src/views/board/BoardWrite.vue
index a6710b0..0b4c07b 100644
--- a/src/views/board/BoardWrite.vue
+++ b/src/views/board/BoardWrite.vue
@@ -92,7 +92,11 @@
@@ -121,7 +125,7 @@
const toastStore = useToastStore();
const categoryList = ref([]);
const title = ref('');
- const nickname = ref("");
+ const nickname = ref('');
const password = ref('');
const categoryValue = ref(null);
const content = ref({ ops: [] });
@@ -139,6 +143,7 @@
const maxSize = 10 * 1024 * 1024;
const fileError = ref('');
const editorUploadedImgList = ref([]);
+ const editorDeleteImgList = ref([]);
const fetchCategories = async () => {
const response = await axios.get('board/categories');
@@ -159,6 +164,10 @@
editorUploadedImgList.value = item;
};
+ const handleDeleteEditorImg = item => {
+ editorDeleteImgList.value = item;
+ };
+
const handleFileUpload = files => {
const validFiles = files.filter(file => file.size <= maxSize);
if (files.some(file => file.size > maxSize)) {
@@ -228,7 +237,14 @@
validateContent();
categoryAlert.value = categoryValue.value == null;
- if (titleAlert.value || nicknameAlert.value || passwordAlert.value || contentAlert.value || categoryAlert.value || !isFileValid.value) {
+ if (
+ titleAlert.value ||
+ nicknameAlert.value ||
+ passwordAlert.value ||
+ contentAlert.value ||
+ categoryAlert.value ||
+ !isFileValid.value
+ ) {
return;
}
@@ -246,6 +262,11 @@
boardData.editorUploadedImgList = [...editorUploadedImgList.value];
}
+ // 삭제할 에디터 이미지 인덱스
+ if (editorDeleteImgList.value && editorDeleteImgList.value.length > 0) {
+ boardData.editorDeleteImgList = [...editorDeleteImgList.value];
+ }
+
const { data: boardResponse } = await axios.post('board', boardData);
const boardId = boardResponse.data;
// 첨부파일 업로드 (비동기 병렬 처리)