import type { CloudDetail } from '@/types/view-models' export type AdminSection = 'dashboard' | 'review' | 'images' | 'users' | 'cloud-types' export type ReviewStatus = CloudDetail['status'] export const statusMeta = { pending: { label: '待审核', type: 'warning' }, approved: { label: '已通过', type: 'success' }, rejected: { label: '已拒绝', type: 'error' }, } as const export function formatDateTime(value: string | null) { if (!value) return '未记录' const date = new Date(value) return Number.isNaN(date.getTime()) ? '未记录' : date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }) } export function visibilityLabel(cloud: Pick) { if (cloud.is_hidden) return '用户隐藏' return cloud.status === 'approved' ? '公开可见' : '尚未公开' } export function serializeCsv(headers: string[], rows: unknown[][]) { const escape = (value: unknown) => { let text = String(value ?? '') // Spreadsheet programs interpret these prefixes as formulas, even inside quoted cells. if (/^[\s]*[=+@-]/.test(text) || /^[\t\r\n]/.test(text)) text = `'${text}` return `"${text.replaceAll('"', '""')}"` } return '\uFEFF' + [headers, ...rows].map(row => row.map(escape).join(',')).join('\r\n') } export function exportCsv(name: string, headers: string[], rows: unknown[][]) { const url = URL.createObjectURL( new Blob([serializeCsv(headers, rows)], { type: 'text/csv;charset=utf-8;' }), ) const link = document.createElement('a') link.href = url link.download = `${name}-${new Date().toISOString().slice(0, 10)}.csv` link.click() setTimeout(() => URL.revokeObjectURL(url), 1000) }