Files
verify/frontend/src/pages/agent/finance/components/columns.ts
T
admin 914e3d5127 feat: 优化代理管理页面和代理后台页面
- 添加云端数据权限列到代理管理页面
- 重构代理后台用户管理、卡密管理、财务管理页面使用DataTable组件
- 添加统计卡片到代理后台各页面
- 修复agent-apps相关类型错误
- 添加代理后台页面i18n国际化支持

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 21:00:33 +08:00

87 lines
3.4 KiB
TypeScript

import type { ColumnDef } from '@tanstack/vue-table'
import type { Composer } from 'vue-i18n'
import { ArrowDownLeft, ArrowUpRight, RotateCcw } from 'lucide-vue-next'
import { h } from 'vue'
import type { Transaction } from '../data/schema'
import Badge from '@/components/ui/badge/Badge.vue'
export function getColumns(t: Composer['t']): ColumnDef<Transaction>[] {
return [
{
accessorKey: 'type',
header: () => t('agent.finance.columns.type'),
cell: ({ row }) => {
const type = row.getValue('type') as string
const typeMap: Record<string, { label: string, variant: 'default' | 'secondary' | 'destructive', icon: any }> = {
recharge: { label: t('agent.finance.types.recharge'), variant: 'default', icon: ArrowDownLeft },
consume: { label: t('agent.finance.types.consume'), variant: 'secondary', icon: ArrowUpRight },
refund: { label: t('agent.finance.types.refund'), variant: 'default', icon: RotateCcw },
}
const config = typeMap[type] || { label: type, variant: 'secondary', icon: ArrowUpRight }
const iconClass = type === 'recharge' ? 'text-green-500' : type === 'refund' ? 'text-blue-500' : 'text-red-500'
const bgClass = type === 'recharge' ? 'bg-green-500/10' : type === 'refund' ? 'bg-blue-500/10' : 'bg-red-500/10'
return h('div', { class: 'flex items-center gap-2' }, [
h('div', { class: `size-8 rounded-lg flex items-center justify-center ${bgClass}` }, [
h(config.icon, { class: `size-4 ${iconClass}` }),
]),
h('span', config.label),
])
},
},
{
accessorKey: 'description',
header: () => t('agent.finance.columns.description'),
cell: ({ row }) => {
const description = row.getValue('description') as string
const type = row.getValue('type') as string
return h('span', { class: 'text-muted-foreground' }, description || t(`agent.finance.types.${type}`) || '-')
},
},
{
accessorKey: 'amount',
header: () => t('agent.finance.columns.amount'),
cell: ({ row }) => {
const type = row.getValue('type') as string
const amount = row.getValue('amount') as number
const prefix = type === 'recharge' || type === 'refund' ? '+' : '-'
const textClass = type === 'recharge' || type === 'refund' ? 'text-green-500' : 'text-red-500'
return h('span', { class: `font-semibold ${textClass}` }, `${prefix}¥${(amount || 0).toFixed(2)}`)
},
},
{
accessorKey: 'balance',
header: () => t('agent.finance.columns.balance'),
cell: ({ row }) => {
const balance = row.getValue('balance') as number
return h('span', { class: 'text-muted-foreground' }, ${(balance || 0).toFixed(2)}`)
},
},
{
accessorKey: 'created_at',
header: () => t('agent.finance.columns.createdAt'),
cell: ({ row }) => {
const createdAt = row.getValue('created_at') as string
if (!createdAt) return '-'
try {
const date = new Date(createdAt)
if (Number.isNaN(date.getTime())) return '-'
return h('span', { class: 'text-muted-foreground whitespace-nowrap' }, date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
}))
}
catch {
return '-'
}
},
},
]
}