Files
accountbook/server/routes/categories.js
T

99 lines
3.2 KiB
JavaScript

const express = require('express');
const db = require('../config/database');
const { authenticate } = require('../middleware/auth');
const { asyncHandler, AppError } = require('../middleware/errorHandler');
const { validateCategoryPayload } = require('../utils/validators');
const router = express.Router();
const defaultCategories = {
expense: [
{ name: '餐饮', icon: '🍜' },
{ name: '买菜', icon: '🥬' },
{ name: '交通', icon: '🚗' },
{ name: '购物', icon: '🛒' },
{ name: '娱乐', icon: '🎮' },
{ name: '房租', icon: '🏠' },
{ name: '房贷', icon: '🏦' },
{ name: '水电', icon: '💧' },
{ name: '衣服', icon: '👔' },
{ name: '通讯', icon: '📱' },
{ name: '日用品', icon: '🧴' },
{ name: '美妆', icon: '💄' },
{ name: '医疗', icon: '🏥' },
{ name: '养娃', icon: '👶' },
{ name: '家电', icon: '📺' },
{ name: '家具', icon: '🛋️' },
{ name: '装修', icon: '🔨' },
{ name: '宠物', icon: '🐕' },
{ name: '其他', icon: '📝' },
],
income: [
{ name: '工资', icon: '💰' },
{ name: '奖金', icon: '🎁' },
{ name: '理财', icon: '📈' },
{ name: '红包', icon: '🧧' },
{ name: '其他', icon: '📝' },
],
};
// 获取分类列表
router.get('/', authenticate, asyncHandler(async (req, res) => {
const stmt = db.prepare('SELECT * FROM categories WHERE user_id = ? ORDER BY type, id');
const customCategories = stmt.all(req.userId);
// 合并默认分类和自定义分类
const categories = {
expense: [
...defaultCategories.expense.map((c) => ({ ...c, is_default: true })),
...customCategories.filter((c) => c.type === 'expense'),
],
income: [
...defaultCategories.income.map((c) => ({ ...c, is_default: true })),
...customCategories.filter((c) => c.type === 'income'),
],
};
res.json(categories);
}));
// 新增自定义分类
router.post('/', authenticate, asyncHandler(async (req, res) => {
const { type, name, icon } = req.body;
const validationError = validateCategoryPayload(req.body);
if (validationError) {
throw new AppError(validationError, 400, 'VALIDATION_ERROR');
}
const stmt = db.prepare(`
INSERT INTO categories (user_id, type, name, icon, is_default)
VALUES (?, ?, ?, ?, 0)
`);
const result = stmt.run(req.userId, type, name.trim(), icon.trim());
console.log(`Category created: user=${req.userId}, id=${result.lastInsertRowid}`);
res.json({ id: result.lastInsertRowid, message: '添加成功' });
}));
// 删除自定义分类
router.delete('/:id', authenticate, asyncHandler(async (req, res) => {
const { id } = req.params;
const checkStmt = db.prepare('SELECT * FROM categories WHERE id = ? AND user_id = ? AND is_default = 0');
const category = checkStmt.get(id, req.userId);
if (!category) {
throw new AppError('分类不存在或无法删除', 404, 'NOT_FOUND');
}
const stmt = db.prepare('DELETE FROM categories WHERE id = ? AND user_id = ?');
stmt.run(id, req.userId);
console.log(`Category deleted: user=${req.userId}, id=${id}`);
res.json({ message: '删除成功' });
}));
module.exports = router;