jichoi / lms_front star
PsHooN7979 2024-08-21
240821 박세훈 대시보드에서 로드맵 문제, 지문, 단어장 이동 시 learning_id값 전달
@f7c4cd080769fe19478ec6959c82a036c7a9fe0f
client/views/pages/AppStore.js
--- client/views/pages/AppStore.js
+++ client/views/pages/AppStore.js
@@ -1,4 +1,4 @@
-import { createStore } from 'vuex';
+import { createStore } from "vuex";
 
 export default createStore({
     state: {
@@ -9,16 +9,17 @@
         schdlId: null,
         bookId: null,
         unitId: null,
+        learningId: null,
     },
     getters: {
         isLoggedIn(state) {
-            return !!state.token; 
+            return !!state.token;
         },
         getUserInfo(state) {
             return {
                 userId: state.userId,
                 authcd: state.authcd,
-            }; 
+            };
         },
         getStdId(state) {
             return state.stdId;
@@ -32,6 +33,9 @@
         getUnitId(state) {
             return state.unitId;
         },
+        getLearningId(state) {
+            return state.learningId;
+        },
     },
     mutations: {
         setToken(state, token) {
@@ -39,18 +43,19 @@
         },
         clearToken(state) {
             state.token = null;
-            state.userId = null; 
+            state.userId = null;
             state.authcd = null;
             state.stdId = null;
             state.schdlId = null;
             state.bookId = null;
             state.unitId = null;
+            state.learningId = null;
         },
         setUser(state, userId) {
-            state.userId = userId; 
+            state.userId = userId;
         },
         setAuthcd(state, authcd) {
-            state.authcd = authcd; 
+            state.authcd = authcd;
         },
         setStdId(state, stdId) {
             state.stdId = stdId;
@@ -63,40 +68,46 @@
         },
         setUnitId(state, unitId) {
             state.unitId = unitId;
-        }
+        },
+        setLearningId(state, learningId) {
+            state.learningId = learningId;
+        },
     },
     actions: {
         login({ commit }, token) {
-            commit('setToken', token); 
-            localStorage.setItem('token', token);
+            commit("setToken", token);
+            localStorage.setItem("token", token);
         },
         logout({ commit }) {
-            commit('clearToken');
-            localStorage.removeItem('token');
+            commit("clearToken");
+            localStorage.removeItem("token");
         },
         updateStdId({ commit }, payload) {
             return new Promise((resolve) => {
-                commit('setStdId', payload);
+                commit("setStdId", payload);
                 resolve();
             });
         },
         updateSchdlId({ commit }, payload) {
             return new Promise((resolve) => {
-                commit('setSchdlId', payload);
+                commit("setSchdlId", payload);
                 resolve();
             });
         },
         updateBookId({ commit }, payload) {
             return new Promise((resolve) => {
-                commit('setBookId', payload);
+                commit("setBookId", payload);
                 resolve();
             });
         },
         updateUnitId({ commit }, payload) {
             return new Promise((resolve) => {
-                commit('setUnitId', payload);
+                commit("setUnitId", payload);
                 resolve();
             });
-        }
-    }
+        },
+        updateLearningId({ commit }, learningId) {
+            commit("setLearningId", learningId);
+        },
+    },
 });
client/views/pages/main/Dashboard.vue
--- client/views/pages/main/Dashboard.vue
+++ client/views/pages/main/Dashboard.vue
@@ -1,1021 +1,755 @@
 <template>
-  <p class="title1" v-if="state === 'finish'">
-    오늘 공부를 다했어요! 너무 고생했어요!
-  </p>
-  <p class="title1" v-else-if="state === 'notRegistered'">
-    지금은 학습 루트가 등록이 안됐어요! 학습 일정에서 학습루트를 등록해볼까요?
-  </p>
-  <p class="title1" v-else-if="state === 'noProblem'">
-    교재에 등록된 문제가 없습니다.
-  </p>
-  <div v-else class="main">
-    <div class="race-wrap">
-      <div class="title-box">
-        <p class="title" style="margin-top: 7rem">{{ titleUnitName }}</p>
-        <p class="subtitle">{{ titleBookName }}</p>
-      </div>
-      <div class="race-box">
-        <div class="rabbit-start">
-          <img
-            src="../../../resources/img/img09_s.png"
-            alt=""
-            :style="{ display: rabbitPos[0] ? 'block' : 'none' }"
-          />
-        </div>
-        <div class="rcon flex justify-end mb5">
-          <div class="race-btn" @click="goToPage('Chapter1')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[1] ? 'block' : 'none' }"
-              />
+    <p class="title1" v-if="state === 'finish'">오늘 공부를 다했어요! 너무 고생했어요!</p>
+    <p class="title1" v-else-if="state === 'notRegistered'">지금은 학습 루트가 등록이 안됐어요! 학습 일정에서 학습루트를 등록해볼까요?</p>
+    <p class="title1" v-else-if="state === 'noProblem'">교재에 등록된 문제가 없습니다.</p>
+    <div v-else class="main">
+        <div class="race-wrap">
+            <div class="title-box">
+                <p class="title" style="margin-top: 7rem;">{{ titleUnitName }}</p>
+                <p class="subtitle">{{ titleBookName }}</p>
             </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="1"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[1] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[1] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[0] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter2')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[2] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="2"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[2] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[2] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[1] }}</p>
