feat(web): 创作者中心「当前创作者」代看下拉 + 未绑定引导页
为什么:超管点进创作者中心原本是一片"未绑定创作者主体"的报错,既没说明原因也没有出路。 这批把两件事做出来:超管能在顶部选一个创作者只读代看;没有创作者身份的账号看到明确的引导页而不是白屏。 - 新增 useCreatorAccess(身份三态:granted / need-target / unbound)+ ImpersonationBar + CreatorAccessGuide, 四个页面用 CreatorCenterPage 统一套壳;身份不满足时不打业务接口,避免一串无意义的报错提示 - 代看目标存 localStorage,由 axios.request 统一给 /admin/creator-center 的请求加 X-Creator-Id 头 (不做查询参数;后端只对具备 impersonate 权限的账号认这个头) - axios 支持 silent 请求:业务码非 0 时不弹全局提示、把 Result 交给调用方判断(引导页据此分流) - 代看只读体验:代看态下「新建作品 / 编辑 / 提交审核 / 撤回」不渲染,编辑页整页禁用并提示原因 - 顶部下拉只在有 impersonate 权限时显示;无权限账号看不到、也不会请求 targets 接口
This commit is contained in:
1 parent
0a2e3e0b81
commit
685c912313
19 files changed
+995
-658
No files matched your search
@@ -3,6 +3,8 @@ import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Search } from '@element-plus/icons-vue'
|
||||
import PageHeading from '@/views/components/PageHeading.vue'
|
||||
import CreatorCenterPage from './components/CreatorCenterPage.vue'
|
||||
import { useCreatorAccess } from './composables/useCreatorAccess'
|
||||
import { useRbac } from '@/stores/rbac'
|
||||
import { dateCell } from '@/utils/format'
|
||||
import {
|
||||
@@ -17,6 +19,8 @@ import {
|
||||
const router = useRouter()
|
||||
const { can } = useRbac()
|
||||
const canEdit = can('creator-center:drama:edit')
|
||||
// 代看是只读:写操作按钮直接不渲染(后端也会拒,界面不该给出做不到的入口)
|
||||
const { impersonating } = useCreatorAccess()
|
||||
|
||||
const {
|
||||
profile,
|
||||
@@ -47,249 +51,260 @@ function openEdit(row) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageHeading
|
||||
eyebrow="创作者中心"
|
||||
title="我的作品"
|
||||
description="查看作品与审核进度,提交上线 / 下线申请。"
|
||||
>
|
||||
<el-button v-if="canEdit" type="primary" @click="openCreate">新建作品</el-button>
|
||||
</PageHeading>
|
||||
<CreatorCenterPage>
|
||||
<PageHeading
|
||||
eyebrow="创作者中心"
|
||||
title="我的作品"
|
||||
description="查看作品与审核进度,提交上线 / 下线申请。"
|
||||
>
|
||||
<el-button v-if="canEdit && !impersonating" type="primary" @click="openCreate"
|
||||
>新建作品</el-button
|
||||
>
|
||||
</PageHeading>
|
||||
|
||||
<section v-loading="profileLoading" class="panel creator-profile">
|
||||
<div class="creator-profile-main">
|
||||
<span class="creator-profile-name">{{ profile?.name || '—' }}</span>
|
||||
<el-tag
|
||||
size="small"
|
||||
effect="light"
|
||||
:type="profile?.status === 'approved' ? 'success' : 'warning'"
|
||||
>
|
||||
{{ profile?.statusText || '—' }}
|
||||
</el-tag>
|
||||
<span class="console-muted">{{ profile?.code || '' }}</span>
|
||||
</div>
|
||||
<div class="creator-profile-meta">
|
||||
<span
|
||||
>作品数 <b>{{ profile?.dramaTotal ?? 0 }}</b></span
|
||||
>
|
||||
<span
|
||||
>联系人 <b>{{ profile?.contactName || '—' }}</b></span
|
||||
>
|
||||
<span
|
||||
>联系邮箱 <b>{{ profile?.contactEmail || '—' }}</b></span
|
||||
>
|
||||
</div>
|
||||
<el-alert
|
||||
v-if="profile && profile.status === 'rejected'"
|
||||
class="creator-profile-alert"
|
||||
type="error"
|
||||
:closable="false"
|
||||
show-icon
|
||||
:title="`入驻审核未通过:${profile.auditNote || '未填写原因'}`"
|
||||
/>
|
||||
<el-alert
|
||||
v-else-if="profile && profile.status !== 'approved'"
|
||||
class="creator-profile-alert"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="入驻审核通过后才能创建作品与提交审核"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<el-tabs v-model="activeTab" @tab-change="onTabChange">
|
||||
<el-tab-pane label="我的作品" name="dramas">
|
||||
<div class="console-toolbar">
|
||||
<el-input
|
||||
v-model="dramas.keyword"
|
||||
class="console-keyword"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="搜索作品名称"
|
||||
@keyup.enter="queryDramas"
|
||||
@clear="queryDramas"
|
||||
/>
|
||||
<el-select
|
||||
v-model="dramas.status"
|
||||
class="console-select"
|
||||
clearable
|
||||
placeholder="全部状态"
|
||||
@change="queryDramas"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in DRAMA_STATUS"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="queryDramas">查询</el-button>
|
||||
<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="还没有作品,点右上角「新建作品」开始"
|
||||
<section v-loading="profileLoading" class="panel creator-profile">
|
||||
<div class="creator-profile-main">
|
||||
<span class="creator-profile-name">{{ profile?.name || '—' }}</span>
|
||||
<el-tag
|
||||
size="small"
|
||||
effect="light"
|
||||
:type="profile?.status === 'approved' ? 'success' : 'warning'"
|
||||
>
|
||||
<el-table-column label="作品" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<div class="creator-drama-cell">
|
||||
<div class="creator-drama-cover">
|
||||
<img v-if="row.cover" :src="row.cover" alt="" />
|
||||
<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>
|
||||
</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="210" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="table-actions">
|
||||
<el-button v-if="canEdit" type="primary" size="small" @click="openEdit(row)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-dropdown
|
||||
v-if="canEdit && 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 &&
|
||||
row.submissionId &&
|
||||
['SUBMITTED', 'REVIEWING'].includes(row.submissionStatus)
|
||||
"
|
||||
size="small"
|
||||
class="danger-action"
|
||||
@click="withdraw(row)"
|
||||
>撤回</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="dramas.page"
|
||||
v-model:page-size="dramas.size"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="dramas.total"
|
||||
layout="total, prev, pager, next, sizes"
|
||||
background
|
||||
@current-change="loadDramas"
|
||||
@size-change="queryDramas"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="通知" name="notices">
|
||||
<div v-loading="notices.loading" class="creator-notice-list">
|
||||
<el-empty v-if="!notices.rows.length" description="还没有审核结果通知" />
|
||||
<div
|
||||
v-for="item in notices.rows"
|
||||
:key="`${item.bizType}-${item.id}`"
|
||||
class="creator-notice"
|
||||
>
|
||||
<div class="creator-notice-head">
|
||||
<span class="creator-notice-title">{{ item.title }}</span>
|
||||
<span class="console-muted">{{
|
||||
item.time ? String(item.time).replace('T', ' ').slice(0, 19) : ''
|
||||
}}</span>
|
||||
</div>
|
||||
<p class="creator-notice-body">{{ item.content || '—' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
{{ profile?.statusText || '—' }}
|
||||
</el-tag>
|
||||
<span class="console-muted">{{ profile?.code || '' }}</span>
|
||||
</div>
|
||||
<div class="creator-profile-meta">
|
||||
<span
|
||||
>作品数 <b>{{ profile?.dramaTotal ?? 0 }}</b></span
|
||||
>
|
||||
<span
|
||||
>联系人 <b>{{ profile?.contactName || '—' }}</b></span
|
||||
>
|
||||
<span
|
||||
>联系邮箱 <b>{{ profile?.contactEmail || '—' }}</b></span
|
||||
>
|
||||
</div>
|
||||
<el-alert
|
||||
type="info"
|
||||
v-if="profile && profile.status === 'rejected'"
|
||||
class="creator-profile-alert"
|
||||
type="error"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="先建草稿,再去作品编辑页完善信息、分集与视频,然后提交审核"
|
||||
:title="`入驻审核未通过:${profile.auditNote || '未填写原因'}`"
|
||||
/>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="createVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="createSaving" @click="confirmCreate">创建草稿</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-alert
|
||||
v-else-if="profile && profile.status !== 'approved'"
|
||||
class="creator-profile-alert"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="入驻审核通过后才能创建作品与提交审核"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<el-tabs v-model="activeTab" @tab-change="onTabChange">
|
||||
<el-tab-pane label="我的作品" name="dramas">
|
||||
<div class="console-toolbar">
|
||||
<el-input
|
||||
v-model="dramas.keyword"
|
||||
class="console-keyword"
|
||||
:prefix-icon="Search"
|
||||
clearable
|
||||
placeholder="搜索作品名称"
|
||||
@keyup.enter="queryDramas"
|
||||
@clear="queryDramas"
|
||||
/>
|
||||
<el-select
|
||||
v-model="dramas.status"
|
||||
class="console-select"
|
||||
clearable
|
||||
placeholder="全部状态"
|
||||
@change="queryDramas"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in DRAMA_STATUS"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" @click="queryDramas">查询</el-button>
|
||||
<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">
|
||||
<img v-if="row.cover" :src="row.cover" alt="" />
|
||||
<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>
|
||||
</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="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
|
||||
>
|
||||
<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)
|
||||
"
|
||||
size="small"
|
||||
class="danger-action"
|
||||
@click="withdraw(row)"
|
||||
>撤回</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="dramas.page"
|
||||
v-model:page-size="dramas.size"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
:total="dramas.total"
|
||||
layout="total, prev, pager, next, sizes"
|
||||
background
|
||||
@current-change="loadDramas"
|
||||
@size-change="queryDramas"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="通知" name="notices">
|
||||
<div v-loading="notices.loading" class="creator-notice-list">
|
||||
<el-empty v-if="!notices.rows.length" description="还没有审核结果通知" />
|
||||
<div
|
||||
v-for="item in notices.rows"
|
||||
:key="`${item.bizType}-${item.id}`"
|
||||
class="creator-notice"
|
||||
>
|
||||
<div class="creator-notice-head">
|
||||
<span class="creator-notice-title">{{ item.title }}</span>
|
||||
<span class="console-muted">{{
|
||||
item.time ? String(item.time).replace('T', ' ').slice(0, 19) : ''
|
||||
}}</span>
|
||||
</div>
|
||||
<p class="creator-notice-body">{{ item.content || '—' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
Reference in new issue
Block a user