diff --git a/src/api/admin/episode.ts b/src/api/admin/episode.ts index 2c17d69..7657106 100644 --- a/src/api/admin/episode.ts +++ b/src/api/admin/episode.ts @@ -4,12 +4,30 @@ import request from '@/axios' import type { EpisodeItem, EpisodeSaveData, PageResult } from './types' export interface EpisodePageParams { - dramaId: number + dramaId: number | string status?: string pageIndex?: number pageSize?: number } +/** + * 解包剧集列表分页。 + * 契约(OpenAPI PageResultEpisodeRespVO):data = { total, list }。 + * 兼容误把 data 当数组的旧调用,避免列表空白。 + */ +export function parseEpisodePage(payload: unknown): PageResult { + if (Array.isArray(payload)) { + return { total: payload.length, list: payload as EpisodeItem[] } + } + if (payload && typeof payload === 'object') { + const page = payload as { total?: unknown; list?: unknown } + const list = Array.isArray(page.list) ? (page.list as EpisodeItem[]) : [] + const total = Number(page.total) + return { total: Number.isFinite(total) ? total : list.length, list } + } + return { total: 0, list: [] } +} + export const listEpisodesApi = (params: EpisodePageParams) => { return request.get>({ url: '/admin/episodes', params }) } diff --git a/src/views/contentManagement/EpisodeManagementView.vue b/src/views/contentManagement/EpisodeManagementView.vue index 4abd935..1313177 100644 --- a/src/views/contentManagement/EpisodeManagementView.vue +++ b/src/views/contentManagement/EpisodeManagementView.vue @@ -6,7 +6,12 @@ import { useRoute } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { AppIcons } from '@/constants/icons' import { pageDramasApi } from '@/api/admin/drama' -import { deleteEpisodeApi, listEpisodesApi, sortEpisodesApi } from '@/api/admin/episode' +import { + deleteEpisodeApi, + listEpisodesApi, + parseEpisodePage, + sortEpisodesApi +} from '@/api/admin/episode' import { useRbac } from '@/stores/rbac' import { formatCount } from '@/utils/format' import { statusClass } from '@/utils/status' @@ -50,6 +55,8 @@ const showPagination = computed(() => { return Math.ceil(total.value / pageSize.value) > 1 }) +const showEmpty = computed(() => !loading.value && episodes.value.length === 0) + async function loadDramas() { const res = await pageDramasApi({ pageIndex: 1, pageSize: 200 }) dramas.value = res.data?.list || [] @@ -77,8 +84,10 @@ async function loadEpisodes() { pageIndex: pageIndex.value, pageSize: pageSize.value }) - episodes.value = res.data?.list || [] - total.value = res.data?.total || 0 + // 按 OpenAPI PageResult{total,list} 解包,禁止再把 data 当数组切片 + const page = parseEpisodePage(res.data) + episodes.value = page.list + total.value = page.total await clampOrRetreatPage() } finally { loading.value = false @@ -100,10 +109,10 @@ async function refreshSnapshot() { pageIndex: page, pageSize: SNAPSHOT_PAGE_SIZE }) - const list = res.data?.list || [] - totalCount = Number(res.data?.total || 0) - collected.push(...list) - if (!list.length) break + const parsed = parseEpisodePage(res.data) + totalCount = parsed.total + collected.push(...parsed.list) + if (!parsed.list.length) break page += 1 } while (collected.length < totalCount) snapshotEpisodes.value = collected @@ -227,7 +236,6 @@ async function move(row, offset) { async function onDramaChange() { pageIndex.value = 1 - statusFilter.value = undefined await loadEpisodes() openBatchIfPendingSessions() } @@ -327,12 +335,17 @@ onMounted(async () => { v-loading="loading" :data="episodes" row-key="id" - empty-text="该短剧暂无剧集" class="drama-el-table episode-el-table" > +