-          </div>
-        </div>
-        <div class="lcon flex justify-between mb5">
-          <div class="race-btn" @click="goToPage('Chapter2_8')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[7] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="7"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[7] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[7] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[6] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter6')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[6] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="6"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[6] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[6] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[5] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter2_8')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[5] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="5"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[5] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[5] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[4] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter2_7')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[4] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="4"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[4] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[4] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[3] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter2_8')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[3] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="3"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[3] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[3] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[2] }}</p>
-          </div>
-        </div>
-        <div class="rcon flex">
-          <div class="race-btn" @click="goToPage('Chapter8')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[8] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="8"
-            >
-              <img
-                :src="item.imgSrc3"
-                :style="{ display: !rabbitCompl[8] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc4"
-                :style="{ display: rabbitCompl[8] ? 'block' : 'none' }"
-              />
-            </button>
-            <p class="long">{{ labeledItems[7] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter2_8')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[9] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="9"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[9] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[9] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[8] }}</p>
-          </div>
-          <div class="race-btn" @click="goToPage('Chapter10')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[10] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImage(index)"
-              data-num="10"
-            >
-              <img
-                :src="item.imgSrc1"
-                :style="{ display: !rabbitCompl[10] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc2"
-                :style="{ display: rabbitCompl[10] ? 'block' : 'none' }"
-              />
-            </button>
-            <p>{{ labeledItems[9] }}</p>
-          </div>
+            <div class="race-box">
 
-          <div class="race-btn" @click="goToPage('Chapter2_8')">
-            <div class="rabbit-running">
-              <img
-                src="../../../resources/img/img09_s.png"
-                alt=""
-                :style="{ display: rabbitPos[11] ? 'block' : 'none' }"
-              />
-            </div>
-            <button
-              class="popTxt"
-              v-for="(item, index) in items"
-              :key="index"
-              @click="toggleImageAndShowPopup(index, '11')"
-              data-num="11"
-            >
-              <img
-                :src="item.imgSrc3"
-                :style="{ display: !rabbitCompl[11] ? 'block' : 'none' }"
-              />
-              <img
-                :src="item.imgSrc4"
-                :style="{ display: rabbitCompl[11] ? 'block' : 'none' }"
-              />
-            </button>
-            <p class="long">{{ labeledItems[10] }}</p>
-          </div>
-        </div>
-        <div class="race-btn">
-          <div class="rabbit-running" style="display: flex">
-            <img
-              class="rabbit-end"
-              src="../../../resources/img/img138_72s.png"
-              alt=""
-              :style="{ display: rabbitEnd ? 'block' : 'none' }"
-            />
-            <img
-              class="fireworks-end"
-              src="../../../resources/img/fireworks.gif"
-              alt=""
-              :style="{ display: rabbitEnd ? 'block' : 'none' }"
-            />
-          </div>
-        </div>
-      </div>
 
-      <!-- 팝업 -->
-      <div v-show="searchOpen2" class="popup-wrap">
-        <div class="popup-box">
-          <button
-            type="button"
-            class="popup-close-btn"
-            style="position: absolute; top: 10px; right: 10px"
-            @click="closeModal"
-          >
-            <svg-icon
-              type="mdi"
-              :path="mdiWindowClose"
-              class="close-btn"
-            ></svg-icon>
-          </button>
+                <div class="rabbit-start"><img src="../../../resources/img/img09_s.png" alt=""
+                        :style="{ display: rabbitPos[0] ? 'block' : 'none' }"></div>
+                <div class="rcon flex justify-end mb5">
+                    <div class="race-btn" @click="[goToPage('Chapter1'), storeLearningId(labeledItems[0].learning_id)]">
 
-          <div class="mb30 text-ct">
-            <p class="title1 mb20">1단원이 끝났습니다!</p>
-            <p class="title1">
-              <em class="yellow">기념사진</em>을 촬영하러 가요
-            </p>
-          </div>
-          <div class="flex justify-center">
-            <button
-              type="button"
-              title="사진촬영"
-              class="new-btn"
-              @click="openCameraModal"
-            >
-              사진 촬영
-            </button>
-          </div>
-        </div>
-      </div>
-      <!-- 카메라 모달 -->
-      <article v-show="showCameraModal" class="popup-wrap">
-        <div class="popup-box" style="top: 500px; left: 500px">
-          <div class="flex mb10 justify-between">
-            <p class="popup-title">사진 촬영</p>
-            <button type="button" class="popup-close-btn" @click="closeModal">
-              <svg-icon
-                type="mdi"
-                :path="mdiWindowClose"
-                class="close-btn"
-              ></svg-icon>
-            </button>
-          </div>
-          <div class="box">
-            <div style="width: 100%">
-              <div id="container" ref="container">
-                <video
-                  v-if="!photoTaken"
-                  autoplay="true"
-                  ref="modalVideoElement"
-                  class="mirrored"
-                  @canplay="onVideoLoaded"
-                  style="position: absolute"
-                ></video>
-                <img
-                  src="../../../resources/img/camera-rabbit.png"
-                  class="camera-rabbit"
-                  style="position: absolute"
-                />
-                <canvas ref="canvas" style="pointer-events: none"></canvas>
-              </div>
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[1] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="1">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[1] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[1] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[0].label }}</p>
+                    </div>
+                    <div class="race-btn" @click="[goToPage('Chapter2'), storeLearningId(labeledItems[1].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[2] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="2">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[2] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[2] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[1].label }}</p>
+                    </div>
+                </div>
+                <div class="lcon flex justify-between mb5">
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter2_8'), storeLearningId(labeledItems[6].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[7] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="7">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[7] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[7] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[6].label }}</p>
+                    </div>
+                    <div class="race-btn" @click="[goToPage('Chapter6'), storeLearningId(labeledItems[5].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[6] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="6">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[6] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[6] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[5].label }}</p>
+                    </div>
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter2_8'), storeLearningId(labeledItems[4].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[5] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="5">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[5] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[5] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[4].label }}</p>
+                    </div>
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter2_7'), storeLearningId(labeledItems[3].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[4] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="4">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[4] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[4] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[3].label }}</p>
+                    </div>
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter2_8'), storeLearningId(labeledItems[2].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[3] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="3">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[3] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[3] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[2].label }}</p>
+                    </div>
+                </div>
+                <div class="rcon flex">
+                    <div class="race-btn" @click="[goToPage('Chapter8'), storeLearningId(labeledItems[7].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[8] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="8">
+                            <img :src="item.imgSrc3" :style="{ display: !rabbitCompl[8] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc4" :style="{ display: rabbitCompl[8] ? 'block' : 'none' }">
+                        </button>
+                        <p class="long">{{ labeledItems[7].label }}</p>
+                    </div>
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter2_8'), storeLearningId(labeledItems[8].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[9] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="9">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[9] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[9] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[8].label }}</p>
+                    </div>
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter10'), storeLearningId(labeledItems[9].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[10] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index" @click="toggleImage(index)"
+                            data-num="10">
+                            <img :src="item.imgSrc1" :style="{ display: !rabbitCompl[10] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc2" :style="{ display: rabbitCompl[10] ? 'block' : 'none' }">
+                        </button>
+                        <p>{{ labeledItems[9].label }}</p>
+                    </div>
+
+                    <div class="race-btn"
+                        @click="[goToPage('Chapter2_8'), storeLearningId(labeledItems[10].learning_id)]">
+                        <div class="rabbit-running"><img src="../../../resources/img/img09_s.png" alt=""
+                                :style="{ display: rabbitPos[11] ? 'block' : 'none' }"></div>
+                        <button class="popTxt" v-for="(item, index) in items" :key="index"
+                            @click="toggleImageAndShowPopup(index, '11')" data-num="11">
+                            <img :src="item.imgSrc3" :style="{ display: !rabbitCompl[11] ? 'block' : 'none' }">
+                            <img :src="item.imgSrc4" :style="{ display: rabbitCompl[11] ? 'block' : 'none' }">
+                        </button>
+                        <p class="long">{{ labeledItems[10].label }}</p>
+                    </div>
+                </div>
+                <div class="race-btn">
+                    <div class="rabbit-running" style=" display: flex;"><img class="rabbit-end"
+                            src="../../../resources/img/img138_72s.png" alt=""
+                            :style="{ display: rabbitEnd ? 'block' : 'none' }">
+                        <img class="fireworks-end" src="../../../resources/img/fireworks.gif" alt=""
+                            :style="{ display: rabbitEnd ? 'block' : 'none' }">
+                    </div>
+                </div>
             </div>
