
--- client/views/component/listLayout/CardStyleComponent.vue
+++ client/views/component/listLayout/CardStyleComponent.vue
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 |
<div class="result-box"> |
5 | 5 |
<div class="main-img"> |
6 | 6 |
<img v-if="name === 'M'" :src="getYouTubeThumbnail(item.link)" alt="영상 썸네일"> |
7 |
- <img v-else-if="!$isEmpty(item.thumbnail)" :src="item.thumbnail.filePath" :alt="item.sj + ' 썸네일'" loading="lazy"> |
|
7 |
+ <img v-else-if="!$isEmpty(item.thumbnail)" :src="item.thumbnail.filePath" :alt="item.sj + ' 썸네일'"> |
|
8 | 8 |
<img v-else src="client/resources/images/img6.png" alt="Not found image"> |
9 | 9 |
</div> |
10 | 10 |
<div class="text-box"> |
--- client/views/pages/bbsDcry/photo/PicHistoryInsert.vue
+++ client/views/pages/bbsDcry/photo/PicHistoryInsert.vue
... | ... | @@ -113,6 +113,13 @@ |
113 | 113 |
</div> |
114 | 114 |
</div> |
115 | 115 |
<CategorySelectModal v-if="isModalOpen" :selectedCtgries="selectedCtgries" @toggleModal="fnToggleModal" @addCtgries="fnAddCtgries" /> |
116 |
+ <div v-if="loading" class="loading-overlay"> |
|
117 |
+ <div class="loading-spinner"></div> |
|
118 |
+ <div> |
|
119 |
+ <p>등록 중입니다</p> |
|
120 |
+ <p>잠시만 기다려주세요</p> |
|
121 |
+ </div> |
|
122 |
+ </div> |
|
116 | 123 |
</template> |
117 | 124 |
<script> |
118 | 125 |
import { DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; |
... | ... | @@ -165,6 +172,8 @@ |
165 | 172 |
selectedCtgries: [], // 카테고리 목록 |
166 | 173 |
|
167 | 174 |
selectedThumb: null, |
175 |
+ |
|
176 |
+ loading: false, // 로딩 상태 추가 |
|
168 | 177 |
}; |
169 | 178 |
}, |
170 | 179 |
|
... | ... | @@ -378,6 +387,7 @@ |
378 | 387 |
return; |
379 | 388 |
} |
380 | 389 |
|
390 |
+ this.loading = true; // 로딩 시작 |
|
381 | 391 |
try { |
382 | 392 |
const formData = new FormData(); |
383 | 393 |
|
... | ... | @@ -447,6 +457,8 @@ |
447 | 457 |
alert("에러가 발생했습니다."); |
448 | 458 |
} |
449 | 459 |
console.error(error.message); |
460 |
+ } finally { |
|
461 |
+ this.loading = false; // 로딩 종료 |
|
450 | 462 |
}; |
451 | 463 |
}, |
452 | 464 |
|
--- client/views/pages/bbsDcry/video/VideoHistoryInsert.vue
+++ client/views/pages/bbsDcry/video/VideoHistoryInsert.vue
... | ... | @@ -53,7 +53,7 @@ |
53 | 53 |
<div class="invalid-feedback"><img :src="erroricon" alt=""><span>첨부파일은 건당 최대 10GB를 초과할 수 없습니다.</span></div> |
54 | 54 |
</li> |
55 | 55 |
<li class="file-insert"> |
56 |
- <input type="file" id="fileInput" class="file-input" accept="video/mp4,video/quicktime,video/x-msvideo,video/x-ms-wmv,video/webm,video/x-matroska" @change="handleFileSelect"> |
|
56 |
+ <input type="file" id="fileInput" ref="fileInput" class="file-input" accept="video/mp4,video/quicktime,video/x-msvideo,video/x-ms-wmv,video/webm,video/x-matroska" @change="handleFileSelect"> |
|
57 | 57 |
<label for="fileInput" class="file-label mb-20" @dragover.prevent="handleDragOver" @dragleave.prevent="handleDragLeave" @drop.prevent="handleDrop" :class="{ 'drag-over': isDragging }"> |
58 | 58 |
<div class="flex-center align-center"> |
59 | 59 |
<img :src="fileicon" alt=""> |
... | ... | @@ -91,6 +91,13 @@ |
91 | 91 |
<span v-if="$isEmpty(pageId)">등록</span> |
92 | 92 |
<span v-else>수정</span> |
93 | 93 |
</button> |
94 |
+ </div> |
|
95 |
+ </div> |
|
96 |
+ <div v-if="loading" class="loading-overlay"> |
|
97 |
+ <div class="loading-spinner"></div> |
|
98 |
+ <div> |
|
99 |
+ <p>등록 중입니다</p> |
|
100 |
+ <p>잠시만 기다려주세요</p> |
|
94 | 101 |
</div> |
95 | 102 |
</div> |
96 | 103 |
<CategorySelectModal v-if="isModalOpen" :selectedCtgries="selectedCtgries" @toggleModal="fnToggleModal" @addCtgries="fnAddCtgries" /> |
... | ... | @@ -144,6 +151,8 @@ |
144 | 151 |
|
145 | 152 |
multipartFiles: [], |
146 | 153 |
selectedCtgries: [], // 카테고리 목록 |
154 |
+ |
|
155 |
+ loading: false, // 로딩 상태 추가 |
|
147 | 156 |
}; |
148 | 157 |
}, |
149 | 158 |
|
... | ... | @@ -240,6 +249,7 @@ |
240 | 249 |
// 유효성 검사 |
241 | 250 |
if ((files.length + this.multipartFiles.length + this.requestDTO.files.length) > 1) { |
242 | 251 |
alert("영상 파일은 한 개만 등록 가능합니다."); |
252 |
+ this.resetFileInput(); |
|
243 | 253 |
return; |
244 | 254 |
} |
245 | 255 |
|
... | ... | @@ -249,16 +259,25 @@ |
249 | 259 |
// 파일 타입 검증 |
250 | 260 |
if (!allowedTypes.includes(fileType)) { |
251 | 261 |
alert(`${file.name} 파일은 허용되지 않는 형식입니다. 영상 파일(mp4, mov, avi, wmv, mkv, webm)만 업로드 가능합니다.`); |
262 |
+ this.resetFileInput(); |
|
252 | 263 |
return; |
253 | 264 |
} |
254 | 265 |
|
255 | 266 |
// 파일 크기 제한 검증 |
256 | 267 |
if (file.size > maxSize) { |
257 | 268 |
alert(`${file.name} 파일이 10GB를 초과합니다.`); |
269 |
+ this.resetFileInput(); |
|
258 | 270 |
return; |
259 | 271 |
} |
260 | 272 |
|
261 | 273 |
this.multipartFiles.push(file); |
274 |
+ } |
|
275 |
+ }, |
|
276 |
+ |
|
277 |
+ // 파일 입력 초기화 메서드 추가 |
|
278 |
+ resetFileInput() { |
|
279 |
+ if (this.$refs.fileInput) { |
|
280 |
+ this.$refs.fileInput.value = ''; |
|
262 | 281 |
} |
263 | 282 |
}, |
264 | 283 |
|
... | ... | @@ -298,6 +317,7 @@ |
298 | 317 |
return; |
299 | 318 |
} |
300 | 319 |
|
320 |
+ this.loading = true; // 로딩 시작 |
|
301 | 321 |
try { |
302 | 322 |
const formData = new FormData(); |
303 | 323 |
|
... | ... | @@ -362,6 +382,8 @@ |
362 | 382 |
alert("에러가 발생했습니다."); |
363 | 383 |
} |
364 | 384 |
console.error(error.message); |
385 |
+ } finally { |
|
386 |
+ this.loading = false; // 로딩 종료 |
|
365 | 387 |
}; |
366 | 388 |
}, |
367 | 389 |
|
--- client/views/pages/bbsNesDta/NewsReleaseInsert.vue
+++ client/views/pages/bbsNesDta/NewsReleaseInsert.vue
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 |
<div class="invalid-feedback"><img :src="erroricon" alt=""><span>첨부파일은 건당 최대 10GB를 초과할 수 없습니다.</span></div> |
55 | 55 |
</li> |
56 | 56 |
<li class="file-insert"> |
57 |
- <input type="file" id="fileInput" class="file-input" accept="image/jpeg,image/png,image/gif,image/jpg" @change="handleFileSelect"> |
|
57 |
+ <input type="file" id="fileInput" ref="fileInput" class="file-input" accept="image/jpeg,image/png,image/gif,image/jpg" @change="handleFileSelect"> |
|
58 | 58 |
<label for="fileInput" class="file-label mb-20" @dragover.prevent="handleDragOver" @dragleave.prevent="handleDragLeave" @drop.prevent="handleDrop" :class="{ 'drag-over': isDragging }"> |
59 | 59 |
<div class="flex-center align-center"> |
60 | 60 |
<img :src="fileicon" alt=""> |
... | ... | @@ -232,12 +232,9 @@ |
232 | 232 |
const maxSize = 10 * 1024 * 1024 * 1024; // 10GB |
233 | 233 |
|
234 | 234 |
// 유효성 검사 |
235 |
- let count = files.length + this.multipartFiles.length |
|
236 |
- if (!this.$isEmpty(this.pageId)) { |
|
237 |
- count += this.requestDTO.files.length |
|
238 |
- } |
|
239 |
- if (count > 1) { |
|
235 |
+ if ((files.length + this.multipartFiles.length + this.requestDTO.files.length) > 1) { |
|
240 | 236 |
alert("썸네일은 한 개만 등록 가능합니다."); |
237 |
+ this.resetFileInput(); |
|
241 | 238 |
return; |
242 | 239 |
} |
243 | 240 |
|
... | ... | @@ -247,12 +244,14 @@ |
247 | 244 |
// 파일 타입 검증 |
248 | 245 |
if (!allowedTypes.includes(fileType)) { |
249 | 246 |
alert(`${file.name} 파일은 허용되지 않는 형식입니다. 이미지 파일(jpg, jpeg, png, gif)만 업로드 가능합니다.`); |
247 |
+ this.resetFileInput(); |
|
250 | 248 |
return; |
251 | 249 |
} |
252 | 250 |
|
253 | 251 |
// 파일 크기 제한 검증 |
254 | 252 |
if (file.size > maxSize) { |
255 | 253 |
alert(`${file.name} 파일이 10GB를 초과합니다.`); |
254 |
+ this.resetFileInput(); |
|
256 | 255 |
return; |
257 | 256 |
} |
258 | 257 |
|
... | ... | @@ -260,6 +259,13 @@ |
260 | 259 |
} |
261 | 260 |
}, |
262 | 261 |
|
262 |
+ // 파일 입력 초기화 메서드 추가 |
|
263 |
+ resetFileInput() { |
|
264 |
+ if (this.$refs.fileInput) { |
|
265 |
+ this.$refs.fileInput.value = ''; |
|
266 |
+ } |
|
267 |
+ }, |
|
268 |
+ |
|
263 | 269 |
// 파일 삭제 |
264 | 270 |
fnDelFile(type, separator) { |
265 | 271 |
if (type === 'new') { |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?