51 lines
1.9 KiB
TypeScript
51 lines
1.9 KiB
TypeScript
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<CloudDetail, 'status' | 'is_hidden'>) {
|
|
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)
|
|
}
|