feat(creator-center): 新增两步发布作品并支持删除作品
This commit is contained in:
1 parent
4055b7a2a9
commit
3c730c7d33
6 files changed
+1522
-112
No files matched your search
@@ -109,6 +109,35 @@ export interface CreatorDramaEditData {
|
||||
language?: string
|
||||
}
|
||||
|
||||
/** 一键发布的分集入参:assetId 来自已完成的分片上传 */
|
||||
export interface PublishEpisodeItem {
|
||||
assetId: number
|
||||
title?: string
|
||||
durationSec?: number
|
||||
cover?: string
|
||||
}
|
||||
|
||||
export interface PublishDramaPayload {
|
||||
title: string
|
||||
subtitle?: string
|
||||
/** 短剧分类 id(下拉选择) */
|
||||
categoryId?: number
|
||||
/** 题材标签(自由文本,可选) */
|
||||
genre?: string
|
||||
description?: string
|
||||
cover?: string
|
||||
language?: string
|
||||
/** 默认 true:创建后立即提交审核 */
|
||||
submit?: boolean
|
||||
episodes: PublishEpisodeItem[]
|
||||
}
|
||||
|
||||
export interface PublishDramaResult {
|
||||
dramaId: number
|
||||
submissionId?: number | null
|
||||
status: string
|
||||
}
|
||||
|
||||
export interface PriceEpisodeConfig {
|
||||
episodeId: number
|
||||
number: number
|
||||
@@ -176,6 +205,11 @@ export const createDramaApi = (data: CreatorDramaEditData) => {
|
||||
return request.post<number>({ url: '/admin/creator-center/dramas', data })
|
||||
}
|
||||
|
||||
/** 一键发布:一个事务里建作品 + 建分集 + 绑定视频(可选提交审核) */
|
||||
export const publishDramaApi = (data: PublishDramaPayload) => {
|
||||
return request.post<PublishDramaResult>({ url: '/admin/creator-center/publish', data })
|
||||
}
|
||||
|
||||
export const updateDramaApi = (id: number, data: CreatorDramaEditData) => {
|
||||
return request.put<void>({ url: `/admin/creator-center/dramas/${id}`, data })
|
||||
}
|
||||
@@ -205,6 +239,11 @@ export const deleteEpisodeApi = (dramaId: number, episodeId: number) => {
|
||||
})
|
||||
}
|
||||
|
||||
/** 删除作品(草稿 / 已下线 / 审核中可删,已上线需先下线) */
|
||||
export const deleteDramaApi = (dramaId: number) => {
|
||||
return request.delete<void>({ url: `/admin/creator-center/dramas/${dramaId}` })
|
||||
}
|
||||
|
||||
export const sortEpisodesApi = (dramaId: number, ids: number[]) => {
|
||||
return request.put<void>({
|
||||
url: `/admin/creator-center/dramas/${dramaId}/episodes/sort`,
|
||||
|
||||
@@ -298,6 +298,11 @@ html.dark .creator-guide-title {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.creator-switch-hint {
|
||||
margin-left: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
html.dark .creator-profile-name,
|
||||
html.dark .creator-profile-meta b,
|
||||
html.dark .creator-drama-title,
|
||||
@@ -316,3 +321,144 @@ html.dark .creator-episode-cover {
|
||||
border-color: var(--el-border-color-light);
|
||||
background: var(--el-fill-color-light);
|
||||
}
|
||||
|
||||
/* ---------- 移动端(创作者多手机上传) ---------- */
|
||||
.creator-mobile-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 作品表格:列宽合计超过容器时由外层横向滚动,
|
||||
不依赖 el-table 内部的 scrollbar(其 header/body 会被各自裁切)。 */
|
||||
.creator-desktop-only {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.creator-desktop-only .el-table.drama-el-table {
|
||||
min-width: 1150px;
|
||||
}
|
||||
|
||||
/* 作品编辑页:分集 / 提交记录表格由外层容器横向滚动(宽度见各表格 inline min-width) */
|
||||
.creator-table-scroll {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* 操作列按钮放不下时换行,避免「删除」被表格裁掉 */
|
||||
.creator-table-scroll .table-actions {
|
||||
flex-wrap: wrap;
|
||||
white-space: normal;
|
||||
row-gap: 6px;
|
||||
}
|
||||
|
||||
.creator-video-preview {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-height: 70vh;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
@media (width <= 768px) {
|
||||
.creator-desktop-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.creator-mobile-only {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.creator-profile-meta {
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
}
|
||||
|
||||
.console-toolbar {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.console-toolbar .console-keyword,
|
||||
.console-toolbar .console-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.creator-drama-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.creator-drama-card {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
border: 1px solid #e6e8eb;
|
||||
border-radius: var(--app-radius-md);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.creator-drama-card-cover {
|
||||
display: grid;
|
||||
flex-shrink: 0;
|
||||
place-content: center;
|
||||
width: 60px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
color: #9a97a8;
|
||||
font-size: 16px;
|
||||
background: #eef0f5;
|
||||
border-radius: var(--app-radius-sm);
|
||||
}
|
||||
|
||||
.creator-drama-card-cover img,
|
||||
.creator-drama-card-cover .creator-drama-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.creator-drama-card-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.creator-drama-card-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.creator-drama-card-head .creator-drama-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.creator-drama-card-meta {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
color: #727983;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.creator-drama-card-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
html.dark .creator-drama-card {
|
||||
border-color: var(--el-border-color-light);
|
||||
background: var(--el-bg-color-overlay);
|
||||
}
|
||||
|
||||
html.dark .creator-drama-card-cover {
|
||||
background: var(--el-fill-color-light);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// Author: fruit.com.cn
|
||||
/** 从本地视频文件截取封面(3:4 居中裁切),抖音式自动封面用 */
|
||||
|
||||
export interface CapturedCover {
|
||||
file: File
|
||||
previewUrl: string
|
||||
}
|
||||
|
||||
function loadVideo(file: File): Promise<HTMLVideoElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const video = document.createElement('video')
|
||||
video.preload = 'metadata'
|
||||
video.muted = true
|
||||
video.playsInline = true
|
||||
const src = URL.createObjectURL(file)
|
||||
const fail = (message: string) => {
|
||||
URL.revokeObjectURL(src)
|
||||
reject(new Error(message))
|
||||
}
|
||||
video.onloadedmetadata = () => {
|
||||
URL.revokeObjectURL(src)
|
||||
resolve(video)
|
||||
}
|
||||
video.onerror = () => fail('当前浏览器无法解析该视频格式')
|
||||
video.src = src
|
||||
})
|
||||
}
|
||||
|
||||
/** 截取第 atSeconds 秒画面,按 3:4 居中裁切输出 720×960 JPEG */
|
||||
export async function captureVideoCover(file: File, atSeconds = 1): Promise<CapturedCover> {
|
||||
const video = await loadVideo(file)
|
||||
const duration = Number.isFinite(video.duration) && video.duration > 0 ? video.duration : 0
|
||||
// 太短的视频从开头截,正常视频取第 1 秒,避免黑场
|
||||
const target = duration ? Math.min(atSeconds, Math.max(0.1, duration * 0.2)) : 0
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const timer = window.setTimeout(() => reject(new Error('截取封面超时')), 8000)
|
||||
video.onseeked = () => {
|
||||
window.clearTimeout(timer)
|
||||
resolve()
|
||||
}
|
||||
video.currentTime = target
|
||||
})
|
||||
|
||||
const width = video.videoWidth
|
||||
const height = video.videoHeight
|
||||
if (!width || !height) throw new Error('无法读取视频尺寸')
|
||||
|
||||
const ratio = 3 / 4
|
||||
let sw = width
|
||||
let sh = height
|
||||
if (width / height > ratio) {
|
||||
sw = height * ratio
|
||||
} else {
|
||||
sh = width / ratio
|
||||
}
|
||||
const sx = (width - sw) / 2
|
||||
const sy = (height - sh) / 2
|
||||
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = 720
|
||||
canvas.height = 960
|
||||
const context = canvas.getContext('2d')
|
||||
if (!context) throw new Error('当前浏览器不支持 canvas')
|
||||
context.drawImage(video, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height)
|
||||
|
||||
const blob = await new Promise<Blob>((resolve, reject) => {
|
||||
canvas.toBlob(
|
||||
(result) => (result ? resolve(result) : reject(new Error('封面生成失败'))),
|
||||
'image/jpeg',
|
||||
0.85
|
||||
)
|
||||
})
|
||||
const baseName = file.name.replace(/\.[^.]+$/, '') || 'cover'
|
||||
return {
|
||||
file: new File([blob], `${baseName}-cover.jpg`, { type: 'image/jpeg' }),
|
||||
previewUrl: URL.createObjectURL(blob)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -30,16 +30,12 @@ const {
|
||||
profileLoading,
|
||||
dramas,
|
||||
notices,
|
||||
createVisible,
|
||||
createSaving,
|
||||
createForm,
|
||||
queryDramas,
|
||||
loadDramas,
|
||||
loadNotices,
|
||||
submit,
|
||||
withdraw,
|
||||
openCreate,
|
||||
confirmCreate
|
||||
remove
|
||||
} = useCreatorWorkspace()
|
||||
|
||||
const activeTab = ref('dramas')
|
||||
@@ -59,6 +55,11 @@ function onTabChange(name) {
|
||||
function openEdit(row) {
|
||||
router.push(`/creator-center/dramas/${row.id}`)
|
||||
}
|
||||
|
||||
/** 抖音式发布:直接进发布页选视频,不再先建空草稿 */
|
||||
function openPublish() {
|
||||
router.push('/creator-center/publish')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -68,8 +69,8 @@ function openEdit(row) {
|
||||
title="我的作品"
|
||||
description="查看作品与审核进度,提交上线 / 下线申请。"
|
||||
>
|
||||
<el-button v-if="canEdit && !impersonating" type="primary" @click="openCreate"
|
||||
>新建作品</el-button
|
||||
<el-button v-if="canEdit && !impersonating" type="primary" @click="openPublish"
|
||||
>发布作品</el-button
|
||||
>
|
||||
</PageHeading>
|
||||
|
||||
@@ -114,7 +115,7 @@ function openEdit(row) {
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<section class="panel creator-workspace-wrap">
|
||||
<el-tabs v-model="activeTab" @tab-change="onTabChange">
|
||||
<el-tab-pane label="我的作品" name="dramas">
|
||||
<div class="console-toolbar">
|
||||
@@ -146,47 +147,151 @@ function openEdit(row) {
|
||||
<span class="console-count">共 {{ dramas.total }} 部作品</span>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="dramas.loading"
|
||||
:data="dramas.rows"
|
||||
row-key="id"
|
||||
border
|
||||
class="drama-el-table"
|
||||
empty-text="还没有作品,点右上角「新建作品」开始"
|
||||
>
|
||||
<el-table-column label="作品" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<div class="creator-drama-cell">
|
||||
<div class="creator-drama-cover">
|
||||
<AppImage
|
||||
v-if="row.cover"
|
||||
:src="row.cover"
|
||||
:preview-list="workspaceCoverPreviewList"
|
||||
:initial-index="workspaceCoverPreviewIndex(row)"
|
||||
fit="cover"
|
||||
class="creator-drama-image"
|
||||
:alt="row.title"
|
||||
/>
|
||||
<span v-else>{{ (row.title || '?').slice(0, 1) }}</span>
|
||||
<div class="creator-desktop-only">
|
||||
<el-table
|
||||
v-loading="dramas.loading"
|
||||
:data="dramas.rows"
|
||||
row-key="id"
|
||||
border
|
||||
class="drama-el-table"
|
||||
empty-text="还没有作品,点右上角「发布作品」开始"
|
||||
>
|
||||
<el-table-column label="作品" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<div class="creator-drama-cell">
|
||||
<div class="creator-drama-cover">
|
||||
<AppImage
|
||||
v-if="row.cover"
|
||||
:src="row.cover"
|
||||
:preview-list="workspaceCoverPreviewList"
|
||||
:initial-index="workspaceCoverPreviewIndex(row)"
|
||||
fit="cover"
|
||||
class="creator-drama-image"
|
||||
:alt="row.title"
|
||||
/>
|
||||
<span v-else>{{ (row.title || '?').slice(0, 1) }}</span>
|
||||
</div>
|
||||
<div class="creator-drama-meta">
|
||||
<span class="creator-drama-title">{{ row.title }}</span>
|
||||
<span class="creator-drama-code">{{ row.code }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="creator-drama-meta">
|
||||
<span class="creator-drama-title">{{ row.title }}</span>
|
||||
<span class="creator-drama-code">{{ row.code }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="dramaStatusMeta(row.status).tag" effect="light">{{
|
||||
dramaStatusMeta(row.status).label
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="episodes" label="分集" width="80" />
|
||||
<el-table-column prop="views" label="播放" width="100" />
|
||||
<el-table-column label="审核进度" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.submissionStatus" class="creator-progress">
|
||||
<el-tag
|
||||
size="small"
|
||||
:type="submissionStatusMeta(row.submissionStatus).tag"
|
||||
effect="plain"
|
||||
>
|
||||
{{ submissionTypeText(row.submissionType) }}·{{
|
||||
submissionStatusMeta(row.submissionStatus).label
|
||||
}}
|
||||
</el-tag>
|
||||
<span v-if="row.reviewNote" class="console-muted" :title="row.reviewNote">{{
|
||||
row.reviewNote
|
||||
}}</span>
|
||||
</div>
|
||||
<span v-else class="console-muted">尚未提交</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="updatedAt"
|
||||
label="更新时间"
|
||||
min-width="165"
|
||||
:formatter="dateCell"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="操作" width="280">
|
||||
<template #default="{ row }">
|
||||
<div class="table-actions">
|
||||
<el-button
|
||||
v-if="canEdit && !impersonating"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="openEdit(row)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-dropdown
|
||||
v-if="canEdit && !impersonating && submitOptions(row).length"
|
||||
trigger="click"
|
||||
@command="(type) => submit(row, type)"
|
||||
>
|
||||
<el-button size="small">提交审核</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="type in submitOptions(row)"
|
||||
:key="type"
|
||||
:command="type"
|
||||
>
|
||||
{{ submissionTypeText(type) }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button
|
||||
v-if="
|
||||
canEdit &&
|
||||
!impersonating &&
|
||||
row.submissionId &&
|
||||
['SUBMITTED', 'REVIEWING'].includes(row.submissionStatus)
|
||||
"
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="withdraw(row)"
|
||||
>撤回</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="canEdit && !impersonating"
|
||||
text
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="remove(row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div v-loading="dramas.loading" class="creator-mobile-only creator-drama-list">
|
||||
<el-empty v-if="!dramas.rows.length" description="还没有作品,点下方「发布作品」开始" />
|
||||
<article v-for="row in dramas.rows" :key="row.id" class="creator-drama-card">
|
||||
<div class="creator-drama-card-cover" @click="openEdit(row)">
|
||||
<AppImage
|
||||
v-if="row.cover"
|
||||
:src="row.cover"
|
||||
fit="cover"
|
||||
class="creator-drama-image"
|
||||
:alt="row.title"
|
||||
/>
|
||||
<span v-else>{{ (row.title || '?').slice(0, 1) }}</span>
|
||||
</div>
|
||||
<div class="creator-drama-card-body">
|
||||
<div class="creator-drama-card-head">
|
||||
<span class="creator-drama-title">{{ row.title }}</span>
|
||||
<el-tag size="small" :type="dramaStatusMeta(row.status).tag" effect="light">
|
||||
{{ dramaStatusMeta(row.status).label }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span class="creator-drama-code">{{ row.code }}</span>
|
||||
<div class="creator-drama-card-meta">
|
||||
<span>{{ row.episodes }} 集</span>
|
||||
<span>{{ row.views }} 播放</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="dramaStatusMeta(row.status).tag" effect="light">{{
|
||||
dramaStatusMeta(row.status).label
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="episodes" label="分集" width="80" />
|
||||
<el-table-column prop="views" label="播放" width="100" />
|
||||
<el-table-column label="审核进度" min-width="200">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row.submissionStatus" class="creator-progress">
|
||||
<el-tag
|
||||
size="small"
|
||||
@@ -197,32 +302,12 @@ function openEdit(row) {
|
||||
submissionStatusMeta(row.submissionStatus).label
|
||||
}}
|
||||
</el-tag>
|
||||
<span v-if="row.reviewNote" class="console-muted" :title="row.reviewNote">{{
|
||||
row.reviewNote
|
||||
}}</span>
|
||||
</div>
|
||||
<span v-else class="console-muted">尚未提交</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="updatedAt"
|
||||
label="更新时间"
|
||||
min-width="165"
|
||||
:formatter="dateCell"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column label="操作" width="210" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="table-actions">
|
||||
<el-button
|
||||
v-if="canEdit && !impersonating"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="openEdit(row)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<div v-if="canEdit && !impersonating" class="creator-drama-card-actions">
|
||||
<el-button size="small" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||
<el-dropdown
|
||||
v-if="canEdit && !impersonating && submitOptions(row).length"
|
||||
v-if="submitOptions(row).length"
|
||||
trigger="click"
|
||||
@command="(type) => submit(row, type)"
|
||||
>
|
||||
@@ -241,20 +326,18 @@ function openEdit(row) {
|
||||
</el-dropdown>
|
||||
<el-button
|
||||
v-if="
|
||||
canEdit &&
|
||||
!impersonating &&
|
||||
row.submissionId &&
|
||||
['SUBMITTED', 'REVIEWING'].includes(row.submissionStatus)
|
||||
row.submissionId && ['SUBMITTED', 'REVIEWING'].includes(row.submissionStatus)
|
||||
"
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="withdraw(row)"
|
||||
>撤回</el-button
|
||||
>
|
||||
<el-button text type="danger" size="small" @click="remove(row)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
@@ -290,41 +373,5 @@ function openEdit(row) {
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</section>
|
||||
|
||||
<el-dialog v-model="createVisible" title="新建作品" width="480px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="作品名称" required>
|
||||
<el-input
|
||||
v-model="createForm.title"
|
||||
maxlength="64"
|
||||
placeholder="例如:闪婚后,傅先生每天都在撒糖"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="题材">
|
||||
<el-input v-model="createForm.genre" maxlength="32" placeholder="例如:都市情感" />
|
||||
</el-form-item>
|
||||
<el-form-item label="简介">
|
||||
<el-input
|
||||
v-model="createForm.description"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="先建草稿,再去作品编辑页完善信息、分集与视频,然后提交审核"
|
||||
/>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="createVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="createSaving" @click="confirmCreate"
|
||||
>创建草稿</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</CreatorCenterPage>
|
||||
</template>
|
||||
@@ -4,6 +4,7 @@ import { onMounted, reactive, ref } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import {
|
||||
createDramaApi,
|
||||
deleteDramaApi,
|
||||
getCreatorProfileApi,
|
||||
listCreatorNoticesApi,
|
||||
pageMyDramasApi,
|
||||
@@ -168,6 +169,32 @@ export function useCreatorWorkspace() {
|
||||
await loadDramas()
|
||||
}
|
||||
|
||||
/** 删作品。已上线的后端会拦,前端按状态给提示。 */
|
||||
async function remove(row) {
|
||||
const label = row.title || '该作品'
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`《${label}》将被永久删除(分集、封面、审核记录一并清理),且不可恢复。确认删除?`,
|
||||
'删除作品',
|
||||
{
|
||||
confirmButtonText: '确认删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
confirmButtonClass: 'el-button--danger'
|
||||
}
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await deleteDramaApi(row.id)
|
||||
ElMessage.success('作品已删除')
|
||||
await loadDramas()
|
||||
} catch (e) {
|
||||
// 后端可能抛"已上线,请先下线"之类的业务错误;ElMessage 全局拦截器会弹 message
|
||||
}
|
||||
}
|
||||
|
||||
const createVisible = ref(false)
|
||||
const createSaving = ref(false)
|
||||
const createForm = reactive({ title: '', genre: '', description: '' })
|
||||
@@ -216,6 +243,7 @@ export function useCreatorWorkspace() {
|
||||
loadNotices,
|
||||
submit,
|
||||
withdraw,
|
||||
remove,
|
||||
openCreate,
|
||||
confirmCreate
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user