Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2a76a593a | ||
|
|
a28eaa4514 | ||
|
|
189a7f689a |
@@ -15,6 +15,9 @@ import BatchUploadDialog from './upload/BatchUploadDialog.vue'
|
||||
import EpisodeFormDialog from './upload/EpisodeFormDialog.vue'
|
||||
import { listPendingSessions } from './upload/uploadSessions'
|
||||
|
||||
const DEFAULT_PAGE_SIZE = 100
|
||||
const PAGE_SIZE_OPTIONS = [50, 100, 200]
|
||||
|
||||
const route = useRoute()
|
||||
const { can } = useRbac()
|
||||
const { t } = useI18n()
|
||||
@@ -23,6 +26,8 @@ const loading = ref(false)
|
||||
const dramas = ref([])
|
||||
const episodes = ref([])
|
||||
const selectedDramaId = ref(undefined)
|
||||
const pageIndex = ref(1)
|
||||
const pageSize = ref(DEFAULT_PAGE_SIZE)
|
||||
const batchUploadVisible = ref(false)
|
||||
const previewVisible = ref(false)
|
||||
const previewEpisode = ref(null)
|
||||
@@ -34,6 +39,17 @@ const existingEpisodeNumbers = computed(() =>
|
||||
episodes.value.map((item) => Number(item.number)).filter((n) => Number.isFinite(n))
|
||||
)
|
||||
|
||||
const pagedEpisodes = computed(() => {
|
||||
const start = (pageIndex.value - 1) * pageSize.value
|
||||
return episodes.value.slice(start, start + pageSize.value)
|
||||
})
|
||||
|
||||
const showPagination = computed(() => {
|
||||
const total = episodes.value.length
|
||||
if (total <= 0) return false
|
||||
return Math.ceil(total / pageSize.value) > 1
|
||||
})
|
||||
|
||||
async function loadDramas() {
|
||||
const res = await pageDramasApi({ pageIndex: 1, pageSize: 200 })
|
||||
dramas.value = res.data?.list || []
|
||||
@@ -55,11 +71,19 @@ async function loadEpisodes() {
|
||||
try {
|
||||
const res = await listEpisodesApi(selectedDramaId.value)
|
||||
episodes.value = res.data || []
|
||||
clampPageIndex()
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 刷新后若当前页越界(如删除末页最后一条),夹到最后一页。 */
|
||||
function clampPageIndex() {
|
||||
const total = episodes.value.length
|
||||
const maxPage = Math.max(1, Math.ceil(total / pageSize.value) || 1)
|
||||
if (pageIndex.value > maxPage) pageIndex.value = maxPage
|
||||
}
|
||||
|
||||
function nextNumber() {
|
||||
return episodes.value.reduce((max, item) => Math.max(max, item.number || 0), 0) + 1
|
||||
}
|
||||
@@ -122,10 +146,24 @@ function stopThumb(event) {
|
||||
}
|
||||
}
|
||||
|
||||
function episodeIndexInFullList(row) {
|
||||
return episodes.value.findIndex((item) => item.id === row.id)
|
||||
}
|
||||
|
||||
function canMoveUp(row) {
|
||||
return episodeIndexInFullList(row) > 0
|
||||
}
|
||||
|
||||
function canMoveDown(row) {
|
||||
const index = episodeIndexInFullList(row)
|
||||
return index >= 0 && index < episodes.value.length - 1
|
||||
}
|
||||
|
||||
/** 上移/下移后把新顺序整表提交,由后端重排 sort。 */
|
||||
async function move(index, offset) {
|
||||
async function move(row, offset) {
|
||||
const index = episodeIndexInFullList(row)
|
||||
const target = index + offset
|
||||
if (target < 0 || target >= episodes.value.length) return
|
||||
if (index < 0 || target < 0 || target >= episodes.value.length) return
|
||||
const next = [...episodes.value]
|
||||
const [moved] = next.splice(index, 1)
|
||||
next.splice(target, 0, moved)
|
||||
@@ -135,10 +173,15 @@ async function move(index, offset) {
|
||||
}
|
||||
|
||||
async function onDramaChange() {
|
||||
pageIndex.value = 1
|
||||
await loadEpisodes()
|
||||
openBatchIfPendingSessions()
|
||||
}
|
||||
|
||||
function handleSizeChange() {
|
||||
pageIndex.value = 1
|
||||
}
|
||||
|
||||
/** 进入页面或切换短剧时,若有 24h 内未完成上传则打开批量上传弹窗以提示续传。 */
|
||||
function openBatchIfPendingSessions() {
|
||||
if (!selectedDramaId.value || !can('episode:upload')) return
|
||||
@@ -202,11 +245,10 @@ onMounted(async () => {
|
||||
<div class="episode-toolbar"
|
||||
><div
|
||||
><h2>剧集列表({{ episodes.length }})</h2><p>按列表顺序播放</p></div
|
||||
></div
|
||||
>
|
||||
></div>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="episodes"
|
||||
:data="pagedEpisodes"
|
||||
row-key="id"
|
||||
empty-text="该短剧暂无剧集"
|
||||
class="drama-el-table episode-el-table"
|
||||
@@ -278,7 +320,7 @@ onMounted(async () => {
|
||||
></el-table-column
|
||||
>
|
||||
<el-table-column label="操作" width="250" fixed="right"
|
||||
><template #default="{ row, $index }"
|
||||
><template #default="{ row }"
|
||||
><div class="table-actions"
|
||||
><el-button
|
||||
v-if="can('episode:upload')"
|
||||
@@ -289,14 +331,14 @@ onMounted(async () => {
|
||||
><el-button
|
||||
v-if="can('episode:sort')"
|
||||
size="small"
|
||||
:disabled="$index === 0"
|
||||
@click="move($index, -1)"
|
||||
:disabled="!canMoveUp(row)"
|
||||
@click="move(row, -1)"
|
||||
>上移</el-button
|
||||
><el-button
|
||||
v-if="can('episode:sort')"
|
||||
size="small"
|
||||
:disabled="$index === episodes.length - 1"
|
||||
@click="move($index, 1)"
|
||||
:disabled="!canMoveDown(row)"
|
||||
@click="move(row, 1)"
|
||||
>下移</el-button
|
||||
><el-button
|
||||
v-if="can('episode:upload')"
|
||||
@@ -309,6 +351,17 @@ onMounted(async () => {
|
||||
></el-table-column
|
||||
>
|
||||
</el-table>
|
||||
<div v-if="showPagination" class="pagination"
|
||||
><el-pagination
|
||||
v-model:current-page="pageIndex"
|
||||
v-model:page-size="pageSize"
|
||||
:page-sizes="PAGE_SIZE_OPTIONS"
|
||||
:total="episodes.length"
|
||||
:pager-count="7"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
/></div>
|
||||
</section>
|
||||
<EpisodeFormDialog
|
||||
ref="formDialogRef"
|
||||
|
||||
Reference in new issue
Block a user