-          </div>
-          <div class="flex justify-center mt20">
-            <button class="new-btn" @click="takePhoto">사진 찍기</button>
-          </div>
+
+            <!-- 팝업 -->
+            <div v-show="searchOpen2" class="popup-wrap">
+                <div class="popup-box">
+                    <button type="button" class="popup-close-btn" style="position:absolute; top:10px; right: 10px;"
+                        @click="closeModal">
+                        <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
+                    </button>
+
+                    <div class="mb30 text-ct">
+                        <p class="title1 mb20">1단원이 끝났습니다!</p>
+                        <p class="title1"><em class="yellow">기념사진</em>을 촬영하러 가요</p>
+                    </div>
+                    <div class="flex justify-center">
+                        <button type="button" title="사진촬영" class="new-btn" @click="openCameraModal">
+                            사진 촬영
+                        </button>
+                    </div>
+                </div>
+            </div>
+            <!-- 카메라 모달 -->
+            <article v-show="showCameraModal" class="popup-wrap">
+                <div class="popup-box" style="top: 500px; left:500px">
+                    <div class="flex mb10 justify-between">
+                        <p class="popup-title">사진 촬영</p>ㄹ
+                        <button type="button" class="popup-close-btn" @click="closeModal">
+                            <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
+                        </button>
+                    </div>
+                    <div class="box">
+                        <div style="width: 100%;">
+                            <div id="container" ref="container">
+                                <video v-if="!photoTaken" autoplay="true" ref="modalVideoElement" class="mirrored"
+                                    @canplay="onVideoLoaded" style="position: absolute;">
+                                </video>
+                                <img src="../../../resources/img/camera-rabbit.png" class="camera-rabbit"
+                                    style="position: absolute; ">
+                                <canvas ref="canvas" style="pointer-events: none;"></canvas>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="flex justify-center mt20">
+                        <button class="new-btn" @click="takePhoto">사진 찍기</button>
+                    </div>
+                </div>
+            </article>
         </div>
-      </article>
+
+
+
+        <div class="complete-wrap  myphoto">
+            <button class="login-btn mt10" type="submit" style="width: 100%;" @click="finishSchedule"><img
+                    src="../../../resources/img/btn07_s.png" alt="" style="width: 100%; height: 100px;">
+                <p>학습 종료하기</p>
+            </button>
+            <h2 class="mb40 mt10">이 단원을 끝낸 친구들</h2>
+
+            <article class="flex-column">
+                <div class="flex-row">
+                    <div class="flex" style="gap: 5px; flex-wrap: wrap;">
+                        <div v-for="(image, index) in images" :key="image.fileId" @click="buttonSearch(image)"
+                            class="photo" style="margin-bottom: 5px;">
+                            <img :src="image.url" :alt="image.fileNm" reloadable="true" style="height: 100%;" />
+                        </div>
+                    </div>
+                </div>
+            </article>
+            <article class="popup-wrap" v-show="searchOpen">
+                <div class="popup-box ">
+                    <div class="flex mb10  justify-between">
+                        <p class="popup-title">알림</p>
+                        <button type="button" class="popup-close-btn" @click="closeModal">
+                            <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
+                        </button>
+                    </div>
+                    <div class="box">
+                        <div style="width: 910px;"><img src="../../../resources/img/img140_747s.png" alt=""></div>
+                    </div>
+                    <div class="flex justify-between mt20">
+                        <div class="text  flex">
+                            <p class="title2 date ml30">2024-08-06</p>
+                            <span class=" title1 ml30">1단원을 마친 <em class="yellow">가나다</em>친구</span>
+                        </div>
+                        <div class="title2 flex align-center" style="gap: 10px;"><svg-icon type="mdi" :path="mdiHeart"
+                                style="color: #FFBA08;"></svg-icon>
+                            <p><em class="yellow">1</em></p>
+                        </div>
+                    </div>
+                </div>
+            </article>
+        </div>
     </div>
