commit
a2e457b5e8
|
@ -19,8 +19,8 @@ async function modifyAudioContent(request) {
|
||||||
return Vue.axios.put("/admin/audio-content", request)
|
return Vue.axios.put("/admin/audio-content", request)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getBannerList() {
|
async function getBannerList(tabId) {
|
||||||
return Vue.axios.get("/admin/audio-content/banner")
|
return Vue.axios.get("/admin/audio-content/banner?tabId=" + tabId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveBanner(formData) {
|
async function saveBanner(formData) {
|
||||||
|
@ -43,8 +43,8 @@ async function updateBannerOrders(ids) {
|
||||||
return Vue.axios.put('/admin/audio-content/banner/orders', {ids: ids})
|
return Vue.axios.put('/admin/audio-content/banner/orders', {ids: ids})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getCurations() {
|
async function getCurations(tabId) {
|
||||||
return Vue.axios.get("/admin/audio-content/curation")
|
return Vue.axios.get("/admin/audio-content/curation?tabId=" + tabId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveCuration(request) {
|
async function saveCuration(request) {
|
||||||
|
@ -63,6 +63,36 @@ async function getAudioContentThemeList() {
|
||||||
return Vue.axios.get("/admin/audio-content/theme")
|
return Vue.axios.get("/admin/audio-content/theme")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAudioContentMainTabList() {
|
||||||
|
return Vue.axios.get("/admin/audio-content/main/tab")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getCurationItems(curationId) {
|
||||||
|
return Vue.axios.get("/admin/audio-content/curation/items?curationId=" + curationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function searchContentItem(curationId, searchWord) {
|
||||||
|
return Vue.axios.get("/admin/audio-content/curation/search/content?curationId=" + curationId + "&searchWord=" + searchWord)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function searchSeriesItem(curationId, searchWord) {
|
||||||
|
return Vue.axios.get("/admin/audio-content/curation/search/series?curationId=" + curationId + "&searchWord=" + searchWord)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addItemToCuration(curationId, itemIdList){
|
||||||
|
return Vue.axios.post(
|
||||||
|
"/admin/audio-content/curation/add/item",
|
||||||
|
{curationId: curationId, itemIdList: itemIdList}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removeItemInCuration(curationId, itemId){
|
||||||
|
return Vue.axios.put(
|
||||||
|
"/admin/audio-content/curation/remove/item",
|
||||||
|
{curationId: curationId, itemId: itemId}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getAudioContentList,
|
getAudioContentList,
|
||||||
searchAudioContent,
|
searchAudioContent,
|
||||||
|
@ -75,5 +105,11 @@ export {
|
||||||
saveCuration,
|
saveCuration,
|
||||||
modifyCuration,
|
modifyCuration,
|
||||||
updateCurationOrders,
|
updateCurationOrders,
|
||||||
getAudioContentThemeList
|
getAudioContentThemeList,
|
||||||
|
getAudioContentMainTabList,
|
||||||
|
getCurationItems,
|
||||||
|
searchSeriesItem,
|
||||||
|
searchContentItem,
|
||||||
|
addItemToCuration,
|
||||||
|
removeItemInCuration
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
async function getRecommendSeriesList(isFree) {
|
||||||
|
return Vue.axios.get("/admin/audio-content/series/recommend?isFree=" + isFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveRecommendSeries(formData) {
|
||||||
|
return Vue.axios.post('/admin/audio-content/series/recommend', formData, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function modifyRecommendSeries(formData) {
|
||||||
|
return Vue.axios.put('/admin/audio-content/series/recommend', formData, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateRecommendSeriesOrders(ids) {
|
||||||
|
return Vue.axios.put('/admin/audio-content/series/recommend/orders', {ids: ids})
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getRecommendSeriesList,
|
||||||
|
saveRecommendSeries,
|
||||||
|
modifyRecommendSeries,
|
||||||
|
updateRecommendSeriesOrders
|
||||||
|
}
|
|
@ -80,15 +80,30 @@ const routes = [
|
||||||
name: 'ContentCuration',
|
name: 'ContentCuration',
|
||||||
component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentCuration.vue')
|
component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentCuration.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/content/curation/detail',
|
||||||
|
name: 'ContentCurationDetail',
|
||||||
|
component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentCurationDetail.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/content/series/list',
|
path: '/content/series/list',
|
||||||
name: 'ContentSeriesList',
|
name: 'ContentSeriesList',
|
||||||
component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentSeriesList.vue')
|
component: () => import(/* webpackChunkName: "series" */ '../views/Series/ContentSeriesList.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/content/series/genre',
|
path: '/content/series/genre',
|
||||||
name: 'ContentSeriesGenre',
|
name: 'ContentSeriesGenre',
|
||||||
component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentSeriesGenre.vue')
|
component: () => import(/* webpackChunkName: "series" */ '../views/Series/ContentSeriesGenre.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/content/series/new',
|
||||||
|
name: 'ContentSeriesNew',
|
||||||
|
component: () => import(/* webpackChunkName: "series" */ '../views/Series/ContentSeriesNew.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/content/series/recommend-free',
|
||||||
|
name: 'ContentSeriesRecommendFree',
|
||||||
|
component: () => import(/* webpackChunkName: "series" */ '../views/Series/ContentSeriesRecommendFree.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/promotion/event',
|
path: '/promotion/event',
|
||||||
|
|
|
@ -10,11 +10,25 @@
|
||||||
|
|
||||||
<v-container>
|
<v-container>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="10" />
|
<v-col cols="9">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selected_tab_id"
|
||||||
|
row
|
||||||
|
@change="getCurations"
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.tabId"
|
||||||
|
:label="tab.title"
|
||||||
|
:value="tab.tabId"
|
||||||
|
/>
|
||||||
|
</v-radio-group>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer />
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-btn
|
<v-btn
|
||||||
block
|
block
|
||||||
color="#9970ff"
|
color="#3bb9f1"
|
||||||
dark
|
dark
|
||||||
depressed
|
depressed
|
||||||
@click="showWriteDialog"
|
@click="showWriteDialog"
|
||||||
|
@ -45,12 +59,24 @@
|
||||||
v-for="(item, index) in props.items"
|
v-for="(item, index) in props.items"
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<td>
|
<td
|
||||||
|
@click="handleItemClick(item)"
|
||||||
|
>
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td
|
||||||
|
@click="handleItemClick(item)"
|
||||||
|
>
|
||||||
{{ item.description }}
|
{{ item.description }}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3 v-if="item.isSeries">
|
||||||
|
O
|
||||||
|
</h3>
|
||||||
|
<h3 v-else>
|
||||||
|
X
|
||||||
|
</h3>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<h3 v-if="item.isAdult">
|
<h3 v-if="item.isAdult">
|
||||||
O
|
O
|
||||||
|
@ -103,6 +129,26 @@
|
||||||
<v-card-title v-else>
|
<v-card-title v-else>
|
||||||
콘텐츠 큐레이션 등록
|
콘텐츠 큐레이션 등록
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
|
<v-card-text v-if="is_modify === false">
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col cols="4">
|
||||||
|
메인 탭
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="8">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="curation.tab_id"
|
||||||
|
row
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.tabId"
|
||||||
|
:label="tab.title"
|
||||||
|
:value="tab.tabId"
|
||||||
|
/>
|
||||||
|
</v-radio-group>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row align="center">
|
<v-row align="center">
|
||||||
<v-col cols="4">
|
<v-col cols="4">
|
||||||
|
@ -131,6 +177,19 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
|
<v-card-text v-if="is_modify === false">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="4">
|
||||||
|
시리즈 큐레이션
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="8">
|
||||||
|
<input
|
||||||
|
v-model="curation.is_series"
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="4">
|
<v-col cols="4">
|
||||||
|
@ -220,8 +279,10 @@ export default {
|
||||||
show_delete_confirm_dialog: false,
|
show_delete_confirm_dialog: false,
|
||||||
show_write_dialog: false,
|
show_write_dialog: false,
|
||||||
selected_curation: {},
|
selected_curation: {},
|
||||||
curation: {is_adult: false},
|
curation: {is_adult: false, is_series: false},
|
||||||
curations: [],
|
curations: [],
|
||||||
|
tabs: [],
|
||||||
|
selected_tab_id: 1,
|
||||||
headers: [
|
headers: [
|
||||||
{
|
{
|
||||||
text: '제목',
|
text: '제목',
|
||||||
|
@ -235,6 +296,12 @@ export default {
|
||||||
sortable: false,
|
sortable: false,
|
||||||
value: 'description',
|
value: 'description',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: '시리즈 큐레이션',
|
||||||
|
align: 'center',
|
||||||
|
sortable: false,
|
||||||
|
value: 'isSeries',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: '19금',
|
text: '19금',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -252,7 +319,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
await this.getCurations()
|
await this.getAudioContentMainTabList()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -273,22 +340,48 @@ export default {
|
||||||
this.selected_curation = item
|
this.selected_curation = item
|
||||||
|
|
||||||
this.curation.id = item.id
|
this.curation.id = item.id
|
||||||
|
this.curation.tab_id = item.tabId
|
||||||
this.curation.title = item.title
|
this.curation.title = item.title
|
||||||
this.curation.description = item.description
|
this.curation.description = item.description
|
||||||
|
this.curation.is_series = item.isSeries
|
||||||
this.curation.is_adult = item.isAdult
|
this.curation.is_adult = item.isAdult
|
||||||
|
|
||||||
this.show_write_dialog = true
|
this.show_write_dialog = true
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.curation = {is_adult: false}
|
this.curation = {is_adult: false, is_series: false}
|
||||||
this.selected_curation = {}
|
this.selected_curation = {}
|
||||||
|
|
||||||
this.is_modify = false
|
this.is_modify = false
|
||||||
this.show_write_dialog = false
|
this.show_write_dialog = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleItemClick(item) {
|
||||||
|
this.$router.push(
|
||||||
|
{
|
||||||
|
name: 'ContentCurationDetail',
|
||||||
|
params: {
|
||||||
|
curation_id: item.id,
|
||||||
|
title: item.title,
|
||||||
|
description: item.description,
|
||||||
|
is_series: item.isSeries,
|
||||||
|
is_adult: item.isAdult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
validate() {
|
validate() {
|
||||||
|
if (
|
||||||
|
this.curation.tab_id === null ||
|
||||||
|
this.curation.tab_id === undefined ||
|
||||||
|
this.curation.tab_id <= 0
|
||||||
|
) {
|
||||||
|
this.notifyError("메인 탭을 선택하세요")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.curation.title === null ||
|
this.curation.title === null ||
|
||||||
this.curation.title === undefined ||
|
this.curation.title === undefined ||
|
||||||
|
@ -320,6 +413,27 @@ export default {
|
||||||
this.show_delete_confirm_dialog = false
|
this.show_delete_confirm_dialog = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getAudioContentMainTabList() {
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.getAudioContentMainTabList()
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
const data = res.data.data
|
||||||
|
|
||||||
|
this.tabs = data.filter(item => item.title !== '홈' && item.title !== '단편')
|
||||||
|
this.selected_tab_id = this.tabs[0].tabId
|
||||||
|
await this.getCurations()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
if (!this.validate()) return;
|
if (!this.validate()) return;
|
||||||
if (this.is_loading) return;
|
if (this.is_loading) return;
|
||||||
|
@ -328,8 +442,10 @@ export default {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const request = {
|
const request = {
|
||||||
|
tabId: this.curation.tab_id,
|
||||||
title: this.curation.title,
|
title: this.curation.title,
|
||||||
description: this.curation.description,
|
description: this.curation.description,
|
||||||
|
isSeries: this.curation.is_series,
|
||||||
isAdult: this.curation.is_adult
|
isAdult: this.curation.is_adult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,6 +473,10 @@ export default {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let request = {id: this.curation.id}
|
let request = {id: this.curation.id}
|
||||||
|
if (this.selected_curation.tab_id !== this.curation.tab_id) {
|
||||||
|
request.tabId = this.curation.tab_id
|
||||||
|
}
|
||||||
|
|
||||||
if (this.selected_curation.title !== this.curation.title && this.curation.title.trim().length > 0) {
|
if (this.selected_curation.title !== this.curation.title && this.curation.title.trim().length > 0) {
|
||||||
request.title = this.curation.title
|
request.title = this.curation.title
|
||||||
}
|
}
|
||||||
|
@ -368,6 +488,10 @@ export default {
|
||||||
request.description = this.curation.description
|
request.description = this.curation.description
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.selected_curation.isSeries !== this.curation.is_series) {
|
||||||
|
request.isSeries = this.curation.is_series
|
||||||
|
}
|
||||||
|
|
||||||
if (this.selected_curation.isAdult !== this.curation.is_adult) {
|
if (this.selected_curation.isAdult !== this.curation.is_adult) {
|
||||||
request.isAdult = this.curation.is_adult
|
request.isAdult = this.curation.is_adult
|
||||||
}
|
}
|
||||||
|
@ -439,7 +563,7 @@ export default {
|
||||||
this.is_loading = true
|
this.is_loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await api.getCurations()
|
const res = await api.getCurations(this.selected_tab_id)
|
||||||
if (res.status === 200 && res.data.success === true) {
|
if (res.status === 200 && res.data.success === true) {
|
||||||
this.curations = res.data.data
|
this.curations = res.data.data
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,604 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-toolbar dark>
|
||||||
|
<v-spacer />
|
||||||
|
<v-toolbar-title>{{ curation_title }}</v-toolbar-title>
|
||||||
|
<v-spacer />
|
||||||
|
</v-toolbar>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col
|
||||||
|
cols="4"
|
||||||
|
align="right"
|
||||||
|
>
|
||||||
|
19금 :
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
align="left"
|
||||||
|
>
|
||||||
|
<div v-if="is_adult">
|
||||||
|
O
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
X
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer />
|
||||||
|
<v-col>
|
||||||
|
<v-btn
|
||||||
|
v-if="is_series"
|
||||||
|
block
|
||||||
|
color="#3bb9f1"
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
@click="showAddSeries"
|
||||||
|
>
|
||||||
|
시리즈 등록
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
v-else
|
||||||
|
block
|
||||||
|
color="#3bb9f1"
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
@click="showAddContent"
|
||||||
|
>
|
||||||
|
콘텐츠 등록
|
||||||
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col
|
||||||
|
cols="4"
|
||||||
|
align="right"
|
||||||
|
>
|
||||||
|
내용 :
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
cols="8"
|
||||||
|
align="left"
|
||||||
|
>
|
||||||
|
<vue-show-more-text
|
||||||
|
:style="{ padding: '0' }"
|
||||||
|
:text="curation_description"
|
||||||
|
:lines="2"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-simple-table class="elevation-10">
|
||||||
|
<template>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">
|
||||||
|
썸네일
|
||||||
|
</th>
|
||||||
|
<th class="text-center">
|
||||||
|
제목
|
||||||
|
</th>
|
||||||
|
<th class="text-center">
|
||||||
|
내용
|
||||||
|
</th>
|
||||||
|
<th class="text-center">
|
||||||
|
크리에이터
|
||||||
|
</th>
|
||||||
|
<th class="text-center">
|
||||||
|
19금
|
||||||
|
</th>
|
||||||
|
<th class="text-center">
|
||||||
|
관리
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="item in items"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<td align="center">
|
||||||
|
<v-img
|
||||||
|
max-width="70"
|
||||||
|
max-height="70"
|
||||||
|
:src="item.coverImageUrl"
|
||||||
|
class="rounded-circle"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<vue-show-more-text
|
||||||
|
:text="item.title"
|
||||||
|
:lines="3"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td style="max-width: 200px !important; word-break:break-all; height: auto;">
|
||||||
|
<vue-show-more-text
|
||||||
|
:text="item.detail"
|
||||||
|
:lines="3"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>{{ item.creatorNickname }}</td>
|
||||||
|
<td>
|
||||||
|
<div v-if="item.isAdult">
|
||||||
|
O
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
X
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<v-btn
|
||||||
|
:disabled="is_loading"
|
||||||
|
@click="deleteConfirm(item)"
|
||||||
|
>
|
||||||
|
삭제
|
||||||
|
</v-btn>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</template>
|
||||||
|
</v-simple-table>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="show_add_content_dialog"
|
||||||
|
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="searchContentItem"
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
slot="append"
|
||||||
|
color="#3bb9f1"
|
||||||
|
dark
|
||||||
|
@click="searchContentItem"
|
||||||
|
>
|
||||||
|
검색
|
||||||
|
</v-btn>
|
||||||
|
</v-text-field>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-text v-if="search_item_list.length > 0 || add_item_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="item in search_item_list"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<td>{{ item.title }}</td>
|
||||||
|
<td>
|
||||||
|
<v-btn
|
||||||
|
color="#3bb9f1"
|
||||||
|
@click="addItem(item)"
|
||||||
|
>
|
||||||
|
추가
|
||||||
|
</v-btn>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</template>
|
||||||
|
</v-simple-table>
|
||||||
|
</v-col>
|
||||||
|
<v-col v-if="add_item_list.length > 0">
|
||||||
|
추가할 콘텐츠
|
||||||
|
<v-simple-table>
|
||||||
|
<template>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">
|
||||||
|
제목
|
||||||
|
</th>
|
||||||
|
<th />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="item in add_item_list"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<td>{{ item.title }}</td>
|
||||||
|
<td>
|
||||||
|
<v-btn
|
||||||
|
color="#3bb9f1"
|
||||||
|
@click="removeItem(item)"
|
||||||
|
>
|
||||||
|
제거
|
||||||
|
</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="addItemInCuration"
|
||||||
|
>
|
||||||
|
추가
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="show_add_series_dialog"
|
||||||
|
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="searchSeriesItem"
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
slot="append"
|
||||||
|
color="#3bb9f1"
|
||||||
|
dark
|
||||||
|
@click="searchSeriesItem"
|
||||||
|
>
|
||||||
|
검색
|
||||||
|
</v-btn>
|
||||||
|
</v-text-field>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-text v-if="search_item_list.length > 0 || add_item_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="item in search_item_list"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<td>{{ item.title }}</td>
|
||||||
|
<td>
|
||||||
|
<v-btn
|
||||||
|
color="#3bb9f1"
|
||||||
|
@click="addItem(item)"
|
||||||
|
>
|
||||||
|
추가
|
||||||
|
</v-btn>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</template>
|
||||||
|
</v-simple-table>
|
||||||
|
</v-col>
|
||||||
|
<v-col v-if="add_item_list.length > 0">
|
||||||
|
추가할 시리즈
|
||||||
|
<v-simple-table>
|
||||||
|
<template>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">
|
||||||
|
제목
|
||||||
|
</th>
|
||||||
|
<th />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="item in add_item_list"
|
||||||
|
:key="item.id"
|
||||||
|
>
|
||||||
|
<td>{{ item.title }}</td>
|
||||||
|
<td>
|
||||||
|
<v-btn
|
||||||
|
color="#3bb9f1"
|
||||||
|
@click="removeItem(item)"
|
||||||
|
>
|
||||||
|
제거
|
||||||
|
</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="addItemInCuration"
|
||||||
|
>
|
||||||
|
추가
|
||||||
|
</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_item !== null">
|
||||||
|
{{ selected_item.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="cancel"
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="removeItemInCuration"
|
||||||
|
>
|
||||||
|
확인
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as api from "@/api/audio_content"
|
||||||
|
import VueShowMoreText from 'vue-show-more-text'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ContentCurationDetail',
|
||||||
|
|
||||||
|
components: {VueShowMoreText},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
is_loading: false,
|
||||||
|
curation_id: 0,
|
||||||
|
curation_title: '',
|
||||||
|
curation_description: '',
|
||||||
|
is_series: false,
|
||||||
|
is_adult: false,
|
||||||
|
|
||||||
|
items: [],
|
||||||
|
|
||||||
|
show_add_series_dialog: false,
|
||||||
|
show_add_content_dialog: false,
|
||||||
|
show_delete_confirm_dialog: false,
|
||||||
|
|
||||||
|
search_word: '',
|
||||||
|
selected_item: null,
|
||||||
|
add_item_list: [],
|
||||||
|
search_item_list: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async created() {
|
||||||
|
this.curation_id = this.$route.params.curation_id
|
||||||
|
this.curation_title = this.$route.params.title
|
||||||
|
this.curation_description = this.$route.params.description
|
||||||
|
this.is_series = this.$route.params.is_series
|
||||||
|
this.is_adult = this.$route.params.is_adult
|
||||||
|
await this.getCurationItems()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
notifyError(message) {
|
||||||
|
this.$dialog.notify.error(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
notifySuccess(message) {
|
||||||
|
this.$dialog.notify.success(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.search_word = ''
|
||||||
|
this.add_item_list = []
|
||||||
|
this.search_item_list = []
|
||||||
|
this.selected_item = null
|
||||||
|
this.show_add_series_dialog = false
|
||||||
|
this.show_add_content_dialog = false
|
||||||
|
this.show_delete_confirm_dialog = false
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteConfirm(item) {
|
||||||
|
this.selected_item = item
|
||||||
|
this.show_delete_confirm_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
showAddContent() {
|
||||||
|
this.show_add_content_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
showAddSeries() {
|
||||||
|
this.show_add_series_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
addItem(item) {
|
||||||
|
this.search_item_list = this.search_item_list.filter((t) => {
|
||||||
|
return t.id !== item.id
|
||||||
|
});
|
||||||
|
this.add_item_list.push(item)
|
||||||
|
},
|
||||||
|
|
||||||
|
removeItem(item) {
|
||||||
|
this.add_item_list = this.add_item_list.filter((t) => {
|
||||||
|
return t.id !== item.id
|
||||||
|
});
|
||||||
|
this.search_item_list.push(item)
|
||||||
|
},
|
||||||
|
|
||||||
|
async searchContentItem() {
|
||||||
|
if (this.search_word.length < 2) {
|
||||||
|
this.notifyError('검색어를 2글자 이상 입력하세요.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.searchContentItem(this.curation_id, this.search_word)
|
||||||
|
|
||||||
|
if (res.data.success === true) {
|
||||||
|
this.search_item_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 searchSeriesItem() {
|
||||||
|
if (this.search_word.length < 2) {
|
||||||
|
this.notifyError('검색어를 2글자 이상 입력하세요.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.searchSeriesItem(this.curation_id, this.search_word)
|
||||||
|
|
||||||
|
if (res.data.success === true) {
|
||||||
|
this.search_item_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 addItemInCuration() {
|
||||||
|
this.is_loading = true
|
||||||
|
const itemIdList = this.add_item_list.map((item) => {
|
||||||
|
return item.id
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.addItemToCuration(this.curation_id, itemIdList)
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.cancel()
|
||||||
|
await this.getCurationItems()
|
||||||
|
} else {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async removeItemInCuration() {
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.removeItemInCuration(this.curation_id, this.selected_item.id)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.cancel()
|
||||||
|
await this.getCurationItems()
|
||||||
|
} else {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async getCurationItems() {
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.getCurationItems(this.curation_id)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.items = res.data.data
|
||||||
|
} else {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -63,9 +63,6 @@
|
||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
내용
|
내용
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">
|
|
||||||
큐레이션
|
|
||||||
</th>
|
|
||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
크리에이터
|
크리에이터
|
||||||
</th>
|
</th>
|
||||||
|
@ -134,7 +131,6 @@
|
||||||
:lines="3"
|
:lines="3"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ item.curationTitle || '없음' }}</td>
|
|
||||||
<td>{{ item.creatorNickname }}</td>
|
<td>{{ item.creatorNickname }}</td>
|
||||||
<td>{{ item.theme }}</td>
|
<td>{{ item.theme }}</td>
|
||||||
<td style="max-width: 100px !important; word-break:break-all; height: auto;">
|
<td style="max-width: 100px !important; word-break:break-all; height: auto;">
|
||||||
|
@ -307,22 +303,6 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-text>
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="4">
|
|
||||||
큐레이션
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="8">
|
|
||||||
<v-select
|
|
||||||
v-model="audio_content.curation_id"
|
|
||||||
:items="curations"
|
|
||||||
item-text="title"
|
|
||||||
item-value="value"
|
|
||||||
label="큐레이션 선택"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="4">
|
<v-col cols="4">
|
||||||
|
@ -415,7 +395,6 @@ export default {
|
||||||
search_word: '',
|
search_word: '',
|
||||||
audio_content: {},
|
audio_content: {},
|
||||||
audio_contents: [],
|
audio_contents: [],
|
||||||
curations: [],
|
|
||||||
themeList: [],
|
themeList: [],
|
||||||
selected_audio_content: {},
|
selected_audio_content: {},
|
||||||
utm_source: '',
|
utm_source: '',
|
||||||
|
@ -426,7 +405,6 @@ export default {
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
await this.getAudioContentThemeList();
|
await this.getAudioContentThemeList();
|
||||||
await this.getCurations()
|
|
||||||
await this.getAudioContent()
|
await this.getAudioContent()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -455,7 +433,6 @@ export default {
|
||||||
this.audio_content.id = item.audioContentId
|
this.audio_content.id = item.audioContentId
|
||||||
this.audio_content.title = item.title
|
this.audio_content.title = item.title
|
||||||
this.audio_content.detail = item.detail
|
this.audio_content.detail = item.detail
|
||||||
this.audio_content.curation_id = item.curationId
|
|
||||||
this.audio_content.theme_id = item.themeId
|
this.audio_content.theme_id = item.themeId
|
||||||
this.audio_content.is_adult = item.isAdult
|
this.audio_content.is_adult = item.isAdult
|
||||||
this.audio_content.is_comment_available = item.isCommentAvailable
|
this.audio_content.is_comment_available = item.isCommentAvailable
|
||||||
|
@ -513,10 +490,6 @@ export default {
|
||||||
request.detail = this.audio_content.detail
|
request.detail = this.audio_content.detail
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.selected_audio_content.curationId !== this.audio_content.curation_id) {
|
|
||||||
request.curationId = this.audio_content.curation_id
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.selected_audio_content.themeId !== this.audio_content.theme_id) {
|
if (this.selected_audio_content.themeId !== this.audio_content.theme_id) {
|
||||||
request.themeId = this.audio_content.theme_id
|
request.themeId = this.audio_content.theme_id
|
||||||
}
|
}
|
||||||
|
@ -598,26 +571,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async getCurations() {
|
|
||||||
this.is_loading = true
|
|
||||||
try {
|
|
||||||
const res = await api.getCurations()
|
|
||||||
if (res.status === 200 && res.data.success === true) {
|
|
||||||
this.curations = res.data.data.map((curation) => {
|
|
||||||
return {title: curation.title, value: curation.id}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.curations.unshift({title: '없음', value: 0})
|
|
||||||
} else {
|
|
||||||
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
|
||||||
} finally {
|
|
||||||
this.is_loading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
async getAudioContent() {
|
async getAudioContent() {
|
||||||
this.is_loading = true
|
this.is_loading = true
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -16,11 +16,25 @@
|
||||||
<template v-slot:activator="{ on, attrs }">
|
<template v-slot:activator="{ on, attrs }">
|
||||||
<v-container>
|
<v-container>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="10" />
|
<v-col cols="9">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selected_tab_id"
|
||||||
|
row
|
||||||
|
@change="getBanners"
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.tabId"
|
||||||
|
:label="tab.title"
|
||||||
|
:value="tab.tabId"
|
||||||
|
/>
|
||||||
|
</v-radio-group>
|
||||||
|
</v-col>
|
||||||
|
<v-spacer />
|
||||||
<v-col>
|
<v-col>
|
||||||
<v-btn
|
<v-btn
|
||||||
block
|
block
|
||||||
color="#9970ff"
|
color="#3BB9F1"
|
||||||
dark
|
dark
|
||||||
depressed
|
depressed
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
|
@ -75,6 +89,26 @@
|
||||||
<v-card-title v-else>
|
<v-card-title v-else>
|
||||||
배너 등록
|
배너 등록
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col cols="4">
|
||||||
|
메인 탭
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="8">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="banner.tab_id"
|
||||||
|
row
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.tabId"
|
||||||
|
:label="tab.title"
|
||||||
|
:value="tab.tabId"
|
||||||
|
/>
|
||||||
|
</v-radio-group>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-row align="center">
|
<v-row align="center">
|
||||||
<v-col cols="4">
|
<v-col cols="4">
|
||||||
|
@ -293,13 +327,15 @@ export default {
|
||||||
show_write_dialog: false,
|
show_write_dialog: false,
|
||||||
show_delete_confirm_dialog: false,
|
show_delete_confirm_dialog: false,
|
||||||
selected_banner: {},
|
selected_banner: {},
|
||||||
banner: {type: 'CREATOR'},
|
banner: {type: 'CREATOR', tab_id: 1},
|
||||||
banners: [],
|
banners: [],
|
||||||
events: [],
|
events: [],
|
||||||
creators: [],
|
creators: [],
|
||||||
series: [],
|
series: [],
|
||||||
search_query_creator: '',
|
search_query_creator: '',
|
||||||
search_query_series: '',
|
search_query_series: '',
|
||||||
|
tabs: [],
|
||||||
|
selected_tab_id: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -319,7 +355,7 @@ export default {
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
await this.getEvents()
|
await this.getEvents()
|
||||||
await this.getBanners()
|
await this.getAudioContentMainTabList()
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -343,7 +379,7 @@ export default {
|
||||||
this.is_selecting = false
|
this.is_selecting = false
|
||||||
this.show_write_dialog = false
|
this.show_write_dialog = false
|
||||||
this.show_delete_confirm_dialog = false
|
this.show_delete_confirm_dialog = false
|
||||||
this.banner = {type: 'CREATOR'}
|
this.banner = {type: 'CREATOR', tab_id: 1}
|
||||||
this.selected_banner = {}
|
this.selected_banner = {}
|
||||||
this.search_query_creator = ''
|
this.search_query_creator = ''
|
||||||
this.search_query_series = ''
|
this.search_query_series = ''
|
||||||
|
@ -357,6 +393,27 @@ export default {
|
||||||
this.$dialog.notify.success(message)
|
this.$dialog.notify.success(message)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getAudioContentMainTabList() {
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await api.getAudioContentMainTabList()
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
const data = res.data.data
|
||||||
|
|
||||||
|
this.tabs = data
|
||||||
|
this.selected_tab_id = data[0].tabId
|
||||||
|
await this.getBanners()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
showModifyBannerDialog(banner) {
|
showModifyBannerDialog(banner) {
|
||||||
this.is_modify = true
|
this.is_modify = true
|
||||||
this.selected_banner = banner
|
this.selected_banner = banner
|
||||||
|
@ -374,6 +431,7 @@ export default {
|
||||||
this.banner.series_title = banner.seriesTitle
|
this.banner.series_title = banner.seriesTitle
|
||||||
this.banner.link = banner.link
|
this.banner.link = banner.link
|
||||||
this.banner.is_adult = banner.isAdult
|
this.banner.is_adult = banner.isAdult
|
||||||
|
this.banner.tab_id = banner.tabId
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.is_selecting = false; // 선택 상태 해제
|
this.is_selecting = false; // 선택 상태 해제
|
||||||
|
@ -452,6 +510,10 @@ export default {
|
||||||
request.seriesId = this.banner.series_id
|
request.seriesId = this.banner.series_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.banner.tab_id !== 1) {
|
||||||
|
request.tabId = this.banner.tab_id
|
||||||
|
}
|
||||||
|
|
||||||
formData.append("request", JSON.stringify(request))
|
formData.append("request", JSON.stringify(request))
|
||||||
|
|
||||||
const res = await api.saveBanner(formData)
|
const res = await api.saveBanner(formData)
|
||||||
|
@ -523,6 +585,10 @@ export default {
|
||||||
request.isAdult = this.banner.is_adult
|
request.isAdult = this.banner.is_adult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.selected_banner.tabId !== this.banner.tab_id) {
|
||||||
|
request.tabId = this.banner.tab_id
|
||||||
|
}
|
||||||
|
|
||||||
formData.append("request", JSON.stringify(request))
|
formData.append("request", JSON.stringify(request))
|
||||||
|
|
||||||
const res = await api.modifyBanner(formData)
|
const res = await api.modifyBanner(formData)
|
||||||
|
@ -680,7 +746,7 @@ export default {
|
||||||
async getBanners() {
|
async getBanners() {
|
||||||
this.is_loading = true
|
this.is_loading = true
|
||||||
try {
|
try {
|
||||||
const res = await api.getBannerList()
|
const res = await api.getBannerList(this.selected_tab_id)
|
||||||
if (res.status === 200 && res.data.success === true) {
|
if (res.status === 200 && res.data.success === true) {
|
||||||
this.banners = res.data.data
|
this.banners = res.data.data
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,481 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-toolbar dark>
|
||||||
|
<v-spacer />
|
||||||
|
<v-toolbar-title>새로운 시리즈</v-toolbar-title>
|
||||||
|
<v-spacer />
|
||||||
|
</v-toolbar>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="show_write_dialog"
|
||||||
|
max-width="1000px"
|
||||||
|
persistent
|
||||||
|
>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="9" />
|
||||||
|
<v-spacer />
|
||||||
|
<v-col>
|
||||||
|
<v-btn
|
||||||
|
block
|
||||||
|
color="#3BB9F1"
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
>
|
||||||
|
새로운 시리즈 등록
|
||||||
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<draggable
|
||||||
|
v-model="recommend_series_list"
|
||||||
|
class="row"
|
||||||
|
@end="onDropCallback(recommend_series_list)"
|
||||||
|
>
|
||||||
|
<v-col
|
||||||
|
v-for="(item, i) in recommend_series_list"
|
||||||
|
:key="i"
|
||||||
|
cols="3"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
<v-spacer />
|
||||||
|
<v-img :src="item.imageUrl" />
|
||||||
|
<v-spacer />
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
@click="showModifyRecommendSeriesDialog(item)"
|
||||||
|
>
|
||||||
|
수정
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
@click="deleteConfirm(item)"
|
||||||
|
>
|
||||||
|
삭제
|
||||||
|
</v-btn>
|
||||||
|
<v-spacer />
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</draggable>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-card>
|
||||||
|
<v-card-title v-if="is_modify === true">
|
||||||
|
새로운 시리즈 수정
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-title v-else>
|
||||||
|
새로운 시리즈 등록
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col cols="4">
|
||||||
|
시리즈
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="8">
|
||||||
|
<v-combobox
|
||||||
|
v-model="recommend_series.series_title"
|
||||||
|
:items="series"
|
||||||
|
:loading="is_loading"
|
||||||
|
:search-input.sync="search_query_series"
|
||||||
|
label="시리즈를 검색하세요"
|
||||||
|
item-text="name"
|
||||||
|
item-value="value"
|
||||||
|
no-data-text="No results found"
|
||||||
|
hide-selected
|
||||||
|
clearable
|
||||||
|
@change="onSelectSeries"
|
||||||
|
@update:search-input="onSearchSeriesUpdate"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<div class="image-select">
|
||||||
|
<label for="image">
|
||||||
|
새로운 시리즈 이미지 등록
|
||||||
|
</label>
|
||||||
|
<v-file-input
|
||||||
|
id="image"
|
||||||
|
v-model="recommend_series.image"
|
||||||
|
@change="imageAdd"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
v-if="recommend_series.image_url"
|
||||||
|
:src="recommend_series.image_url"
|
||||||
|
alt=""
|
||||||
|
class="image-preview"
|
||||||
|
>
|
||||||
|
<v-card-actions v-show="!is_loading">
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="cancel"
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
v-if="is_modify === true"
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="modify"
|
||||||
|
>
|
||||||
|
수정
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
v-else
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="submit"
|
||||||
|
>
|
||||||
|
등록
|
||||||
|
</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-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="deleteRecommendSeries"
|
||||||
|
>
|
||||||
|
확인
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Draggable from "vuedraggable";
|
||||||
|
import debounce from "lodash/debounce";
|
||||||
|
|
||||||
|
import * as api from "@/api/audio_content_series_recommend"
|
||||||
|
import * as seriesApi from "@/api/audio_content_series";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ContentSeriesNew",
|
||||||
|
components: {Draggable},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
is_selecting: false,
|
||||||
|
is_loading: false,
|
||||||
|
is_modify: false,
|
||||||
|
show_write_dialog: false,
|
||||||
|
show_delete_confirm_dialog: false,
|
||||||
|
selected_recommend_series: {},
|
||||||
|
recommend_series: {},
|
||||||
|
recommend_series_list: [],
|
||||||
|
series: [],
|
||||||
|
search_query_series: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
search_query_series() {
|
||||||
|
if (!this.is_selecting) {
|
||||||
|
this.debouncedSearchSeries();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async created() {
|
||||||
|
await this.getRecommendSeriesList();
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.debouncedSearchSeries = debounce(this.searchSeries, 500);
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
imageAdd(payload) {
|
||||||
|
const file = payload;
|
||||||
|
if (file) {
|
||||||
|
this.recommend_series.image_url = URL.createObjectURL(file)
|
||||||
|
URL.revokeObjectURL(file)
|
||||||
|
} else {
|
||||||
|
this.recommend_series.image_url = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.is_modify = false
|
||||||
|
this.is_selecting = false
|
||||||
|
this.show_write_dialog = false
|
||||||
|
this.show_delete_confirm_dialog = false
|
||||||
|
this.recommend_series = {}
|
||||||
|
this.selected_recommend_series = {}
|
||||||
|
this.search_query_series = ''
|
||||||
|
this.series = []
|
||||||
|
},
|
||||||
|
|
||||||
|
notifyError(message) {
|
||||||
|
this.$dialog.notify.error(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
notifySuccess(message) {
|
||||||
|
this.$dialog.notify.success(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
showModifyRecommendSeriesDialog(recommendSeries) {
|
||||||
|
this.is_modify = true
|
||||||
|
this.selected_recommend_series = recommendSeries
|
||||||
|
|
||||||
|
this.is_selecting = true; // 선택 중 플래그 활성화
|
||||||
|
|
||||||
|
this.recommend_series.id = recommendSeries.id
|
||||||
|
this.recommend_series.image_url = recommendSeries.imageUrl
|
||||||
|
this.recommend_series.series_id = recommendSeries.seriesId
|
||||||
|
this.recommend_series.series_title = recommendSeries.seriesTitle
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.is_selecting = false; // 선택 상태 해제
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
this.show_write_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteConfirm(recommendSeries) {
|
||||||
|
this.selected_recommend_series = recommendSeries
|
||||||
|
this.show_delete_confirm_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelectSeries(value) {
|
||||||
|
this.recommend_series.series_id = value.value
|
||||||
|
this.is_selecting = true; // 선택 중 플래그 활성화
|
||||||
|
setTimeout(() => {
|
||||||
|
this.is_selecting = false; // 선택 상태 해제
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearchSeriesUpdate(value) {
|
||||||
|
if (!this.is_selecting) {
|
||||||
|
this.search_query_series = value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
validate() {
|
||||||
|
if (this.recommend_series.series_id === null || this.recommend_series.series_id === undefined) {
|
||||||
|
this.notifyError("시리즈를 선택하세요")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
async getRecommendSeriesList() {
|
||||||
|
this.is_loading = true
|
||||||
|
try {
|
||||||
|
const res = await api.getRecommendSeriesList(false)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.recommend_series_list = res.data.data
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
this.is_loading = false
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
if (!this.validate()) return;
|
||||||
|
if (this.is_loading === true) return;
|
||||||
|
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append("image", this.recommend_series.image)
|
||||||
|
|
||||||
|
let request = {
|
||||||
|
seriesId: this.recommend_series.series_id,
|
||||||
|
isFree: false
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.append("request", JSON.stringify(request))
|
||||||
|
|
||||||
|
const res = await api.saveRecommendSeries(formData)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.cancel()
|
||||||
|
this.notifySuccess('등록되었습니다.')
|
||||||
|
|
||||||
|
this.recommend_series_list = []
|
||||||
|
await this.getRecommendSeriesList()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async modify() {
|
||||||
|
if (this.is_loading) return;
|
||||||
|
|
||||||
|
this.is_loading = true
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
let request = {id: this.recommend_series.id}
|
||||||
|
|
||||||
|
if (this.recommend_series.image !== null) {
|
||||||
|
formData.append("image", this.recommend_series.image)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.selected_recommend_series.series_id !== this.recommend_series.series_id &&
|
||||||
|
this.recommend_series.series_id !== null &&
|
||||||
|
this.recommend_series.series_id !== undefined
|
||||||
|
) {
|
||||||
|
request.seriesId = this.recommend_series.series_id
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.append("request", JSON.stringify(request))
|
||||||
|
|
||||||
|
const res = await api.modifyRecommendSeries(formData)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.cancel()
|
||||||
|
this.notifySuccess('수정되었습니다.')
|
||||||
|
|
||||||
|
this.recommend_series_list = []
|
||||||
|
await this.getRecommendSeriesList()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async deleteRecommendSeries() {
|
||||||
|
if (this.is_loading) return;
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append("request", JSON.stringify({id: this.selected_recommend_series.id, isActive: false}))
|
||||||
|
const res = await api.modifyRecommendSeries(formData)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.show_delete_confirm_dialog = false
|
||||||
|
this.cancel()
|
||||||
|
this.notifySuccess('삭제되었습니다.')
|
||||||
|
|
||||||
|
this.recommend_series_list = []
|
||||||
|
await this.getRecommendSeriesList()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async onDropCallback(items) {
|
||||||
|
const ids = items.map((item) => {
|
||||||
|
return item.id
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await api.updateRecommendSeriesOrders(ids)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.notifySuccess(res.data.message || '수정되었습니다.')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async searchSeries() {
|
||||||
|
if (this.search_query_series === null || this.search_query_series.length < 2) {
|
||||||
|
this.series = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.is_loading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await seriesApi.searchSeriesList(this.search_query_series);
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.series = res.data.data.map((item) => {
|
||||||
|
return {name: item.title, value: item.id}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.series = []
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
this.is_loading = false
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.image-select label {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #232d4a;
|
||||||
|
color: #fff;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-size: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-file-input {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-preview {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 250px;
|
||||||
|
object-fit: cover;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,481 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-toolbar dark>
|
||||||
|
<v-spacer />
|
||||||
|
<v-toolbar-title>무료 추천 시리즈</v-toolbar-title>
|
||||||
|
<v-spacer />
|
||||||
|
</v-toolbar>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="show_write_dialog"
|
||||||
|
max-width="1000px"
|
||||||
|
persistent
|
||||||
|
>
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-container>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="9" />
|
||||||
|
<v-spacer />
|
||||||
|
<v-col>
|
||||||
|
<v-btn
|
||||||
|
block
|
||||||
|
color="#3BB9F1"
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
>
|
||||||
|
무료 추천 시리즈 등록
|
||||||
|
</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<draggable
|
||||||
|
v-model="recommend_series_list"
|
||||||
|
class="row"
|
||||||
|
@end="onDropCallback(recommend_series_list)"
|
||||||
|
>
|
||||||
|
<v-col
|
||||||
|
v-for="(item, i) in recommend_series_list"
|
||||||
|
:key="i"
|
||||||
|
cols="3"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
<v-spacer />
|
||||||
|
<v-img :src="item.imageUrl" />
|
||||||
|
<v-spacer />
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
@click="showModifyRecommendSeriesDialog(item)"
|
||||||
|
>
|
||||||
|
수정
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
@click="deleteConfirm(item)"
|
||||||
|
>
|
||||||
|
삭제
|
||||||
|
</v-btn>
|
||||||
|
<v-spacer />
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</draggable>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-card>
|
||||||
|
<v-card-title v-if="is_modify === true">
|
||||||
|
추천 시리즈 수정
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-title v-else>
|
||||||
|
추천 시리즈 등록
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col cols="4">
|
||||||
|
시리즈
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="8">
|
||||||
|
<v-combobox
|
||||||
|
v-model="recommend_series.series_title"
|
||||||
|
:items="series"
|
||||||
|
:loading="is_loading"
|
||||||
|
:search-input.sync="search_query_series"
|
||||||
|
label="시리즈를 검색하세요"
|
||||||
|
item-text="name"
|
||||||
|
item-value="value"
|
||||||
|
no-data-text="No results found"
|
||||||
|
hide-selected
|
||||||
|
clearable
|
||||||
|
@change="onSelectSeries"
|
||||||
|
@update:search-input="onSearchSeriesUpdate"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<div class="image-select">
|
||||||
|
<label for="image">
|
||||||
|
추천 시리즈 이미지 등록
|
||||||
|
</label>
|
||||||
|
<v-file-input
|
||||||
|
id="image"
|
||||||
|
v-model="recommend_series.image"
|
||||||
|
@change="imageAdd"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
v-if="recommend_series.image_url"
|
||||||
|
:src="recommend_series.image_url"
|
||||||
|
alt=""
|
||||||
|
class="image-preview"
|
||||||
|
>
|
||||||
|
<v-card-actions v-show="!is_loading">
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="cancel"
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
v-if="is_modify === true"
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="modify"
|
||||||
|
>
|
||||||
|
수정
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
v-else
|
||||||
|
color="blue darken-1"
|
||||||
|
text
|
||||||
|
@click="submit"
|
||||||
|
>
|
||||||
|
등록
|
||||||
|
</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-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="deleteRecommendSeries"
|
||||||
|
>
|
||||||
|
확인
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Draggable from "vuedraggable";
|
||||||
|
import debounce from "lodash/debounce";
|
||||||
|
|
||||||
|
import * as api from "@/api/audio_content_series_recommend"
|
||||||
|
import * as seriesApi from "@/api/audio_content_series";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ContentSeriesRecommendFree",
|
||||||
|
components: {Draggable},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
is_selecting: false,
|
||||||
|
is_loading: false,
|
||||||
|
is_modify: false,
|
||||||
|
show_write_dialog: false,
|
||||||
|
show_delete_confirm_dialog: false,
|
||||||
|
selected_recommend_series: {},
|
||||||
|
recommend_series: {},
|
||||||
|
recommend_series_list: [],
|
||||||
|
series: [],
|
||||||
|
search_query_series: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
search_query_series() {
|
||||||
|
if (!this.is_selecting) {
|
||||||
|
this.debouncedSearchSeries();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async created() {
|
||||||
|
await this.getRecommendSeriesList();
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.debouncedSearchSeries = debounce(this.searchSeries, 500);
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
imageAdd(payload) {
|
||||||
|
const file = payload;
|
||||||
|
if (file) {
|
||||||
|
this.recommend_series.image_url = URL.createObjectURL(file)
|
||||||
|
URL.revokeObjectURL(file)
|
||||||
|
} else {
|
||||||
|
this.recommend_series.image_url = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.is_modify = false
|
||||||
|
this.is_selecting = false
|
||||||
|
this.show_write_dialog = false
|
||||||
|
this.show_delete_confirm_dialog = false
|
||||||
|
this.recommend_series = {}
|
||||||
|
this.selected_recommend_series = {}
|
||||||
|
this.search_query_series = ''
|
||||||
|
this.series = []
|
||||||
|
},
|
||||||
|
|
||||||
|
notifyError(message) {
|
||||||
|
this.$dialog.notify.error(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
notifySuccess(message) {
|
||||||
|
this.$dialog.notify.success(message)
|
||||||
|
},
|
||||||
|
|
||||||
|
showModifyRecommendSeriesDialog(recommendSeries) {
|
||||||
|
this.is_modify = true
|
||||||
|
this.selected_recommend_series = recommendSeries
|
||||||
|
|
||||||
|
this.is_selecting = true; // 선택 중 플래그 활성화
|
||||||
|
|
||||||
|
this.recommend_series.id = recommendSeries.id
|
||||||
|
this.recommend_series.image_url = recommendSeries.imageUrl
|
||||||
|
this.recommend_series.series_id = recommendSeries.seriesId
|
||||||
|
this.recommend_series.series_title = recommendSeries.seriesTitle
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.is_selecting = false; // 선택 상태 해제
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
this.show_write_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteConfirm(recommendSeries) {
|
||||||
|
this.selected_recommend_series = recommendSeries
|
||||||
|
this.show_delete_confirm_dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelectSeries(value) {
|
||||||
|
this.recommend_series.series_id = value.value
|
||||||
|
this.is_selecting = true; // 선택 중 플래그 활성화
|
||||||
|
setTimeout(() => {
|
||||||
|
this.is_selecting = false; // 선택 상태 해제
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSearchSeriesUpdate(value) {
|
||||||
|
if (!this.is_selecting) {
|
||||||
|
this.search_query_series = value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
validate() {
|
||||||
|
if (this.recommend_series.series_id === null || this.recommend_series.series_id === undefined) {
|
||||||
|
this.notifyError("시리즈를 선택하세요")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
async getRecommendSeriesList() {
|
||||||
|
this.is_loading = true
|
||||||
|
try {
|
||||||
|
const res = await api.getRecommendSeriesList(true)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.recommend_series_list = res.data.data
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
this.is_loading = false
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
if (!this.validate()) return;
|
||||||
|
if (this.is_loading === true) return;
|
||||||
|
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append("image", this.recommend_series.image)
|
||||||
|
|
||||||
|
let request = {
|
||||||
|
seriesId: this.recommend_series.series_id,
|
||||||
|
isFree: true
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.append("request", JSON.stringify(request))
|
||||||
|
|
||||||
|
const res = await api.saveRecommendSeries(formData)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.cancel()
|
||||||
|
this.notifySuccess('등록되었습니다.')
|
||||||
|
|
||||||
|
this.recommend_series_list = []
|
||||||
|
await this.getRecommendSeriesList()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async modify() {
|
||||||
|
if (this.is_loading) return;
|
||||||
|
|
||||||
|
this.is_loading = true
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
let request = {id: this.recommend_series.id}
|
||||||
|
|
||||||
|
if (this.recommend_series.image !== null) {
|
||||||
|
formData.append("image", this.recommend_series.image)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.selected_recommend_series.series_id !== this.recommend_series.series_id &&
|
||||||
|
this.recommend_series.series_id !== null &&
|
||||||
|
this.recommend_series.series_id !== undefined
|
||||||
|
) {
|
||||||
|
request.seriesId = this.recommend_series.series_id
|
||||||
|
}
|
||||||
|
|
||||||
|
formData.append("request", JSON.stringify(request))
|
||||||
|
|
||||||
|
const res = await api.modifyRecommendSeries(formData)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.cancel()
|
||||||
|
this.notifySuccess('수정되었습니다.')
|
||||||
|
|
||||||
|
this.recommend_series_list = []
|
||||||
|
await this.getRecommendSeriesList()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async deleteRecommendSeries() {
|
||||||
|
if (this.is_loading) return;
|
||||||
|
this.is_loading = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append("request", JSON.stringify({id: this.selected_recommend_series.id, isActive: false}))
|
||||||
|
const res = await api.modifyRecommendSeries(formData)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.show_delete_confirm_dialog = false
|
||||||
|
this.cancel()
|
||||||
|
this.notifySuccess('삭제되었습니다.')
|
||||||
|
|
||||||
|
this.recommend_series_list = []
|
||||||
|
await this.getRecommendSeriesList()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async onDropCallback(items) {
|
||||||
|
const ids = items.map((item) => {
|
||||||
|
return item.id
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await api.updateRecommendSeriesOrders(ids)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.notifySuccess(res.data.message || '수정되었습니다.')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async searchSeries() {
|
||||||
|
if (this.search_query_series === null || this.search_query_series.length < 2) {
|
||||||
|
this.series = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.is_loading = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await seriesApi.searchSeriesList(this.search_query_series);
|
||||||
|
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.series = res.data.data.map((item) => {
|
||||||
|
return {name: item.title, value: item.id}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.series = []
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||||
|
this.is_loading = false
|
||||||
|
} finally {
|
||||||
|
this.is_loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.image-select label {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #232d4a;
|
||||||
|
color: #fff;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-size: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-file-input {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-preview {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 250px;
|
||||||
|
object-fit: cover;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue