feat(admin): 剧集多选分片上传与断点续传
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
8e1a02ace0
commit
6b3620c3c4
9 files changed
+1210
-8
No files matched your search
@@ -16,10 +16,15 @@ import {
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import { formatCount } from '@/utils/format'
|
||||
import { statusClass } from '@/utils/status'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { probeVideoDuration, uploadFile } from '@/utils/uploader'
|
||||
import BatchUploadDialog from './upload/BatchUploadDialog.vue'
|
||||
import { listPendingSessions } from './upload/uploadSessions'
|
||||
import { MAX_VIDEO_SIZE } from './upload/videoLimit'
|
||||
|
||||
const route = useRoute()
|
||||
const { can } = useRbac()
|
||||
const { t } = useI18n()
|
||||
|
||||
const loading = ref(false)
|
||||
const dramas = ref([])
|
||||
@@ -27,6 +32,8 @@ const episodes = ref([])
|
||||
const selectedDramaId = ref(undefined)
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const batchUploadVisible = ref(false)
|
||||
const batchNextNumber = computed(() => nextNumber())
|
||||
const saving = ref(false)
|
||||
const uploadingVideo = ref(false)
|
||||
const videoPercent = ref(0)
|
||||
@@ -55,7 +62,6 @@ const statusOptions = [
|
||||
{ code: 'offline', text: '已下线' }
|
||||
]
|
||||
|
||||
const MAX_VIDEO_SIZE = 500 * 1024 * 1024
|
||||
const VIDEO_EXTENSIONS = ['mp4', 'mov']
|
||||
const formRules = {
|
||||
number: [{ required: true, message: '请输入集号', trigger: 'change' }],
|
||||
@@ -120,6 +126,19 @@ function nextNumber() {
|
||||
return episodes.value.reduce((max, item) => Math.max(max, item.number || 0), 0) + 1
|
||||
}
|
||||
|
||||
const existingEpisodeNumbers = computed(() =>
|
||||
episodes.value.map((item) => Number(item.number)).filter((n) => Number.isFinite(n))
|
||||
)
|
||||
|
||||
function openBatchUpload() {
|
||||
if (!selectedDramaId.value) return
|
||||
batchUploadVisible.value = true
|
||||
}
|
||||
|
||||
async function onBatchEpisodesCreated() {
|
||||
await loadEpisodes()
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
editingId.value = null
|
||||
Object.assign(form, {
|
||||
@@ -304,11 +323,20 @@ async function move(index, offset) {
|
||||
|
||||
async function onDramaChange() {
|
||||
await loadEpisodes()
|
||||
openBatchIfPendingSessions()
|
||||
}
|
||||
|
||||
/** 进入页面或切换短剧时,若有 24h 内未完成上传则打开批量上传弹窗以提示续传。 */
|
||||
function openBatchIfPendingSessions() {
|
||||
if (!selectedDramaId.value || !can('episode:upload')) return
|
||||
const pending = listPendingSessions(String(selectedDramaId.value))
|
||||
if (pending.length) batchUploadVisible.value = true
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadDramas()
|
||||
await loadEpisodes()
|
||||
openBatchIfPendingSessions()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -317,13 +345,17 @@ onMounted(async () => {
|
||||
><div
|
||||
><div class="eyebrow">内容管理</div><h1>剧集管理</h1
|
||||
><p>为短剧维护剧集信息、视频地址与播放顺序。</p></div
|
||||
><el-button
|
||||
v-if="can('episode:upload')"
|
||||
type="primary"
|
||||
class="primary-button"
|
||||
:disabled="!selectedDramaId"
|
||||
@click="openCreate"
|
||||
><AppIcon :icon="AppIcons.add" />新增剧集</el-button
|
||||
><div class="page-heading-actions">
|
||||
<el-button v-if="can('episode:upload')" :disabled="!selectedDramaId" @click="openBatchUpload"
|
||||
><AppIcon :icon="AppIcons.upload" />{{ t('episodeBatch.entry') }}</el-button
|
||||
><el-button
|
||||
v-if="can('episode:upload')"
|
||||
type="primary"
|
||||
class="primary-button"
|
||||
:disabled="!selectedDramaId"
|
||||
@click="openCreate"
|
||||
><AppIcon :icon="AppIcons.add" />新增剧集</el-button
|
||||
></div
|
||||
></div
|
||||
>
|
||||
<section class="panel episode-panel">
|
||||
@@ -672,4 +704,14 @@ onMounted(async () => {
|
||||
></video>
|
||||
<el-empty v-else description="该剧集还没有上传视频" />
|
||||
</el-dialog>
|
||||
<BatchUploadDialog
|
||||
v-if="selectedDramaId"
|
||||
v-model="batchUploadVisible"
|
||||
:drama-id="selectedDramaId"
|
||||
:next-episode-number="batchNextNumber"
|
||||
:default-unlock-coin="selectedDrama?.unlockCoin ?? 0"
|
||||
:existing-numbers="existingEpisodeNumbers"
|
||||
@refreshed="loadEpisodes"
|
||||
@created="onBatchEpisodesCreated"
|
||||
/>
|
||||
</template>
|
||||
Reference in new issue
Block a user