Files
money.sori.studio/server/api/export/transactions.csv.get.ts

38 lines
1.4 KiB
TypeScript

import { setHeader } from 'h3'
import { format } from 'date-fns'
import { prisma } from '../../utils/db'
import { requireUser } from '../../utils/auth'
export default defineEventHandler(async (event) => {
const user = await requireUser(event)
const rows = await prisma.transaction.findMany({
where: { userId: user.id },
include: { asset: true, category: { include: { parent: true } } },
orderBy: { occurredAt: 'desc' }
})
const escape = (value: unknown) => `"${String(value ?? '').replaceAll('"', '""')}"`
const categoryName = (row: typeof rows[number]) => row.category.name
const parentCategoryName = (row: typeof rows[number]) => row.category.parent?.name || ''
const lines = [
['날짜', '유형', '자산', '상위분류', '분류', '금액', '내용', '메모', '위도', '경도', '거래ID'].map(escape).join(','),
...rows.map(row => [
format(row.occurredAt, 'yyyy-MM-dd'),
row.type === 'income' ? '수입' : '지출',
row.asset.name,
parentCategoryName(row),
categoryName(row),
row.amount,
row.title,
row.memo,
row.latitude,
row.longitude,
row.id
].map(escape).join(','))
]
setHeader(event, 'content-type', 'text/csv; charset=utf-8')
setHeader(event, 'content-disposition', 'attachment; filename="money-transactions.csv"')
return `\uFEFF${lines.join('\n')}`
})