fix(admin): 批量建分集是否免费改由短剧免费集数决定
This commit is contained in:
1 parent
5741ebbf17
commit
05b977cc33
5 files changed
+59
-22
No files matched your search
+4
-2
@@ -555,11 +555,13 @@ export default {
|
||||
resumeUnmatched: '{count} session(s) could not match local files; pick again manually',
|
||||
createTitle: 'Create episodes in batch',
|
||||
createHint:
|
||||
'Title uses the video file name; episode numbers are assigned automatically. You can edit them later in episode settings.',
|
||||
'Title uses the video file name; episode numbers are assigned automatically. Free vs paid follows the drama free-episode count; episodes beyond that are paid. You can edit them later in episode settings.',
|
||||
colSource: 'Source file',
|
||||
colNumber: 'Episode No.',
|
||||
colTitle: 'Title',
|
||||
colFree: 'Free',
|
||||
colFree: 'Pricing',
|
||||
labelFree: 'Free',
|
||||
labelPaid: 'Paid',
|
||||
colResult: 'Result',
|
||||
missingVideo: 'Missing video URL',
|
||||
createOk: 'Created',
|
||||
|
||||
@@ -546,11 +546,14 @@ export default {
|
||||
resumeMatched: '已匹配 {count} 个文件并开始续传',
|
||||
resumeUnmatched: '有 {count} 个会话无法匹配本地文件,请手动重选',
|
||||
createTitle: '批量创建分集',
|
||||
createHint: '标题取视频文件名,集号自动顺延分配,创建后可在分集编辑中修改',
|
||||
createHint:
|
||||
'标题取视频文件名,集号自动顺延分配;免费集数由短剧管理中的「免费集数」配置决定,超出部分为收费集;创建后可在分集编辑中修改',
|
||||
colSource: '源文件',
|
||||
colNumber: '集号',
|
||||
colTitle: '标题',
|
||||
colFree: '免费',
|
||||
colFree: '收费类型',
|
||||
labelFree: '免费',
|
||||
labelPaid: '收费',
|
||||
colResult: '结果',
|
||||
missingVideo: '缺少视频地址',
|
||||
createOk: '已创建',
|
||||
|
||||
@@ -337,6 +337,7 @@ onMounted(async () => {
|
||||
:drama-id="selectedDramaId"
|
||||
:next-episode-number="batchNextNumber"
|
||||
:default-unlock-coin="selectedDrama?.unlockCoin ?? 0"
|
||||
:free-episodes="selectedDrama?.freeEpisodes ?? 0"
|
||||
:existing-numbers="existingEpisodeNumbers"
|
||||
@refreshed="loadEpisodes"
|
||||
@created="onBatchEpisodesCreated"
|
||||
|
||||
@@ -12,13 +12,20 @@ import { useUploadQueue } from './useUploadQueue'
|
||||
import { MAX_VIDEO_SIZE, VIDEO_ACCEPT_ATTR, VIDEO_EXTENSIONS } from './videoLimit'
|
||||
import type { UploadSessionRecord } from './uploadSessions'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
dramaId: string | number
|
||||
nextEpisodeNumber: number
|
||||
defaultUnlockCoin: number
|
||||
existingNumbers: number[]
|
||||
}>()
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: boolean
|
||||
dramaId: string | number
|
||||
nextEpisodeNumber: number
|
||||
defaultUnlockCoin: number
|
||||
existingNumbers: number[]
|
||||
/** 所属短剧免费集数;不传默认 0 */
|
||||
freeEpisodes?: number
|
||||
}>(),
|
||||
{
|
||||
freeEpisodes: 0
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
@@ -272,6 +279,7 @@ function onEpisodesCreated(): void {
|
||||
:done-items="queue.doneItems.value"
|
||||
:next-episode-number="nextEpisodeNumber"
|
||||
:default-unlock-coin="defaultUnlockCoin"
|
||||
:free-episodes="freeEpisodes"
|
||||
:existing-numbers="existingNumbers"
|
||||
@settled="emit('refreshed')"
|
||||
@created="onEpisodesCreated"
|
||||
|
||||
@@ -8,14 +8,21 @@ import { createEpisodeApi } from '@/api/admin/episode'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import type { UploadQueueItem } from './useUploadQueue'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
dramaId: string | number
|
||||
doneItems: UploadQueueItem[]
|
||||
nextEpisodeNumber: number
|
||||
defaultUnlockCoin: number
|
||||
existingNumbers: number[]
|
||||
}>()
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: boolean
|
||||
dramaId: string | number
|
||||
doneItems: UploadQueueItem[]
|
||||
nextEpisodeNumber: number
|
||||
defaultUnlockCoin: number
|
||||
existingNumbers: number[]
|
||||
/** 所属短剧免费集数;不传默认 0 */
|
||||
freeEpisodes?: number
|
||||
}>(),
|
||||
{
|
||||
freeEpisodes: 0
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [value: boolean]
|
||||
@@ -66,16 +73,18 @@ function buildRows(): void {
|
||||
)
|
||||
const used = new Set(props.existingNumbers)
|
||||
let cursor = props.nextEpisodeNumber
|
||||
const freeLimit = props.freeEpisodes
|
||||
rows.value = sorted.map((item) => {
|
||||
const number = nextFreeNumber(cursor, used)
|
||||
used.add(number)
|
||||
cursor = number + 1
|
||||
const isFree = number <= freeLimit
|
||||
return {
|
||||
key: item.id,
|
||||
sourceName: item.fileName,
|
||||
number,
|
||||
title: baseName(item.fileName),
|
||||
isFree: true,
|
||||
isFree,
|
||||
videoUrl: item.url || '',
|
||||
durationSec: item.durationSec || 0,
|
||||
saved: false,
|
||||
@@ -173,7 +182,9 @@ function hasFailed(): boolean {
|
||||
<b class="create-episode-source" :title="row.sourceName">{{ row.sourceName }}</b>
|
||||
<span class="create-episode-number">{{ row.number }}</span>
|
||||
<span class="create-episode-title" :title="row.title">{{ row.title }}</span>
|
||||
<el-switch v-model="row.isFree" :disabled="row.saved" />
|
||||
<span class="create-episode-free" :class="row.isFree ? 'is-free' : 'is-paid'">
|
||||
{{ row.isFree ? t('episodeBatch.labelFree') : t('episodeBatch.labelPaid') }}
|
||||
</span>
|
||||
<span class="create-episode-result">
|
||||
{{ row.saved ? t('episodeBatch.createOk') : row.error }}
|
||||
</span>
|
||||
@@ -199,11 +210,23 @@ function hasFailed(): boolean {
|
||||
.create-episode-head,
|
||||
.create-episode-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(120px, 1.2fr) 72px minmax(140px, 1.4fr) 48px minmax(80px, 0.8fr);
|
||||
grid-template-columns: minmax(120px, 1.2fr) 72px minmax(140px, 1.4fr) 56px minmax(80px, 0.8fr);
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.create-episode-free {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.create-episode-free.is-free {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
|
||||
.create-episode-free.is-paid {
|
||||
color: var(--el-color-warning);
|
||||
}
|
||||
|
||||
.create-episode-head {
|
||||
margin-bottom: 8px;
|
||||
color: var(--el-text-color-secondary);
|
||||
|
||||
Reference in new issue
Block a user