Merge pull request 'fix(admin-series): 시리즈 수정 기능 추가' (#83) from test into main
Reviewed-on: #83
This commit is contained in:
@@ -24,11 +24,17 @@ async function searchSeriesList(searchWord) {
|
|||||||
return Vue.axios.get("/admin/audio-content/series/search?search_word=" + searchWord)
|
return Vue.axios.get("/admin/audio-content/series/search?search_word=" + searchWord)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 시리즈 수정
|
||||||
|
async function updateAudioContentSeries(request) {
|
||||||
|
return Vue.axios.put('/admin/audio-content/series', request);
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getAudioContentSeriesList,
|
getAudioContentSeriesList,
|
||||||
getAudioContentSeriesGenreList,
|
getAudioContentSeriesGenreList,
|
||||||
createAudioContentSeriesGenre,
|
createAudioContentSeriesGenre,
|
||||||
updateAudioContentSeriesGenre,
|
updateAudioContentSeriesGenre,
|
||||||
updateAudioContentSeriesGenreOrders,
|
updateAudioContentSeriesGenreOrders,
|
||||||
searchSeriesList
|
searchSeriesList,
|
||||||
|
updateAudioContentSeries
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,9 @@
|
|||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
19금
|
19금
|
||||||
</th>
|
</th>
|
||||||
|
<th class="text-center">
|
||||||
|
수정
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -73,13 +76,13 @@
|
|||||||
<td>
|
<td>
|
||||||
<vue-show-more-text
|
<vue-show-more-text
|
||||||
:text="item.title"
|
:text="item.title"
|
||||||
:lines="3"
|
:lines="2"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td style="max-width: 200px !important; word-break:break-all; height: auto;">
|
<td style="max-width: 200px !important; word-break:break-all; height: auto;">
|
||||||
<vue-show-more-text
|
<vue-show-more-text
|
||||||
:text="item.introduction"
|
:text="item.introduction"
|
||||||
:lines="3"
|
:lines="2"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ item.creatorNickname }}</td>
|
<td>{{ item.creatorNickname }}</td>
|
||||||
@@ -94,6 +97,17 @@
|
|||||||
X
|
X
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<v-btn
|
||||||
|
small
|
||||||
|
color="#3bb9f1"
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
@click="openEditDialog(item)"
|
||||||
|
>
|
||||||
|
수정
|
||||||
|
</v-btn>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</template>
|
</template>
|
||||||
@@ -111,6 +125,165 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
|
<v-dialog
|
||||||
|
v-model="show_edit_dialog"
|
||||||
|
max-width="700px"
|
||||||
|
persistent
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
시리즈 수정
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col
|
||||||
|
cols="3"
|
||||||
|
class="text-center"
|
||||||
|
>
|
||||||
|
<v-img
|
||||||
|
:src="edit_target.coverImageUrl"
|
||||||
|
max-width="120"
|
||||||
|
max-height="120"
|
||||||
|
class="rounded-circle"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="9">
|
||||||
|
<div style="font-weight:600;">
|
||||||
|
{{ edit_target.title }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="edit_target.introduction"
|
||||||
|
style="max-height:80px; overflow:auto; word-break:break-all;"
|
||||||
|
>
|
||||||
|
{{ edit_target.introduction }}
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-divider class="my-4" />
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col
|
||||||
|
cols="4"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
장르
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
cols="8"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
<v-select
|
||||||
|
v-model="edit_form.genreId"
|
||||||
|
:items="genre_list"
|
||||||
|
item-text="genre"
|
||||||
|
item-value="id"
|
||||||
|
:loading="is_loading_genres"
|
||||||
|
:disabled="is_saving || is_loading_genres"
|
||||||
|
label="장르를 선택하세요"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col
|
||||||
|
cols="4"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
연재 요일
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
cols="8"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
<v-row
|
||||||
|
dense
|
||||||
|
class="flex-grow-1"
|
||||||
|
>
|
||||||
|
<v-col
|
||||||
|
v-for="opt in daysOfWeekOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
cols="6"
|
||||||
|
sm="4"
|
||||||
|
md="3"
|
||||||
|
class="py-0 my-0"
|
||||||
|
>
|
||||||
|
<v-checkbox
|
||||||
|
v-model="edit_form.publishedDaysOfWeek"
|
||||||
|
:label="opt.text"
|
||||||
|
:value="opt.value"
|
||||||
|
:disabled="is_saving"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
class="ma-0 pa-0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col
|
||||||
|
cols="4"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
오리지널
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
cols="8"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
<v-checkbox
|
||||||
|
v-model="edit_form.isOriginal"
|
||||||
|
:disabled="is_saving"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
class="ma-0 pa-0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row align="center">
|
||||||
|
<v-col
|
||||||
|
cols="4"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
19금
|
||||||
|
</v-col>
|
||||||
|
<v-col
|
||||||
|
cols="8"
|
||||||
|
class="d-flex align-center"
|
||||||
|
>
|
||||||
|
<v-checkbox
|
||||||
|
v-model="edit_form.isAdult"
|
||||||
|
:disabled="is_saving"
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
class="ma-0 pa-0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
:disabled="is_saving"
|
||||||
|
@click="cancelEdit"
|
||||||
|
>
|
||||||
|
취소
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="#3bb9f1"
|
||||||
|
dark
|
||||||
|
depressed
|
||||||
|
:loading="is_saving"
|
||||||
|
:disabled="is_saving"
|
||||||
|
@click="saveEdit"
|
||||||
|
>
|
||||||
|
저장
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -130,7 +303,52 @@ export default {
|
|||||||
page: 1,
|
page: 1,
|
||||||
total_page: 0,
|
total_page: 0,
|
||||||
total_count: 0,
|
total_count: 0,
|
||||||
series_list: []
|
series_list: [],
|
||||||
|
// 수정 다이얼로그 상태/데이터
|
||||||
|
show_edit_dialog: false,
|
||||||
|
is_saving: false,
|
||||||
|
is_loading_genres: false,
|
||||||
|
genre_list: [],
|
||||||
|
edit_target: {},
|
||||||
|
edit_form: {
|
||||||
|
genreId: null,
|
||||||
|
isOriginal: false,
|
||||||
|
isAdult: false,
|
||||||
|
publishedDaysOfWeek: []
|
||||||
|
},
|
||||||
|
daysOfWeekOptions: [
|
||||||
|
{ value: 'RANDOM', text: '랜덤' },
|
||||||
|
{ value: 'SUN', text: '일' },
|
||||||
|
{ value: 'MON', text: '월' },
|
||||||
|
{ value: 'TUE', text: '화' },
|
||||||
|
{ value: 'WED', text: '수' },
|
||||||
|
{ value: 'THU', text: '목' },
|
||||||
|
{ value: 'FRI', text: '금' },
|
||||||
|
{ value: 'SAT', text: '토' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'edit_form.publishedDaysOfWeek': {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (!Array.isArray(newVal)) return;
|
||||||
|
const hasRandom = newVal.includes('RANDOM');
|
||||||
|
const hadRandom = Array.isArray(oldVal) && oldVal.includes('RANDOM');
|
||||||
|
const others = newVal.filter(v => v !== 'RANDOM');
|
||||||
|
|
||||||
|
// RANDOM과 특정 요일은 함께 설정될 수 없음
|
||||||
|
if (hasRandom && others.length > 0) {
|
||||||
|
if (hadRandom) {
|
||||||
|
// RANDOM 상태에서 다른 요일을 선택한 경우 → RANDOM 제거, 나머지만 유지
|
||||||
|
this.edit_form.publishedDaysOfWeek = others;
|
||||||
|
} else {
|
||||||
|
// 다른 요일이 선택된 상태에서 RANDOM을 선택한 경우 → RANDOM만 유지
|
||||||
|
this.edit_form.publishedDaysOfWeek = ['RANDOM'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -176,6 +394,96 @@ export default {
|
|||||||
async next() {
|
async next() {
|
||||||
await this.getAudioContentSeries()
|
await this.getAudioContentSeries()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openEditDialog(item) {
|
||||||
|
this.edit_target = item
|
||||||
|
this.show_edit_dialog = true
|
||||||
|
this.is_saving = false
|
||||||
|
this.loadGenresThenInit()
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadGenresThenInit() {
|
||||||
|
try {
|
||||||
|
this.is_loading_genres = true
|
||||||
|
if (!this.genre_list || this.genre_list.length === 0) {
|
||||||
|
const res = await api.getAudioContentSeriesGenreList()
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.genre_list = res.data.data || []
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '장르 목록을 불러오지 못했습니다.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('장르 목록을 불러오지 못했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_loading_genres = false
|
||||||
|
this.initEditForm()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initEditForm() {
|
||||||
|
const item = this.edit_target || {}
|
||||||
|
let genreId = item.genreId || null
|
||||||
|
if (!genreId && item.genre && this.genre_list && this.genre_list.length > 0) {
|
||||||
|
const found = this.genre_list.find(g => g.genre === item.genre)
|
||||||
|
if (found) genreId = found.id
|
||||||
|
}
|
||||||
|
// 초기 publishedDaysOfWeek 정규화 (RANDOM과 특정 요일 혼재 금지)
|
||||||
|
let published = Array.isArray(item.publishedDaysOfWeek) ? [...item.publishedDaysOfWeek] : []
|
||||||
|
if (published.includes('RANDOM')) {
|
||||||
|
const others = published.filter(v => v !== 'RANDOM')
|
||||||
|
published = others.length > 0 ? ['RANDOM'] : ['RANDOM']
|
||||||
|
}
|
||||||
|
this.edit_form = {
|
||||||
|
genreId: genreId,
|
||||||
|
isOriginal: typeof item.isOriginal === 'boolean' ? item.isOriginal : false,
|
||||||
|
isAdult: typeof item.isAdult === 'boolean' ? item.isAdult : false,
|
||||||
|
publishedDaysOfWeek: published
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cancelEdit() {
|
||||||
|
this.show_edit_dialog = false
|
||||||
|
this.edit_target = {}
|
||||||
|
this.edit_form = {
|
||||||
|
genreId: null,
|
||||||
|
isOriginal: false,
|
||||||
|
isAdult: false,
|
||||||
|
publishedDaysOfWeek: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async saveEdit() {
|
||||||
|
if (this.is_saving) return
|
||||||
|
if (!this.edit_form.genreId) {
|
||||||
|
this.notifyError('장르를 선택해 주세요.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.is_saving = true
|
||||||
|
try {
|
||||||
|
const days = Array.isArray(this.edit_form.publishedDaysOfWeek) ? this.edit_form.publishedDaysOfWeek : []
|
||||||
|
const payloadDays = days.includes('RANDOM') ? ['RANDOM'] : days
|
||||||
|
const request = {
|
||||||
|
seriesId: this.edit_target.id,
|
||||||
|
genreId: this.edit_form.genreId,
|
||||||
|
isOriginal: this.edit_form.isOriginal,
|
||||||
|
isAdult: this.edit_form.isAdult,
|
||||||
|
publishedDaysOfWeek: payloadDays
|
||||||
|
}
|
||||||
|
const res = await api.updateAudioContentSeries(request)
|
||||||
|
if (res.status === 200 && res.data.success === true) {
|
||||||
|
this.notifySuccess('수정되었습니다.')
|
||||||
|
this.show_edit_dialog = false
|
||||||
|
await this.getAudioContentSeries()
|
||||||
|
} else {
|
||||||
|
this.notifyError(res.data.message || '수정에 실패했습니다. 다시 시도해 주세요.')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.notifyError('수정에 실패했습니다. 다시 시도해 주세요.')
|
||||||
|
} finally {
|
||||||
|
this.is_saving = false
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user