Files
services/controllers/export.js
T

88 lines
2.8 KiB
JavaScript
Raw Normal View History

2026-05-26 13:37:55 +08:00
const { query } = require('../config/database')
function toCSV(headers, rows) {
const escape = (v) => {
if (v === null || v === undefined) return ''
const s = String(v)
if (s.includes(',') || s.includes('"') || s.includes('\n')) {
return '"' + s.replace(/"/g, '""') + '"'
}
return s
}
const lines = [headers.map(escape).join(',')]
for (const row of rows) {
lines.push(headers.map(h => escape(row[h])).join(','))
}
return lines.join('\n')
}
async function exportGoods(ctx) {
const rows = await query(
'SELECT g.id, g.name, g.price, g.original_price, g.unit, g.stock, g.sales, g.pricing_type, c.name as category_name FROM goods g LEFT JOIN categories c ON g.category_id = c.id ORDER BY g.id ASC'
)
const csv = toCSV(
['id', 'name', 'price', 'original_price', 'unit', 'stock', 'sales', 'category_name'],
rows
)
ctx.set('Content-Type', 'text/csv; charset=utf-8')
ctx.set('Content-Disposition', 'attachment; filename="goods.csv"')
ctx.body = '\uFEFF' + csv
}
async function exportOrders(ctx) {
const statusMap = { pending: '待付款', paid: '已付款', completed: '已完成', cancelled: '已取消' }
const rows = await query(
'SELECT o.id, o.total_price, o.status, o.created_at, u.phone as user_phone FROM orders o LEFT JOIN users u ON o.user_id = u.id ORDER BY o.created_at DESC'
)
const mapped = rows.map(r => ({
...r,
status: statusMap[r.status] || r.status,
total_price: parseFloat(r.total_price)
}))
const csv = toCSV(
['id', 'total_price', 'status', 'created_at', 'user_phone'],
mapped
)
ctx.set('Content-Type', 'text/csv; charset=utf-8')
ctx.set('Content-Disposition', 'attachment; filename="orders.csv"')
ctx.body = '\uFEFF' + csv
}
async function exportStock(ctx) {
const rows = await query(
'SELECT g.id, g.name, g.price, COALESCE(s.quantity, 0) as quantity FROM goods g LEFT JOIN stock s ON g.id = s.goods_id ORDER BY quantity ASC'
)
const csv = toCSV(
['id', 'name', 'price', 'quantity'],
rows
)
ctx.set('Content-Type', 'text/csv; charset=utf-8')
ctx.set('Content-Disposition', 'attachment; filename="stock.csv"')
ctx.body = '\uFEFF' + csv
}
async function exportPurchases(ctx) {
const rows = await query(
'SELECT p.id, p.supplier_name, p.total, p.status, p.created_at FROM purchases p ORDER BY p.created_at DESC'
)
const mapped = rows.map(r => ({
...r,
status: r.status === 0 ? '待入库' : r.status === 1 ? '已入库' : String(r.status),
total: parseFloat(r.total)
}))
const csv = toCSV(
['id', 'supplier_name', 'total', 'status', 'created_at'],
mapped
)
ctx.set('Content-Type', 'text/csv; charset=utf-8')
ctx.set('Content-Disposition', 'attachment; filename="purchases.csv"')
ctx.body = '\uFEFF' + csv
}
module.exports = {
exportGoods,
exportOrders,
exportStock,
exportPurchases
}