From 756e0321f8e209c1efa50604d3f9804d3f60c99e Mon Sep 17 00:00:00 2001
From: Yu Sung <hwchon1234@gmail.com>
Date: Wed, 24 Apr 2024 14:22:41 +0900
Subject: [PATCH] =?UTF-8?q?=EC=8B=9C=EB=A6=AC=EC=A6=88=EC=97=90=20?=
 =?UTF-8?q?=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=B6=94=EA=B0=80=ED=95=98?=
 =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=EB=8A=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/api/audio_content_series.js           |  10 +-
 src/views/Content/ContentSeriesDetail.vue | 295 ++++++++++++++++++++--
 2 files changed, 284 insertions(+), 21 deletions(-)

diff --git a/src/api/audio_content_series.js b/src/api/audio_content_series.js
index a2c19c5..b7bfbe6 100644
--- a/src/api/audio_content_series.js
+++ b/src/api/audio_content_series.js
@@ -34,6 +34,13 @@ async function getSeriesContent(seriesId, page) {
     );
 }
 
+async function searchContentNotInSeries(seriesId, searchWord) {
+    return Vue.axios.get(
+        "/creator-admin/audio-content/series/content/search?series_id=" + seriesId +
+        "&search_word=" + searchWord
+    )
+}
+
 async function addingContentToTheSeries(seriesId, contentIdList) {
     return Vue.axios.post(
         "/creator-admin/audio-content/series/add/content",
@@ -56,5 +63,6 @@ export {
     getSeriesDetail,
     getSeriesContent,
     addingContentToTheSeries,
-    removeContentInTheSeries
+    removeContentInTheSeries,
+    searchContentNotInSeries
 }
diff --git a/src/views/Content/ContentSeriesDetail.vue b/src/views/Content/ContentSeriesDetail.vue
index b0263b7..2810713 100644
--- a/src/views/Content/ContentSeriesDetail.vue
+++ b/src/views/Content/ContentSeriesDetail.vue
@@ -12,7 +12,8 @@
               제목 : {{ series_detail.title }}
             </v-card-text>
             <v-card-text>
-              소개 : <vue-show-more-text
+              소개 :
+              <vue-show-more-text
                 :text="series_detail.introduction"
                 :lines="2"
               />
@@ -42,27 +43,18 @@
         </v-col>
         <v-col cols="8">
           <v-row>
-            <v-col cols="6" />
-            <v-col cols="3">
+            <v-col cols="8" />
+            <v-col cols="4">
               <v-btn
                 block
                 color="#3bb9f1"
                 dark
                 depressed
+                @click="showAddContent"
               >
                 콘텐츠 추가
               </v-btn>
             </v-col>
-            <v-col cols="3">
-              <v-btn
-                block
-                color="#3bb9f1"
-                dark
-                depressed
-              >
-                콘텐츠 등록
-              </v-btn>
-            </v-col>
           </v-row>
           <v-row>
             <v-col v-if="series_content_list.length > 0">
@@ -91,9 +83,9 @@
                     >
                       <td align="center">
                         <v-img
-                          max-width="100"
-                          max-height="100"
                           :src="content.coverImage"
+                          max-width="100"
+                          class="content-cover-image"
                         />
                       </td>
                       <td align="center">
@@ -110,7 +102,7 @@
                       <td align="center">
                         <v-btn
                           color="#3bb9f1"
-                          @click="removeContentInSeries(content)"
+                          @click="deleteConfirm(content)"
                         >
                           삭제
                         </v-btn>
@@ -119,6 +111,20 @@
                   </tbody>
                 </template>
               </v-simple-table>
+              <br><br>
+              <v-row
+                v-if="total_page > 0"
+                class="text-center"
+              >
+                <v-col>
+                  <v-pagination
+                    v-model="page"
+                    :length="total_page"
+                    circle
+                    @input="next"
+                  />
+                </v-col>
+              </v-row>
             </v-col>
             <v-col
               v-else
@@ -131,6 +137,150 @@
       </v-row>
     </v-container>
 
+    <v-dialog
+      v-model="show_add_series_content"
+      max-width="1000px"
+      persistent
+    >
+      <v-card>
+        <v-card-title>
+          콘텐츠 추가
+        </v-card-title>
+        <v-card-text>
+          <v-text-field
+            v-model="search_word"
+            label="콘텐츠 제목"
+            @keyup.enter="searchContentNotInSeries"
+          >
+            <v-btn
+              slot="append"
+              color="#3bb9f1"
+              dark
+              @click="searchContentNotInSeries"
+            >
+              검색
+            </v-btn>
+          </v-text-field>
+        </v-card-text>
+        <v-card-text v-if="search_content_list.length > 0 || add_content_list.length > 0">
+          <v-row>
+            <v-col>
+              검색결과
+              <v-simple-table>
+                <template v-slot:default>
+                  <thead>
+                    <tr>
+                      <th class="text-center">
+                        제목
+                      </th>
+                      <th />
+                    </tr>
+                  </thead>
+                  <tbody>
+                    <tr
+                      v-for="content in search_content_list"
+                      :key="content.contentId"
+                    >
+                      <td>{{ content.title }}</td>
+                      <td>
+                        <v-btn
+                          color="#3bb9f1"
+                          @click="addContent(content)"
+                        >
+                          추가
+                        </v-btn>
+                      </td>
+                    </tr>
+                  </tbody>
+                </template>
+              </v-simple-table>
+            </v-col>
+            <v-col v-if="add_content_list.length > 0">
+              추가할 콘텐츠
+              <v-simple-table>
+                <template>
+                  <thead>
+                    <tr>
+                      <th class="text-center">
+                        제목
+                      </th>
+                      <th />
+                    </tr>
+                  </thead>
+                  <tbody>
+                    <tr
+                      v-for="content in add_content_list"
+                      :key="content.contentId"
+                    >
+                      <td>{{ content.title }}</td>
+                      <td>
+                        <v-btn
+                          color="#3bb9f1"
+                          @click="removeContent(content)"
+                        >
+                          제거
+                        </v-btn>
+                      </td>
+                    </tr>
+                  </tbody>
+                </template>
+              </v-simple-table>
+            </v-col>
+          </v-row>
+        </v-card-text>
+        <v-card-actions v-show="!is_loading">
+          <v-spacer />
+          <v-btn
+            color="blue darken-1"
+            text
+            @click="cancel"
+          >
+            취소
+          </v-btn>
+          <v-btn
+            color="blue darken-1"
+            text
+            @click="addContentInSeries"
+          >
+            추가
+          </v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+
+    <v-dialog
+      v-model="show_delete_confirm_dialog"
+      max-width="400px"
+      persistent
+    >
+      <v-card>
+        <v-card-text />
+        <v-card-text v-if="selected_series_content !== null">
+          {{ selected_series_content.title }} 삭제하시겠습니까?
+        </v-card-text>
+        <v-card-text v-else>
+          삭제하시겠습니까?
+        </v-card-text>
+        <v-card-actions v-show="!is_loading">
+          <v-spacer />
+          <v-btn
+            color="blue darken-1"
+            text
+            @click="deleteCancel"
+          >
+            취소
+          </v-btn>
+          <v-btn
+            color="blue darken-1"
+            text
+            @click="removeContentInSeries"
+          >
+            확인
+          </v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+
     <v-dialog
       v-model="is_loading"
       max-width="400px"
@@ -166,13 +316,24 @@ export default {
       selected_series_content: null,
       page: 1,
       total_page: 0,
+
+      search_word: '',
+      add_content_list: [],
+      search_content_list: [],
+      show_add_series_content: false,
+
+      show_delete_confirm_dialog: false,
     }
   },
 
   async created() {
     this.series_id = this.$route.params.seriesId
-    await this.getSeriesDetail()
-    await this.getSeriesContentList()
+    if (this.series_id !== undefined && this.series_id > 0) {
+      await this.getSeriesDetail()
+      await this.getSeriesContentList()
+    } else {
+      this.$router.go(-1);
+    }
   },
 
   methods: {
@@ -184,6 +345,91 @@ export default {
       this.$dialog.notify.success(message)
     },
 
+    cancel() {
+      this.search_word = ''
+      this.add_content_list = []
+      this.search_content_list = []
+      this.selected_series_content = null
+      this.show_add_series_content = false
+      this.show_delete_confirm_dialog = false
+    },
+
+    deleteConfirm(series_content) {
+      this.selected_series_content = series_content
+      this.show_delete_confirm_dialog = true
+    },
+
+    deleteCancel() {
+      this.cancel();
+    },
+
+    showAddContent() {
+      this.show_add_series_content = true
+    },
+
+    addContent(content) {
+      this.search_content_list = this.search_content_list.filter((item) => {
+        return item.contentId !== content.contentId
+      });
+      this.add_content_list.push(content)
+    },
+
+    removeContent(content) {
+      this.add_content_list = this.add_content_list.filter((item) => {
+        return item.contentId !== content.contentId
+      });
+      this.search_content_list.push(content)
+    },
+
+    async searchContentNotInSeries() {
+      if (this.search_word.length < 2) {
+        this.notifyError('검색어를 2글자 이상 입력하세요.')
+        return
+      }
+
+      this.is_loading = true
+
+      try {
+        const res = await api.searchContentNotInSeries(this.series_id, this.search_word)
+
+        if (res.data.success === true) {
+          this.search_content_list = res.data.data
+          if (res.data.data.length <= 0) {
+            this.notifyError('검색결과가 없습니다.')
+          }
+        } else {
+          this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
+        }
+      } catch (e) {
+        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
+      } finally {
+        this.is_loading = false
+      }
+    },
+
+    async addContentInSeries() {
+      this.is_loading = true
+      const contentIdList = this.add_content_list.map((item) => {
+        return item.contentId
+      })
+
+      try {
+        const res = await api.addingContentToTheSeries(this.series_id, contentIdList)
+        if (res.status === 200 && res.data.success === true) {
+          this.cancel()
+          this.page = 1
+          this.total_page = 0
+          await this.getSeriesContentList()
+        } else {
+          this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
+        }
+      } catch (e) {
+        this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
+      } finally {
+        this.is_loading = false
+      }
+    },
+
     async getSeriesDetail() {
       this.is_loading = true
 
@@ -201,6 +447,10 @@ export default {
       }
     },
 
+    async next() {
+      await this.getSeriesContentList()
+    },
+
     async getSeriesContentList() {
       try {
         const res = await api.getSeriesContent(this.series_id, this.page)
@@ -221,16 +471,17 @@ export default {
       }
     },
 
-    async removeContentInSeries(content) {
+    async removeContentInSeries() {
       this.is_loading = true
 
       try {
-        const res = await api.removeContentInTheSeries(this.series_id, content.contentId)
+        const res = await api.removeContentInTheSeries(this.series_id, this.selected_series_content.contentId)
 
         if (res.status === 200 && res.data.success === true) {
           this.page = 1
           this.total_page = 0
           this.series_content_list = []
+          this.cancel()
           this.notifySuccess('삭제되었습니다.')
           await this.getSeriesContentList()
         } else {
@@ -255,6 +506,10 @@ export default {
   aspect-ratio: 1/1.4;
 }
 
+.content-cover-image {
+  aspect-ratio: 1;
+}
+
 .no-series-content {
   height: 50vh;
   margin-top: 100px;