Files
ReelShortWeb/src/views/creator-center/composables/useCreatorWorkspace.js
T

223 lines
6.1 KiB
JavaScript

// Author: fruit.com.cn
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
createDramaApi,
getCreatorProfileApi,
listCreatorNoticesApi,
pageMyDramasApi,
submitDramaApi,
withdrawSubmissionApi
} from '@/api/admin/creatorCenter'
import { useCreatorAccess } from './useCreatorAccess'
/** 作品状态:与后端 ContentStatus 一一对应 */
export const DRAMA_STATUS = [
{ value: 'draft', label: '草稿', tag: 'info' },
{ value: 'reviewing', label: '审核中', tag: 'warning' },
{ value: 'approved', label: '待发布', tag: 'warning' },
{ value: 'published', label: '已上线', tag: 'success' },
{ value: 'offline', label: '已下线', tag: 'info' }
]
/** 提交状态:与后端 content_submission.status 一一对应 */
export const SUBMISSION_STATUS = [
{ value: 'DRAFT', label: '草稿', tag: 'info' },
{ value: 'SUBMITTED', label: '已提交', tag: 'warning' },
{ value: 'REVIEWING', label: '审核中', tag: 'warning' },
{ value: 'APPROVED', label: '已通过', tag: 'success' },
{ value: 'REJECTED', label: '已驳回', tag: 'danger' },
{ value: 'WITHDRAWN', label: '已撤回', tag: 'info' }
]
export const SUBMISSION_TYPE = [
{ value: 'CREATE', label: '新建' },
{ value: 'UPDATE', label: '编辑' },
{ value: 'PUBLISH', label: '申请上线' },
{ value: 'OFFLINE', label: '申请下线' }
]
export function dramaStatusMeta(status) {
return DRAMA_STATUS.find((item) => item.value === status) || { label: status || '-', tag: 'info' }
}
export function submissionStatusMeta(status) {
return (
SUBMISSION_STATUS.find((item) => item.value === status) || { label: status || '-', tag: 'info' }
)
}
export function submissionTypeText(type) {
return SUBMISSION_TYPE.find((item) => item.value === type)?.label || type || '-'
}
/**
* 可提交的类型:与后端 submit 的状态矩阵一一对应,前端只做"给不给出这个按钮",
* 真正的校验仍在服务端(前端不复制规则,只减少无效点击)。
*/
export function submitOptions(row) {
const firstSubmit = !row.submissionId
const options = []
if (row.status === 'draft') {
options.push(firstSubmit ? 'CREATE' : 'UPDATE')
options.push('PUBLISH')
} else if (row.status === 'offline') {
options.push('UPDATE', 'PUBLISH')
} else if (row.status === 'reviewing' || row.status === 'approved') {
options.push('PUBLISH')
} else if (row.status === 'published') {
options.push('OFFLINE')
}
return options
}
export function useCreatorWorkspace() {
const { ensureAccess } = useCreatorAccess()
const profileLoading = ref(false)
const profile = ref(null)
const dramas = reactive({
rows: [],
total: 0,
loading: false,
page: 1,
size: 10,
keyword: '',
status: undefined
})
const notices = reactive({ rows: [], loading: false, loaded: false })
async function loadProfile() {
profileLoading.value = true
try {
profile.value = (await getCreatorProfileApi()).data || null
} finally {
profileLoading.value = false
}
}
async function loadDramas() {
dramas.loading = true
try {
const res = await pageMyDramasApi({
pageIndex: dramas.page,
pageSize: dramas.size,
keyword: dramas.keyword.trim() || undefined,
status: dramas.status || undefined
})
dramas.rows = res.data?.list || []
dramas.total = res.data?.total || 0
} finally {
dramas.loading = false
}
}
function queryDramas() {
dramas.page = 1
loadDramas()
}
async function loadNotices() {
notices.loading = true
try {
notices.rows = (await listCreatorNoticesApi()).data || []
notices.loaded = true
} finally {
notices.loading = false
}
}
async function submit(row, type) {
const label = submissionTypeText(type)
if (type === 'OFFLINE') {
try {
await ElMessageBox.confirm(
`提交「申请下线」后由后台审核,审核通过前内容仍在线。确认提交?`,
label,
{ confirmButtonText: '确认提交', cancelButtonText: '取消', type: 'warning' }
)
} catch {
return
}
}
await submitDramaApi(row.id, type)
ElMessage.success(`已提交「${label}」,等待后台审核`)
await loadDramas()
if (notices.loaded) await loadNotices()
}
async function withdraw(row) {
if (!row.submissionId) return
try {
await ElMessageBox.confirm(
'撤回后作品回到草稿、可以继续编辑,确认撤回这次提交?',
'撤回提交',
{
confirmButtonText: '确认撤回',
cancelButtonText: '取消',
confirmButtonClass: 'el-button--danger'
}
)
} catch {
return
}
await withdrawSubmissionApi(row.submissionId)
ElMessage.success('已撤回,作品回到草稿')
await loadDramas()
}
const createVisible = ref(false)
const createSaving = ref(false)
const createForm = reactive({ title: '', genre: '', description: '' })
function openCreate() {
Object.assign(createForm, { title: '', genre: '', description: '' })
createVisible.value = true
}
async function confirmCreate() {
if (!createForm.title.trim()) return ElMessage.warning('请填写作品名称')
createSaving.value = true
try {
const res = await createDramaApi({
title: createForm.title.trim(),
genre: createForm.genre.trim(),
description: createForm.description.trim()
})
ElMessage.success('草稿已创建,可以继续编辑分集')
createVisible.value = false
await loadDramas()
return res.data
} finally {
createSaving.value = false
}
}
onMounted(async () => {
// 身份不满足(未绑定 / 未选代看目标)时不打业务接口,交给外层渲染引导页
if (!(await ensureAccess())) return
loadProfile()
loadDramas()
})
return {
profile,
profileLoading,
dramas,
notices,
createVisible,
createSaving,
createForm,
loadProfile,
loadDramas,
queryDramas,
loadNotices,
submit,
withdraw,
openCreate,
confirmCreate
}
}