-
-    <div class="complete-wrap myphoto">
-      <button
-        class="login-btn mt10"
-        type="submit"
-        style="width: 100%"
-        @click="finishSchedule"
-      >
-        <img
-          src="../../../resources/img/btn07_s.png"
-          alt=""
-          style="width: 100%; height: 100px"
-        />
-        <p>학습 종료하기</p>
-      </button>
-      <h2 class="mb40 mt10">이 단원을 끝낸 친구들</h2>
-
-      <article class="flex-column">
-        <div class="flex-row">
-          <div class="flex" style="gap: 5px; flex-wrap: wrap">
-            <div
-              v-for="(image, index) in images"
-              :key="image.fileId"
-              @click="buttonSearch(image)"
-              class="photo"
-              style="margin-bottom: 5px"
-            >
-              <img
-                :src="image.url"
-                :alt="image.fileNm"
-                reloadable="true"
-                style="height: 100%"
-              />
-            </div>
-          </div>
-        </div>
-      </article>
-      <article class="popup-wrap" v-show="searchOpen">
-        <div class="popup-box">
-          <div class="flex mb10 justify-between">
-            <p class="popup-title">알림</p>
-            <button type="button" class="popup-close-btn" @click="closeModal">
-              <svg-icon
-                type="mdi"
-                :path="mdiWindowClose"
-                class="close-btn"
-              ></svg-icon>
-            </button>
-          </div>
-          <div class="box">
-            <div style="width: 910px">
-              <img src="../../../resources/img/img140_747s.png" alt="" />
-            </div>
-          </div>
-          <div class="flex justify-between mt20">
-            <div class="text flex">
-              <p class="title2 date ml30">2024-08-06</p>
-              <span class="title1 ml30"
-                >1단원을 마친 <em class="yellow">가나다</em>친구</span
-              >
-            </div>
-            <div class="title2 flex align-center" style="gap: 10px">
-              <svg-icon
-                type="mdi"
-                :path="mdiHeart"
-                style="color: #ffba08"
-              ></svg-icon>
-              <p><em class="yellow">1</em></p>
-            </div>
-          </div>
-        </div>
-      </article>
-    </div>
-  </div>
 </template>
 
 <script>
