// 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 } }