--- client/views/pages/main/AIDashboard.vue
+++ client/views/pages/main/AIDashboard.vue
... | ... | @@ -223,7 +223,7 @@ |
223 | 223 |
<p>재촬영</p> |
224 | 224 |
</button> |
225 | 225 |
|
226 |
- <button class="login-btn" type="submit" @click="goToPage('PhotoEdit')"> |
|
226 |
+ <button class="login-btn" type="submit" @click="goToPageImg('PhotoEdit')"> |
|
227 | 227 |
<img src="../../../resources/img/btn07_s.png" alt=""> |
228 | 228 |
<p>완성</p> |
229 | 229 |
</button> |
... | ... | @@ -266,11 +266,11 @@ |
266 | 266 |
<p>학습 종료하기</p> |
267 | 267 |
</button> |
268 | 268 |
<h2 class="mb40 mt10">이 단원을 끝낸 친구들</h2> |
269 |
- <article class=" flex-column" style="gap: 5px;"> |
|
269 |
+ <article class="flex-column" style="gap: 5px;"> |
|
270 | 270 |
<div class="flex" style="gap: 5px;"> |
271 |
- <div @click="buttonSearch" class="photo"><img src="../../../resources/img/img143_75s.png" alt=""> |
|
272 |
- </div> |
|
273 |
- <div @click="buttonSearch" class="photo"><img src="../../../resources/img/img143_75s.png" alt=""> |
|
271 |
+ <div v-for="(image, index) in images" :key="image.fileId" @click="buttonSearch(image)" |
|
272 |
+ class="photo"> |
|
273 |
+ <img :src="image.url" :alt="image.fileNm" reloadable="true" /> |
|
274 | 274 |
</div> |
275 | 275 |
</div> |
276 | 276 |
</article> |
... | ... | @@ -305,6 +305,7 @@ |
305 | 305 |
<script> |
306 | 306 |
import SvgIcon from '@jamescoyle/vue-icon'; |
307 | 307 |
import { mdiMagnify, mdiHeart, mdiWindowClose } from '@mdi/js'; |
308 |
+import axios from 'axios'; |
|
308 | 309 |
|
309 | 310 |
export default { |
310 | 311 |
data() { |
... | ... | @@ -364,11 +365,74 @@ |
364 | 365 |
|
365 | 366 |
|
366 | 367 |
isHidden: false, |
368 |
+ images: [] |
|
367 | 369 |
|
368 | 370 |
} |
369 | 371 |
}, |
370 | 372 |
methods: { |
373 |
+ async findFile(file_mng_id) { |
|
374 |
+ try { |
|
375 |
+ const res = await axios({ |
|
376 |
+ url: "/file/find.json", |
|
377 |
+ method: "post", |
|
378 |
+ headers: { |
|
379 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
380 |
+ }, |
|
381 |
+ data: { |
|
382 |
+ file_mng_id: file_mng_id, |
|
383 |
+ }, |
|
384 |
+ }); |
|
385 |
+ return res.data.list[0]; |
|
386 |
+ } catch (error) { |
|
387 |
+ console.log("result - error : ", error); |
|
388 |
+ return null; |
|
389 |
+ } |
|
390 |
+ }, |
|
391 |
+ fetchImage() { |
|
392 |
+ axios({ |
|
393 |
+ url: "/photo/photoUnitList.json", |
|
394 |
+ method: "post", |
|
395 |
+ headers: { |
|
396 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
397 |
+ }, |
|
398 |
+ data: { |
|
399 |
+ unitId: "UNIT_000000000000001", |
|
400 |
+ sclsId: "1" |
|
401 |
+ } |
|
402 |
+ }) |
|
403 |
+ .then(response => { |
|
404 |
+ this.file_mng_id = response.data; |
|
371 | 405 |
|
406 |
+ const findFilePromises = this.file_mng_id.map(id => |
|
407 |
+ this.findFile(id.file_mng_id) |
|
408 |
+ ); |
|
409 |
+ |
|
410 |
+ return Promise.all(findFilePromises); |
|
411 |
+ }) |
|
412 |
+ .then(fileResults => { |
|
413 |
+ // Format file results to include image URL |
|
414 |
+ this.images = fileResults.map(file => { |
|
415 |
+ if (file) { |
|
416 |
+ return { |
|
417 |
+ url: "http://localhost:9080/" + `${file.fileRpath}`, |
|
418 |
+ fileId: file.fileId, |
|
419 |
+ fileNm: file.fileNm, |
|
420 |
+ // Add any other properties you need here |
|
421 |
+ }; |
|
422 |
+ } |
|
423 |
+ return null; |
|
424 |
+ }).filter(image => image !== null); |
|
425 |
+ }) |
|
426 |
+ .catch(error => { |
|
427 |
+ console.error("Error fetching images:", error); |
|
428 |
+ }); |
|
429 |
+ }, |
|
430 |
+ goToPageImg(page) { |
|
431 |
+ const canvas = document.querySelector('canvas'); |
|
432 |
+ const dataURL = canvas.toDataURL('image/png'); |
|
433 |
+ |
|
434 |
+ this.$router.push({ name: page, query: { image: encodeURIComponent(dataURL) } }); |
|
435 |
+ }, |
|
372 | 436 |
finishSchedule() { |
373 | 437 |
this.isHidden = true; |
374 | 438 |
}, |
... | ... | @@ -761,6 +825,7 @@ |
761 | 825 |
mounted() { |
762 | 826 |
console.log('main mounted'); |
763 | 827 |
|
828 |
+ this.fetchImage(); |
|
764 | 829 |
|
765 | 830 |
}, |
766 | 831 |
computed() { |
--- client/views/pages/main/PhotoEdit.vue
+++ client/views/pages/main/PhotoEdit.vue
... | ... | @@ -1,31 +1,32 @@ |
1 | 1 |
<template> |
2 |
- <div class="content-wrap " > |
|
2 |
+ <div class="content-wrap "> |
|
3 | 3 |
<div class="flex justify-center"> |
4 | 4 |
<div> |
5 | 5 |
<div class="frame title-box"> |
6 |
- <div class="photo" > |
|
7 |
- <img src="../../../resources/img/img143_75s.png" alt=""> |
|
6 |
+ <div class="photo"> |
|
7 |
+ <img :src="imageSrc" alt=""> |
|
8 | 8 |
</div> |
9 | 9 |
<p class="title mt20" style="color: #fff;">2024.07.01 1단원 완료!</p> |
10 |
- |
|
10 |
+ |
|
11 | 11 |
</div> |
12 | 12 |
<div class="btn-wrap flex justify-center mt40" style="gap: 40px;"> |
13 |
- <button class="login-btn" @click="goToPage('PhotoDesign')"> |
|
14 |
- <img src="../../../resources/img/btn07_s.png" alt=""> |
|
15 |
- <p>수정하기</p> |
|
16 |
- </button> |
|
17 |
- |
|
18 |
- <button class="login-btn" type="submit" @click="goToPage('Dashboard')"><img |
|
19 |
- src="../../../resources/img/btn07_s.png" alt=""> |
|
20 |
- <p>완료</p> |
|
21 |
- </button> |
|
22 |
- </div> |
|
13 |
+ <button class="login-btn" @click="goToPage('PhotoDesign')"> |
|
14 |
+ <img src="../../../resources/img/btn07_s.png" alt=""> |
|
15 |
+ <p>수정하기</p> |
|
16 |
+ </button> |
|
17 |
+ |
|
18 |
+ <button class="login-btn" type="submit" @click="insertPhoto()"><img src="../../../resources/img/btn07_s.png" |
|
19 |
+ alt=""> |
|
20 |
+ <p>완료</p> |
|
21 |
+ </button> |
|
22 |
+ </div> |
|
23 | 23 |
</div> |
24 | 24 |
</div> |
25 | 25 |
</div> |
26 | 26 |
</template> |
27 | 27 |
|
28 | 28 |
<script> |
29 |
+import axios from 'axios'; |
|
29 | 30 |
export default { |
30 | 31 |
data() { |
31 | 32 |
return { |
... | ... | @@ -35,13 +36,82 @@ |
35 | 36 |
], |
36 | 37 |
timer: '00', |
37 | 38 |
selectedIndex: 0, |
39 |
+ |
|
40 |
+ imageSrc: '', |
|
41 |
+ file: '', |
|
42 |
+ fileId: '', |
|
38 | 43 |
} |
39 | 44 |
}, |
40 | 45 |
methods: { |
46 |
+ async fetchImageAsFile(imageUrl, filename = "image.jpg") { |
|
47 |
+ try { |
|
48 |
+ const response = await fetch(imageUrl); |
|
49 |
+ const blob = await response.blob(); |
|
50 |
+ |
|
51 |
+ const file = new File([blob], filename, { type: blob.type }); |
|
52 |
+ |
|
53 |
+ return file; |
|
54 |
+ } catch (error) { |
|
55 |
+ console.error("이미지 변환 오류:", error); |
|
56 |
+ throw new Error("이미지 변환에 실패했습니다."); |
|
57 |
+ } |
|
58 |
+ }, |
|
59 |
+ async fetchPhoto() { |
|
60 |
+ const image = this.$route.query.image; |
|
61 |
+ if (image) { |
|
62 |
+ this.imageSrc = decodeURIComponent(image); |
|
63 |
+ try { |
|
64 |
+ this.file = await this.fetchImageAsFile(this.imageSrc, "image.jpg"); |
|
65 |
+ } catch (error) { |
|
66 |
+ console.error("파일 변환 오류:", error); |
|
67 |
+ } |
|
68 |
+ } |
|
69 |
+ }, async uploadFiles(file) { |
|
70 |
+ if (!file) { |
|
71 |
+ console.error("파일이 없습니다."); |
|
72 |
+ throw new Error("파일이 없습니다."); |
|
73 |
+ } |
|
74 |
+ const formData = new FormData(); |
|
75 |
+ formData.append("files", file); |
|
76 |
+ |
|
77 |
+ try { |
|
78 |
+ const response = await axios.post("/file/upload.json", formData, { |
|
79 |
+ headers: { |
|
80 |
+ "Content-Type": "multipart/form-data", |
|
81 |
+ }, |
|
82 |
+ }); |
|
83 |
+ |
|
84 |
+ return response.data.fileMngId; // 서버에서 반환된 파일 매니지 ID |
|
85 |
+ } catch (error) { |
|
86 |
+ console.error("파일 업로드 오류:", error); |
|
87 |
+ throw new Error("파일 업로드에 실패했습니다."); |
|
88 |
+ } |
|
89 |
+ }, async insertPhoto() { |
|
90 |
+ try { |
|
91 |
+ this.fileId = await this.uploadFiles(this.file); |
|
92 |
+ |
|
93 |
+ const response = await axios({ |
|
94 |
+ url: "/photo/insertPhoto.json", |
|
95 |
+ method: "post", |
|
96 |
+ headers: { |
|
97 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
98 |
+ }, |
|
99 |
+ data: { |
|
100 |
+ "photoMngId": "PHOTO_MNG_000000000000001", // 사진첩아이디 교체 |
|
101 |
+ "likeData": "0", |
|
102 |
+ "unitId": "UNIT_000000000000001", // 유닛아이디 교체 |
|
103 |
+ "stdId": "1", //학생아이디 교체 |
|
104 |
+ "fileMngId": this.fileId |
|
105 |
+ } |
|
106 |
+ }); |
|
107 |
+ this.$router.push({ name: 'AIDashboard' }); |
|
108 |
+ } catch (error) { |
|
109 |
+ console.error("사진 삽입 오류:", error); |
|
110 |
+ } |
|
111 |
+ }, |
|
41 | 112 |
updateContent(index) { |
42 |
- this.selectedIndex = index; |
|
43 |
- // this.currentCon = this.items[index].con; |
|
44 |
- }, |
|
113 |
+ this.selectedIndex = index; |
|
114 |
+ }, |
|
45 | 115 |
goToPage(page) { |
46 | 116 |
this.$router.push({ name: page }); |
47 | 117 |
}, |
... | ... | @@ -68,7 +138,7 @@ |
68 | 138 |
components: { |
69 | 139 |
}, |
70 | 140 |
mounted() { |
71 |
- |
|
141 |
+ this.fetchPhoto(); |
|
72 | 142 |
} |
73 | 143 |
} |
74 | 144 |
</script> |
... | ... | @@ -118,5 +188,8 @@ |
118 | 188 |
.pickGroup article>div>p { |
119 | 189 |
font-size: 64px; |
120 | 190 |
} |
121 |
-.popTxt{width: 101px;} |
|
191 |
+ |
|
192 |
+.popTxt { |
|
193 |
+ width: 101px; |
|
194 |
+} |
|
122 | 195 |
</style>(파일 끝에 줄바꿈 문자 없음) |
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?