-import SvgIcon from "@jamescoyle/vue-icon";
-import { mdiMagnify, mdiHeart, mdiWindowClose } from "@mdi/js";
-import axios from "axios";
-import { mapGetters } from "vuex";
+import SvgIcon from '@jamescoyle/vue-icon';
+import { mdiMagnify, mdiHeart, mdiWindowClose } from '@mdi/js';
+import axios from 'axios';
+import { mapGetters } from 'vuex';
+import { mapActions } from "vuex";
 
 export default {
-  data() {
-    return {
-      items: [
-        {
-          imgSrc1: "client/resources/img/img11_1_s.png",
-          imgSrc2: "client/resources/img/img12_1_s.png",
-          imgSrc3: "client/resources/img/img11_2_s.png",
-          imgSrc4: "client/resources/img/img12_2_s.png",
-          isSecondImageVisible: false,
-        },
-      ],
-      mdiMagnify: mdiMagnify,
-      mdiWindowClose: mdiWindowClose,
-      mdiHeart: mdiHeart,
-      showModal: false,
-      searchOpen: false, // 사진 상세보기 모달창
-      searchOpen2: false, // 단원 마친 후, 사진 촬영 여부 선택 모달창
-      showCameraModal: false, // 카메라 모달창
-      photoTaken: false,
-      photo: null, //캡쳐 사진
-      stream: null,
+    data() {
+        return {
+            items: [
+                {
+                    imgSrc1: 'client/resources/img/img11_1_s.png',
+                    imgSrc2: 'client/resources/img/img12_1_s.png',
+                    imgSrc3: 'client/resources/img/img11_2_s.png',
+                    imgSrc4: 'client/resources/img/img12_2_s.png',
+                    isSecondImageVisible: false
+                },
+            ],
+            mdiMagnify: mdiMagnify,
+            mdiWindowClose: mdiWindowClose,
+            mdiHeart: mdiHeart,
+            showModal: false,
+            searchOpen: false,  // 사진 상세보기 모달창
+            searchOpen2: false, // 단원 마친 후, 사진 촬영 여부 선택 모달창
+            showCameraModal: false, // 카메라 모달창 
+            photoTaken: false,
+            photo: null,    //캡쳐 사진 
+            stream: null,
 
-      roadmapData: [],
-      labeledItems: [],
 
-      problemCounter: 0,
-      wordCounter: 0,
-      textCounter: 0,
-      evalCounter: 0,
-      book_id: null,
-      unit_id: null,
+            roadmapData: [],
+            labeledItems: [],
 
-      schedules: [],
-      nowSchedule: "",
-      state: "",
-      rabbitPos: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-      rabbitCompl: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-      rabbitEnd: false,
+            problemCounter: 0,
+            wordCounter: 0,
+            textCounter: 0,
+            evalCounter: 0,
+            book_id: null,
+            unit_id: null,
 
-      titleUnitName: "",
-      titleBookName: "",
+            schedules: [],
+            nowSchedule: "",
+            state: '',
+            rabbitPos: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            rabbitCompl: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+            rabbitEnd: false,
 
-      images: [],
-      unit_id: "",
-      book_id: "",
-    };
-  },
-  methods: {
-    checkAndFetchData() {
-      console.log("받은 Book ID:", this.getBookId);
-      console.log("받은 Unit ID:", this.getUnitId);
-      const book_id = this.getBookId;
-      const unit_id = this.getUnitId;
+            titleUnitName: "",
+            titleBookName: "",
 
-      if (!book_id || !unit_id) {
-        console.error("book_id 또는 unit_id가 설정되지 않았습니다.");
-        return;
-      }
-      this.fetchImage(unit_id);
-      this.fetchSchedule(unit_id, book_id);
-      this.fetchRoadmapData(unit_id, book_id);
-      this.fetchRabbit();
-
-      this.unit_id = unit_id;
-      this.book_id = book_id;
-
-      if (this.$route.query.reCapture == "true") {
-        this.openCameraModal();
-      }
-    },
-
-    //은진
-    async findFile(file_mng_id) {
-      try {
-        const res = await axios({
-          url: "/file/find.json",
-          method: "post",
-          headers: {
-            "Content-Type": "application/json; charset=UTF-8",
-          },
-          data: {
-            file_mng_id: file_mng_id,
-          },
-        });
-        return res.data.list[0];
-      } catch (error) {
-        console.log("result - error : ", error);
-        return null;
-      }
-    },
-    fetchImage(unit_id) {
-      axios({
-        url: "/photo/photoUnitList.json",
-        method: "post",
-        headers: {
-          "Content-Type": "application/json; charset=UTF-8",
-        },
-        data: {
-          unitId: unit_id,
-          sclsId: "1",
-        },
-      })
-        .then((response) => {
-          this.file_mng_id = response.data;
-
-          const findFilePromises = this.file_mng_id.map((id) =>
-            this.findFile(id.file_mng_id)
-          );
-
-          return Promise.all(findFilePromises);
-        })
-        .then((fileResults) => {
-          // Format file results to include image URL
-          this.images = fileResults
-            .map((file) => {
-              if (file) {
-                return {
-                  url: "http://localhost:9080/" + `${file.fileRpath}`,
-                  fileId: file.fileId,
-                  fileNm: file.fileNm,
-                  // Add any other properties you need here
-                };
-              }
-              return null;
-            })
-            .filter((image) => image !== null);
-        })
-        .catch((error) => {
-          console.error("Error fetching images:", error);
-        });
-    },
-    goToPageImg(page) {
-      const canvas = document.querySelector("canvas");
-      const dataURL = canvas.toDataURL("image/png");
-
-      this.$router.push({
-        name: page,
-        query: { image: encodeURIComponent(dataURL) },
-      });
-    },
-
-    fetchRabbit() {
-      for (var i = 0; i < 12; i++) {
-        this.rabbitPos[i] = false;
-      }
-
-      if (this.$route.query.value) {
-        this.rabbitPos[parseInt(this.$route.query.value, 10) + 1] = true;
-        for (var i = 0; i < this.$route.query.value; i++) {
-          this.rabbitCompl[i + 1] = true;
+            images: [],
+            unit_id: "",
+            book_id: "",
         }
-
-        if (this.$route.query.value === "11") {
-          this.rabbitEnd = true;
-          setTimeout(() => {
-            this.searchOpen2 = true;
-          }, 1000);
-        }
-      } else this.rabbitPos[0] = true;
     },
-    fetchSchedule(unit_id, book_id) {
-      axios({
-        url: "/schedule/selectSchedule.json",
-        method: "post",
-        headers: {
-          "Content-Type": "application/json; charset=UTF-8",
-        },
-        data: {
-          stdId: "2",
-        },
-      })
-        .then((response) => {
-          this.schedules = response.data;
+    methods: {
+        checkAndFetchData() {
+            console.log("받은 Book ID:", this.getBookId);
+            console.log("받은 Unit ID:", this.getUnitId);
+            const book_id = this.getBookId;
+            const unit_id = this.getUnitId;
 
-          if (this.schedules.length == 0) {
-            this.state = "notRegistered";
-          } else {
-            const allFinished = this.schedules.every(
-              (schedule) => schedule.finish === "T"
-            );
-            if (allFinished) {
-              this.state = "finish";
-            } else {
-              this.nowSchedule = this.schedules.find(
-                (schedule) =>
-                  schedule.finish === null || schedule.finish === "F"
-              );
-              if (this.nowSchedule) {
-                this.fetchRoadmapData(unit_id, book_id);
-                this.state = "studying";
-              } else {
-                this.state = "notRegistered";
-              }
+            if (!book_id || !unit_id) {
+                console.error("book_id 또는 unit_id가 설정되지 않았습니다.");
+                return;
             }
-          }
-        })
-        .catch((error) => {
-          console.error("Error fetching roadmap data:", error);
-        });
-    },
-    finishSchedule() {
-      axios({
-        url: "/schedule/scheduleUpdate.json",
-        method: "post",
-        headers: {
-          "Content-Type": "application/json; charset=UTF-8",
+            this.fetchImage(unit_id);
+            this.fetchSchedule(unit_id, book_id);
+            this.fetchRoadmapData(unit_id, book_id);
+            this.fetchRabbit();
+
+            this.unit_id = unit_id
+            this.book_id = book_id
+
+            if (this.$route.query.reCapture == 'true') {
+                this.openCameraModal()
+            }
         },
-        data: {
-          scheduleId: this.nowSchedule.schdl_id,
-          finish: "T",
+
+        //은진
+        async findFile(file_mng_id) {
+            try {
+                const res = await axios({
+                    url: "/file/find.json",
+                    method: "post",
+                    headers: {
+                        "Content-Type": "application/json; charset=UTF-8",
+                    },
+                    data: {
+                        file_mng_id: file_mng_id,
+                    },
+                });
+                return res.data.list[0];
+            } catch (error) {
+                console.log("result - error : ", error);
+                return null;
+            }
         },
-      })
-        .then((response) => {
-          const nextSchedule = this.schedules.find(
-            (schedule) => schedule.schdl_id > this.nowSchedule.schdl_id
-          );
-          alert("학습을 완료했습니다!");
+        fetchImage(unit_id) {
+            axios({
+                url: "/photo/photoUnitList.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    unitId: unit_id,
+                    sclsId: "1"
+                }
+            })
+                .then(response => {
+                    this.file_mng_id = response.data;
 
-          if (nextSchedule) {
-            this.nowSchedule = nextSchedule;
-            this.fetchSchedule(nextSchedule.unit_id, nextSchedule.book_id);
-            this.fetchRoadmapData(nextSchedule.unit_id, nextSchedule.book_id);
-            this.$router.push({
-              name: "Dashboard",
-              query: {
-                unit_id: nextSchedule.unit_id,
-                book_id: nextSchedule.book_id,
-              },
-            });
-          } else {
-            alert("모든 학습을 완료했습니다!");
-            this.state = "finish";
-          }
-        })
-        .catch((error) => {
-          console.error("Error updating schedule:", error);
-        });
-    },
-    fetchRoadmapData(unit_id, book_id) {
-      axios({
-        url: "/unitLearning/find.json",
-        method: "post",
-        headers: {
-          "Content-Type": "application/json; charset=UTF-8",
+                    const findFilePromises = this.file_mng_id.map(id =>
+                        this.findFile(id.file_mng_id)
+                    );
+
+                    return Promise.all(findFilePromises);
+                })
+                .then(fileResults => {
+                    // Format file results to include image URL
+                    this.images = fileResults.map(file => {
+                        if (file) {
+                            return {
+                                url: "http://localhost:9080/" + `${file.fileRpath}`,
+                                fileId: file.fileId,
+                                fileNm: file.fileNm,
+                                // Add any other properties you need here
+                            };
+                        }
+                        return null;
+                    }).filter(image => image !== null);
+                })
+                .catch(error => {
+                    console.error("Error fetching images:", error);
+                });
         },
-        data: {
-          unit_id: unit_id,
-          book_id: book_id,
+        goToPageImg(page) {
+            const canvas = document.querySelector('canvas');
+            const dataURL = canvas.toDataURL('image/png');
+
+            this.$router.push({ name: page, query: { image: encodeURIComponent(dataURL) } });
         },
-      })
-        .then((response) => {
-          if (response.data.length != 0) {
-            this.roadmapData = response.data;
-            this.titleUnitName = this.roadmapData[0].unit_nm;
-            this.titleBookName = this.roadmapData[0].book_nm;
-            this.labeledItems = this.processedRoadmap;
-          } else {
-            this.state = "noProblem";
-          }
-        })
-        .catch((error) => {
-          this.state = "noProblem";
-          console.error("Error fetching roadmap data:", error);
-        });
-    },
-    toggleImage(index) {
-      this.items[index].isSecondImageVisible =
-        !this.items[index].isSecondImageVisible;
-    },
-    ShowPopup() {
-      this.searchOpen2 = true; // 촬영 여부 묻는 모달창 열기
-    },
-    goToPage(page) {
-      const { unit_id, book_id } = this.$route.query;
-      this.$router.push({ name: page, query: { unit_id, book_id } });
-    },
-    openCameraModal() {
-      this.closeModal();
 
-      this.showCameraModal = true;
-      navigator.mediaDevices
-        .getUserMedia({ video: true })
-        .then((stream) => {
-          const modalVideo = this.$refs.modalVideoElement;
-          modalVideo.srcObject = stream;
-          this.stream = stream;
-        })
-        .catch((error) => {
-          console.log("error>>>>>>>>", error);
-          alert("웹캠이 필요한 기능입니다!");
-          this.closeModal(); // 모달창을 닫음
-        });
+        fetchRabbit() {
+            for (var i = 0; i < 12; i++) {
+                this.rabbitPos[i] = false
+            }
+
+            if (this.$route.query.value) {
+                this.rabbitPos[parseInt(this.$route.query.value, 10) + 1] = true
+                for (var i = 0; i < this.$route.query.value; i++) {
+                    this.rabbitCompl[i + 1] = true
+                }
+
+                if (this.$route.query.value === '11') {
+                    this.rabbitEnd = true;
+                    setTimeout(() => {
+                        this.searchOpen2 = true;
+                    }, 1000);
+                }
+
+            }
+            else
+                this.rabbitPos[0] = true
+        },
+        fetchSchedule(unit_id, book_id) {
+            axios({
+                url: "/schedule/selectSchedule.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    stdId: "2",
+                }
+            }).then(response => {
+                this.schedules = response.data;
+
+                if (this.schedules.length == 0) {
+                    this.state = 'notRegistered';
+                } else {
+                    const allFinished = this.schedules.every(schedule => schedule.finish === "T");
+                    if (allFinished) {
+                        this.state = 'finish';
+                    } else {
+                        this.nowSchedule = this.schedules.find(schedule => schedule.finish === null || schedule.finish === "F");
+                        if (this.nowSchedule) {
+                            this.fetchRoadmapData(unit_id, book_id);
+                            this.state = 'studying';
+                        } else {
+                            this.state = 'notRegistered';
+                        }
+                    }
+                }
+            })
+                .catch(error => {
+                    console.error("Error fetching roadmap data:", error);
+                });
+        },
+        finishSchedule() {
+            axios({
+                url: "/schedule/scheduleUpdate.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    scheduleId: this.nowSchedule.schdl_id,
+                    finish: "T"
+                }
+            })
+                .then(response => {
+                    const nextSchedule = this.schedules.find(schedule => schedule.schdl_id > this.nowSchedule.schdl_id);
+                    alert("학습을 완료했습니다!");
+
+                    if (nextSchedule) {
+                        this.nowSchedule = nextSchedule;
+                        this.fetchSchedule(nextSchedule.unit_id, nextSchedule.book_id);
+                        this.fetchRoadmapData(nextSchedule.unit_id, nextSchedule.book_id);
+                        this.$router.push({ name: 'Dashboard', query: { unit_id: nextSchedule.unit_id, book_id: nextSchedule.book_id } });
+                    } else {
+                        alert("모든 학습을 완료했습니다!");
+                        this.state = 'finish';
+                    }
+                })
+                .catch(error => {
+                    console.error("Error updating schedule:", error);
+                });
+        },
+        fetchRoadmapData(unit_id, book_id) {
+            axios({
+                url: "/unitLearning/find.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    unit_id: unit_id,
+                    book_id: book_id
+                }
+            })
+                .then(response => {
+                    if (response.data.length != 0) {
+                        this.roadmapData = response.data;
+                        this.titleUnitName = this.roadmapData[0].unit_nm
+                        this.titleBookName = this.roadmapData[0].book_nm
+                        this.labeledItems = this.processedRoadmap;
+                    } else {
+                        this.state = "noProblem"
+                    }
+                })
+                .catch(error => {
+                    this.state = "noProblem"
+                    console.error("Error fetching roadmap data:", error);
+                });
+        },
+        toggleImage(index) {
+            this.items[index].isSecondImageVisible = !this.items[index].isSecondImageVisible;
+        },
+        ShowPopup() {
+            this.searchOpen2 = true;  // 촬영 여부 묻는 모달창 열기
+        },
+        goToPage(page) {
+            // const { unit_id, book_id } = this.$route.query;
+            // this.$router.push({ name: page, query: { unit_id, book_id } });
+            this.$router.push({ name: page });
+        },
+        storeLearningId(learningId) {
+            // console.log(learningId)
+            this.$store.dispatch('updateLearningId', learningId);
+            // console.log(this.$store.getters.getLearningId)
+        },
+        openCameraModal() {
+            this.closeModal();
+
+            this.showCameraModal = true;
+            navigator.mediaDevices.getUserMedia({ video: true })
+                .then(stream => {
+                    const modalVideo = this.$refs.modalVideoElement;
+                    modalVideo.srcObject = stream;
+                    this.stream = stream;
+                })
+                .catch(error => {
+                    console.log("error>>>>>>>>", error);
+                });
+        },
+        closeModal() {  //웹캠 및 모든 팝업 닫기
+            // this.showModal = false;
+            this.searchOpen = false;
+            this.searchOpen2 = false;
+            this.showCameraModal = false;
+            this.photoTaken = false;
+            this.photo = null;
+
+            //스트림 종료
+            if (this.stream) {
+                let tracks = this.stream.getTracks();
+                tracks.forEach(track => track.stop());
+                this.stream = null;
+            }
+        },
+
+        onVideoLoaded() {
+            const video = this.$refs.modalVideoElement;
+            const canvas = this.$refs.canvas;
+            const ctx = canvas.getContext('2d');
+
+            canvas.width = video.videoWidth;
+            canvas.height = video.videoHeight;
+        }, takePhoto() {
+            const video = this.$refs.modalVideoElement;
+            const canvas = this.$refs.canvas;
+            const ctx = canvas.getContext('2d');
+
+            ctx.save(); // 현재 상태 저장
+
+            // 캔버스 좌우 반전
+            ctx.scale(-1, 1);
+            ctx.drawImage(video, -canvas.width, 0, canvas.width, canvas.height);
+
+            ctx.restore();
+
+            const overlayImg = new Image();
+            overlayImg.src = 'client/resources/img/camera-rabbit.png';
+            overlayImg.onload = () => {
+                const overlayWidth = canvas.width * 0.4;
+                const overlayHeight = (overlayImg.height / overlayImg.width) * overlayWidth;
+                const overlayX = canvas.width - overlayWidth;
+                const overlayY = canvas.height - overlayHeight;
+
+                // 오버레이 이미지 그리기
+                ctx.drawImage(overlayImg, overlayX, overlayY, overlayWidth, overlayHeight);
+
+                // 사진 저장 함수 호출
+                const dataURL = canvas.toDataURL('image/png');
+                this.$router.push({ name: 'PhotoEdit', query: { image: encodeURIComponent(dataURL), unit_id: this.unit_id, book_id: this.book_id } });
+            };
+        },
+
+
+
+        buttonSearch() {
+            this.searchOpen = true;
+        },
+        buttonSearch2() {
+            this.searchOpen2 = true;
+        },
+        closeBtn() {
+            this.searchOpen = false;
+        },
     },
-    closeModal() {
-      //웹캠 및 모든 팝업 닫기
-      // this.showModal = false;
-      this.searchOpen = false;
-      this.searchOpen2 = false;
-      this.showCameraModal = false;
-      this.photoTaken = false;
-      this.photo = null;
-
-      //스트림 종료
-      if (this.stream) {
-        let tracks = this.stream.getTracks();
-        tracks.forEach((track) => track.stop());
-        this.stream = null;
-      }
+    components: {
+        SvgIcon,
     },
-
-    onVideoLoaded() {
-      const video = this.$refs.modalVideoElement;
-      const canvas = this.$refs.canvas;
-      const ctx = canvas.getContext("2d");
-
-      canvas.width = video.videoWidth;
-      canvas.height = video.videoHeight;
+    mounted() {
+        console.log('main mounted');
+        this.checkAndFetchData();
+        // const { book_id, unit_id } = this.$route.query;
     },
-    takePhoto() {
-      const video = this.$refs.modalVideoElement;
-      const canvas = this.$refs.canvas;
-      const ctx = canvas.getContext("2d");
-
-      ctx.save(); // 현재 상태 저장
-
-      // 캔버스 좌우 반전
-      ctx.scale(-1, 1);
-      ctx.drawImage(video, -canvas.width, 0, canvas.width, canvas.height);
-
-      ctx.restore();
-
-      const overlayImg = new Image();
-      overlayImg.src = "client/resources/img/camera-rabbit.png";
-      overlayImg.onload = () => {
-        const overlayWidth = canvas.width * 0.4;
-        const overlayHeight =
-          (overlayImg.height / overlayImg.width) * overlayWidth;
-        const overlayX = canvas.width - overlayWidth;
-        const overlayY = canvas.height - overlayHeight;
-
-        // 오버레이 이미지 그리기
-        ctx.drawImage(
-          overlayImg,
-          overlayX,
-          overlayY,
-          overlayWidth,
-          overlayHeight
-        );
-
-        // 사진 저장 함수 호출
-        const dataURL = canvas.toDataURL("image/png");
-        this.$router.push({
-          name: "PhotoEdit",
-          query: {
-            image: encodeURIComponent(dataURL),
-            unit_id: this.unit_id,
-            book_id: this.book_id,
-          },
-        });
-      };
-    },
-
-    buttonSearch() {
-      this.searchOpen = true;
-    },
-    buttonSearch2() {
-      this.searchOpen2 = true;
-    },
-    closeBtn() {
-      this.searchOpen = false;
-    },
-  },
-  components: {
-    SvgIcon,
-  },
-  mounted() {
-    console.log("main mounted");
-    this.checkAndFetchData();
-    // const { book_id, unit_id } = this.$route.query;
-  },
-  watch: {
-    getBookId(newBookId) {
-      this.checkAndFetchData();
-    },
-    getUnitId(newUnitId) {
-      this.checkAndFetchData();
-    },
-  },
-  computed: {
-    ...mapGetters(["getBookId", "getUnitId"]),
-
-    processedRoadmap() {
-      let problemCounter = 0;
-      let wordCounter = 0;
-      let textCounter = 0;
-      let evalCounter = 0;
-
-      return this.roadmapData.map((item) => {
-        if (item.wd_book_id !== null) {
-          wordCounter++;
-          return `단어장${wordCounter}`;
-        } else if (item.text_id !== null) {
-          textCounter++;
-          return `지문${textCounter}`;
-        } else if (item.eval_id !== null) {
-          evalCounter++;
-          return evalCounter === 1 ? "중간평가" : "최종평가";
-        } else {
-          problemCounter++;
-          return `문제${problemCounter}`;
+    watch: {
+        getBookId(newBookId) {
+            this.checkAndFetchData();
+        },
+        getUnitId(newUnitId) {
+            this.checkAndFetchData();
         }
-      });
     },
-  },
-  beforeDestroy() {
-    // 컴포넌트가 파괴되기 전에 리스너 제거
-    window.removeEventListener("resize", this.updateCanvasRect);
-    this.$refs.canvas.removeEventListener("click", this.handleCanvasClick);
-  },
-};
+    computed: {
+        ...mapGetters(['getBookId', 'getUnitId']),
+
+        processedRoadmap() {
+            let problemCounter = 0;
+            let wordCounter = 0;
+            let textCounter = 0;
+            let evalCounter = 0;
+
+            return this.roadmapData.map(item => {
+                if (item.wd_cnt_id !== null) {
+                    wordCounter++;
+                    return { label: `단어장${wordCounter}`, learning_id: item.learning_id };
+                } else if (item.text_id !== null) {
+                    textCounter++;
+                    return { label: `지문${textCounter}`, learning_id: item.learning_id };
+                } else if (item.eval_id !== null) {
+                    evalCounter++;
+                    return { label: evalCounter === 1 ? '중간평가' : '최종평가', learning_id: item.learning_id };
+                } else {
+                    problemCounter++;
+                    return { label: `문제${problemCounter}`, learning_id: item.learning_id };
+                }
+            });
+        }
+    },
+    beforeDestroy() {
+        // 컴포넌트가 파괴되기 전에 리스너 제거
+        window.removeEventListener('resize', this.updateCanvasRect);
+        this.$refs.canvas.removeEventListener('click', this.handleCanvasClick);
+    }
+}
 </script>
 
 <style scoped>
 .body {
-  width: 1435px;
-  height: auto;
-  margin: 0 auto;
+    width: 1435px;
+    height: auto;
+    margin: 0 auto;
 }
 
 #container {
-  position: relative;
-  margin: auto;
-  border: 10px #333 solid;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  z-index: 100;
+    position: relative;
+    margin: auto;
+    border: 10px #333 solid;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 100;
 }
 
 video {
-  width: 100%;
-  height: 100%;
-  background-color: #666;
+    width: 100%;
+    height: auto;
+    background-color: #666;
 }
 
 .mirrored {
-  transform: scaleX(-1);
+    transform: scaleX(-1);
 }
 
 .new-btn:disabled {
-  background-color: #fff3d7;
-  cursor: not-allowed;
+    background-color: #FFF3D7;
+    cursor: not-allowed;
 }
 
 .sticker {
-  position: absolute;
-  cursor: move;
+    position: absolute;
+    cursor: move;
 }
 
 .sticker-handle {
-  width: 15px;
-  height: 15px;
-  background: rgba(255, 255, 255, 0.521);
-  position: absolute;
-  bottom: 0;
-  right: 0;
-  cursor: nwse-resize;
-  font-size: 13px;
-  font-weight: bolder;
-  color: rgb(63, 63, 63);
+    width: 15px;
+    height: 15px;
+    background: rgba(255, 255, 255, 0.521);
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    cursor: nwse-resize;
+    font-size: 13px;
+    font-weight: bolder;
+    color: rgb(63, 63, 63);
 }
 
 .sticker-delete {
-  position: absolute;
-  top: 0;
-  right: 0;
-  background: rgba(255, 0, 0, 0.425);
-  color: white;
-  padding: 5px;
-  cursor: pointer;
+    position: absolute;
+    top: 0;
+    right: 0;
+    background: rgba(255, 0, 0, 0.425);
+    color: white;
+    padding: 5px;
+    cursor: pointer;
 }
 
 .toolbar {
-  display: flex;
-  justify-content: center;
-  margin-top: 10px;
+    display: flex;
+    justify-content: center;
+    margin-top: 10px;
 }
 
 .toolbar button {
-  margin: 5px;
-  padding: 5px 10px;
-  cursor: pointer;
+    margin: 5px;
+    padding: 5px 10px;
+    cursor: pointer;
 }
 
 .toolbar input {
-  margin: 5px;
+    margin: 5px;
 }
 
 .rabbit-end {
-  cursor: pointer;
-  display: block;
-  position: absolute;
-  bottom: 0px;
-  left: -15px;
-  z-index: 10000;
+    cursor: pointer;
+    display: block;
+    position: absolute;
+    bottom: 0px;
+    left: -15px;
+    z-index: 10000;
 }
 
 .rabbit-running {
-  position: absolute;
-  bottom: 40px;
-  right: 110px;
-  z-index: 10000;
-  transform: scaleX(-1);
-  transition: all 0.5s ease-in-out;
+    position: absolute;
+    bottom: 40px;
+    right: 110px;
+    z-index: 10000;
+    transform: scaleX(-1);
+    transition: all 0.5s ease-in-out;
 }
 
 .fireworks-end {
-  position: absolute;
-  bottom: 70px;
-  left: -40px;
-  width: 20rem;
+    position: absolute;
+    bottom: 70px;
+    left: -40px;
+    width: 20rem;
 }
 
+
 .camera-rabbit {
-  position: absolute;
-  right: 0;
-  bottom: 0;
-  width: 40%;
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    width: 40%;
 }
-</style>
+</style>
(파일 끝에 줄바꿈 문자 없음)
Add a comment
List