transactionController.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. const Transaction = require('../models/Transaction');
  2. const Group = require('../models/Group');
  3. const { pool } = require('../config/database');
  4. // @desc 获取交易列表
  5. // @route GET /api/transactions
  6. // @access Private
  7. const getTransactions = async (req, res) => {
  8. try {
  9. const { page = 1, limit = 10, startDate, endDate, type, groupId } = req.query;
  10. const result = await Transaction.findAll(
  11. { startDate, endDate, type, groupId },
  12. parseInt(page),
  13. parseInt(limit)
  14. );
  15. res.json(result);
  16. } catch (error) {
  17. res.status(500).json({ message: '服务器错误' });
  18. }
  19. };
  20. // @desc 创建交易
  21. // @route POST /api/transactions
  22. // @access Private
  23. const createTransaction = async (req, res) => {
  24. try {
  25. const { groupId, type, amount } = req.body;
  26. const group = await Group.findByGroupId(groupId);
  27. if (!group) {
  28. return res.status(404).json({ message: '群组不存在' });
  29. }
  30. const id = await Transaction.create({
  31. groupId,
  32. groupName: group.group_name,
  33. type,
  34. amount
  35. });
  36. const transaction = await Transaction.findById(id);
  37. res.status(201).json(transaction);
  38. } catch (error) {
  39. res.status(500).json({ message: '服务器错误' });
  40. }
  41. };
  42. // @desc 删除交易
  43. // @route DELETE /api/transactions/:id
  44. // @access Private
  45. const deleteTransaction = async (req, res) => {
  46. try {
  47. const transaction = await Transaction.findById(req.params.id);
  48. if (!transaction) {
  49. return res.status(404).json({ message: '交易不存在' });
  50. }
  51. await Transaction.delete(req.params.id);
  52. res.json({ message: '交易已删除' });
  53. } catch (error) {
  54. res.status(500).json({ message: '服务器错误' });
  55. }
  56. };
  57. // @desc 获取仪表板数据
  58. // @route GET /api/transactions/dashboard
  59. // @access Private
  60. const getDashboardData = async (req, res) => {
  61. try {
  62. // 获取总群组数
  63. const [groupResult] = await pool.query('SELECT COUNT(*) as total FROM groups WHERE is_active = true');
  64. const totalGroups = groupResult[0].total;
  65. // 获取总交易数
  66. const [transactionResult] = await pool.query('SELECT COUNT(*) as total FROM transactions');
  67. const totalTransactions = transactionResult[0].total;
  68. // 获取总金额
  69. const [amountResult] = await pool.query(`
  70. SELECT
  71. COALESCE(SUM(CASE WHEN type = 'deposit' THEN amount ELSE -amount END), 0) as total
  72. FROM transactions
  73. `);
  74. const totalAmount = parseFloat(amountResult[0].total) || 0;
  75. // 获取今日交易数
  76. const [todayResult] = await pool.query(`
  77. SELECT COUNT(*) as total
  78. FROM transactions
  79. WHERE DATE(time) = CURDATE()
  80. `);
  81. const todayTransactions = todayResult[0].total;
  82. // 获取最近交易
  83. const [recentTransactions] = await pool.query(`
  84. SELECT
  85. t.*,
  86. u.username as operator_name,
  87. g.group_name
  88. FROM transactions t
  89. LEFT JOIN users u ON t.operator_id = u.id
  90. LEFT JOIN groups g ON t.group_id = g.group_id
  91. ORDER BY t.time DESC
  92. LIMIT 5
  93. `);
  94. // 获取活跃群组
  95. const [activeGroups] = await pool.query(`
  96. SELECT
  97. g.group_id,
  98. g.group_name,
  99. COUNT(t.id) as totalTransactions,
  100. COUNT(CASE WHEN DATE(t.time) = CURDATE() THEN 1 END) as todayTransactions
  101. FROM groups g
  102. LEFT JOIN transactions t ON g.group_id = t.group_id
  103. WHERE g.is_active = true
  104. GROUP BY g.group_id, g.group_name
  105. ORDER BY todayTransactions DESC, totalTransactions DESC
  106. LIMIT 5
  107. `);
  108. res.json({
  109. totalGroups,
  110. totalTransactions,
  111. totalAmount,
  112. todayTransactions,
  113. recentTransactions,
  114. activeGroups
  115. });
  116. } catch (error) {
  117. console.error('获取仪表板数据失败:', error);
  118. res.status(500).json({ message: '服务器错误' });
  119. }
  120. };
  121. // @desc 导出交易数据
  122. // @route GET /api/transactions/export
  123. // @access Private
  124. const exportTransactions = async (req, res) => {
  125. try {
  126. const { startDate, endDate, type, groupId } = req.query;
  127. const result = await Transaction.findAll(
  128. { startDate, endDate, type, groupId },
  129. 1,
  130. 1000000 // 导出所有数据
  131. );
  132. // 生成 CSV 数据
  133. const csvData = [
  134. ['时间', '群组', '类型', '金额'].join(','),
  135. ...result.transactions.map(t => [
  136. new Date(t.time).toLocaleString(),
  137. t.group_name,
  138. t.type === 'deposit' ? '入款' : '下发',
  139. t.amount.toFixed(2)
  140. ].join(','))
  141. ].join('\n');
  142. res.setHeader('Content-Type', 'text/csv');
  143. res.setHeader('Content-Disposition', 'attachment; filename=transactions.csv');
  144. res.send(csvData);
  145. } catch (error) {
  146. res.status(500).json({ message: '服务器错误' });
  147. }
  148. };
  149. module.exports = {
  150. getTransactions,
  151. createTransaction,
  152. deleteTransaction,
  153. getDashboardData,
  154. exportTransactions
  155. };