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

95 lines
2.9 KiB
JavaScript

// Author: fruit.com.cn
import { onMounted, ref } from 'vue'
import { getCreatorDashboardApi } from '@/api/admin/creatorCenter'
import { useCreatorAccess } from './useCreatorAccess'
/**
* 指标展示配置:key 与后端 /admin/creator-center/dashboard 的字段一一对应,
* 不在前端编字段;口径见后端 CreatorDashboardService 注释与 docs/api-phase1.md「2.10」。
*/
export const DASHBOARD_GROUPS = [
{
key: 'drama',
title: '我的作品',
metrics: [
{ key: 'total', label: '作品总数' },
{ key: 'draft', label: '草稿' },
{ key: 'reviewing', label: '审核中' },
{ key: 'approved', label: '待发布' },
{ key: 'published', label: '已上线' },
{ key: 'offline', label: '已下线' },
{ key: 'episodeTotal', label: '分集总数' },
{ key: 'episodeWithMedia', label: '有片源分集' }
]
},
{
key: 'playback',
title: '播放',
metrics: [
{ key: 'viewTotal', label: '累计观看' },
{ key: 'playTotal', label: '累计播放' },
{ key: 'watchedDramas', label: '看过我的剧(用户×剧)' },
{ key: 'finishedDramas', label: '其中标记完播' },
{ key: 'finishRate', label: '完播率' },
{ key: 'playEvents7d', label: '近 7 天播放流水' },
{ key: 'playEventsTotal', label: '播放流水总量' },
{ key: 'finishEvents', label: '完播事件' }
]
},
{
key: 'interaction',
title: '互动',
metrics: [
{ key: 'favoriteTotal', label: '收藏' },
{ key: 'commentTotal', label: '评论' },
{ key: 'commentPending', label: '待审评论' }
]
},
{
key: 'revenue',
title: '解锁收入',
metrics: [
{ key: 'unlockCount', label: '解锁笔数' },
{ key: 'coinIncome', label: '金币收入' },
{ key: 'coinIncome7d', label: '近 7 天金币收入' },
{ key: 'paidOrderAmount', label: '法币收入金额' }
]
}
]
export function useCreatorDashboard() {
const { ensureAccess } = useCreatorAccess()
const loading = ref(false)
const board = ref(null)
const lastUpdated = ref('')
async function load() {
loading.value = true
try {
board.value = (await getCreatorDashboardApi()).data || null
lastUpdated.value = new Date().toLocaleString()
} finally {
loading.value = false
}
}
/** 取不到的指标后端给 null,这里显示「暂无数据源」而不是 0 */
function display(value) {
if (value === null || value === undefined) return '暂无数据源'
if (typeof value === 'number' && !Number.isInteger(value)) return value.toFixed(3)
return value
}
function groupValue(groupKey, metricKey) {
return board.value?.[groupKey]?.[metricKey]
}
onMounted(async () => {
if (!(await ensureAccess())) return
await load()
})
return { loading, board, lastUpdated, load, display, groupValue }
}