Files
ReelShortWeb/src/views/creator/composables/useCreatorAudit.js
T
Vicky f037d243cd feat(web): 08 后台四个页面落地(内容治理 / 订单与权益 / 创作者审核 / 数据看板)
为什么:08 运营后台的接口在前几轮已经实现,但运营在界面上点不到——
评论审核、举报工单、敏感词维护、订单补发/退款、权益回收、金币补发、对账、
创作者入驻与内容提交审核、运营大盘,都只能靠 curl。本轮把这四个页面补齐,
08 才算真正闭环。

- 内容治理:评论审核(通过/驳回/删除)、举报工单处理(可联动封禁)、敏感词库增删改查
- 订单与权益:订单检索与流水、补发、退款、权益检索/人工补发/回收、金币流水与人工补币、对账运行与历史
- 创作者审核:入驻审核(通过/驳回原因码/冻结)+ 资质抽屉;内容提交审核(通过/驳回)
- 数据看板:overview 五组指标 + transcode 队列与失败任务,只读;取不到的指标显示「暂无数据源」而不是 0
- 新增 console.css(工具条/抽屉/看板卡片,含深色模式),四个页面共用;时间列统一 yyyy-MM-dd HH:mm:ss
- 按钮按权限点显隐(没有 *:update / *:audit 的角色看到的是只读态),表格列与后端字段一一对应
2026-10-15 13:28:46 +08:00

168 lines
4.1 KiB
JavaScript

import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { auditCreatorApi, listCreatorDocumentsApi, pageCreatorsApi } from '@/api/admin/creator'
/** 与后端 CreatorService 的状态取值保持一致 */
export const CREATOR_STATUS = [
{ value: 'pending', label: '待审核', tag: 'warning' },
{ value: 'approved', label: '已通过', tag: 'success' },
{ value: 'rejected', label: '已驳回', tag: 'danger' },
{ value: 'frozen', label: '已冻结', tag: 'info' }
]
export const CREATOR_TYPE = [
{ value: 'INDIVIDUAL', label: '个人' },
{ value: 'COMPANY', label: '机构' }
]
export function creatorStatusMeta(status) {
return (
CREATOR_STATUS.find((item) => item.value === status) || { label: status || '-', tag: 'info' }
)
}
export function creatorTypeText(type) {
return CREATOR_TYPE.find((item) => item.value === type)?.label || type || '-'
}
export function useCreatorAudit() {
const rows = ref([])
const total = ref(0)
const loading = ref(false)
const keyword = ref('')
const statusFilter = ref(undefined)
const typeFilter = ref(undefined)
const currentPage = ref(1)
const pageSize = ref(10)
const auditVisible = ref(false)
const auditSaving = ref(false)
const auditTarget = ref(null)
const auditForm = reactive({ action: 'APPROVE', reason: '', rejectCode: '' })
const documentsVisible = ref(false)
const documentsLoading = ref(false)
const documents = ref([])
const documentsTarget = ref(null)
async function load() {
loading.value = true
try {
const res = await pageCreatorsApi({
pageIndex: currentPage.value,
pageSize: pageSize.value,
keyword: keyword.value.trim() || undefined,
status: statusFilter.value,
type: typeFilter.value
})
rows.value = res.data?.list || []
total.value = res.data?.total || 0
} finally {
loading.value = false
}
}
function query() {
currentPage.value = 1
load()
}
function reset() {
keyword.value = ''
statusFilter.value = undefined
typeFilter.value = undefined
query()
}
function handleSizeChange() {
currentPage.value = 1
load()
}
async function openDocuments(row) {
documentsTarget.value = row
documentsVisible.value = true
documentsLoading.value = true
documents.value = []
try {
documents.value = (await listCreatorDocumentsApi(row.id)).data || []
} finally {
documentsLoading.value = false
}
}
function openAudit(row, action = 'APPROVE') {
auditTarget.value = row
auditForm.action = action
auditForm.reason = ''
auditForm.rejectCode = ''
auditVisible.value = true
}
async function confirmAudit() {
const row = auditTarget.value
if (!row) return
if (auditForm.action === 'REJECT' && !auditForm.reason.trim()) {
return ElMessage.warning('驳回必须填写原因')
}
auditSaving.value = true
try {
await auditCreatorApi(row.id, {
action: auditForm.action,
reason: auditForm.reason.trim(),
rejectCode: auditForm.rejectCode.trim()
})
ElMessage.success('审核已提交')
auditVisible.value = false
await load()
} finally {
auditSaving.value = false
}
}
/** 冻结是不可逆的运营动作,单独二次确认 */
async function freeze(row) {
try {
await ElMessageBox.confirm(`冻结后「${row.name}」将无法提交内容,确认冻结?`, '冻结创作者', {
confirmButtonText: '确认冻结',
cancelButtonText: '取消',
type: 'warning'
})
} catch {
return
}
await auditCreatorApi(row.id, { action: 'FREEZE', reason: '运营冻结' })
ElMessage.success('已冻结')
await load()
}
onMounted(load)
return {
rows,
total,
loading,
keyword,
statusFilter,
typeFilter,
currentPage,
pageSize,
auditVisible,
auditSaving,
auditTarget,
auditForm,
documentsVisible,
documentsLoading,
documents,
documentsTarget,
load,
query,
reset,
handleSizeChange,
openDocuments,
openAudit,
confirmAudit,
freeze
}
}