Files
aijianhua/backend/routes/admin.js

265 lines
6.6 KiB
JavaScript

const express = require('express');
const dbConnector = require('../utils/dbConnector');
const { adminRequired } = require('../middlewares/auth');
const { asyncHandler } = require('../middlewares/errorHandler');
const router = express.Router();
/**
* 获取系统统计概览
*/
router.get('/statistics/overview', adminRequired, asyncHandler(async (req, res) => {
// 获取总用户数
const totalUsersResult = await dbConnector.query(
'SELECT COUNT(*) as total FROM users WHERE status = 1'
);
// 获取今日新增用户数
const newUsersTodayResult = await dbConnector.query(
'SELECT COUNT(*) as total FROM users WHERE status = 1 AND DATE(created_at) = CURDATE()'
);
// 获取总订单数
const totalOrdersResult = await dbConnector.query(
'SELECT COUNT(*) as total FROM orders'
);
// 获取总收入
const totalRevenueResult = await dbConnector.query(
'SELECT COALESCE(SUM(total_amount), 0) as total FROM orders WHERE payment_status = 1'
);
// 获取总识别次数
const totalIdentificationsResult = await dbConnector.query(
'SELECT COUNT(*) as total FROM identifications'
);
// 获取今日活跃用户数
const activeUsersTodayResult = await dbConnector.query(
`SELECT COUNT(DISTINCT user_id) as total FROM (
SELECT user_id FROM orders WHERE DATE(created_at) = CURDATE()
UNION
SELECT user_id FROM identifications WHERE DATE(created_at) = CURDATE()
) as active_users`
);
res.json({
code: 200,
message: '获取成功',
data: {
total_users: totalUsersResult[0].total,
new_users_today: newUsersTodayResult[0].total,
total_orders: totalOrdersResult[0].total,
total_revenue: parseFloat(totalRevenueResult[0].total),
total_identifications: totalIdentificationsResult[0].total,
active_users_today: activeUsersTodayResult[0].total
}
});
}));
/**
* 获取趋势数据
*/
router.get('/statistics/trend', adminRequired, asyncHandler(async (req, res) => {
const { days = 7, type = 'users' } = req.query;
const dayCount = parseInt(days);
let query = '';
let dataKey = '';
switch (type) {
case 'users':
query = `
SELECT DATE(created_at) as date, COUNT(*) as count
FROM users
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY date
`;
dataKey = 'new_users';
break;
case 'orders':
query = `
SELECT DATE(created_at) as date, COUNT(*) as count
FROM orders
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY date
`;
dataKey = 'new_orders';
break;
case 'revenue':
query = `
SELECT DATE(created_at) as date, COALESCE(SUM(total_amount), 0) as amount
FROM orders
WHERE payment_status = 1 AND created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY date
`;
dataKey = 'revenue';
break;
case 'identifications':
query = `
SELECT DATE(created_at) as date, COUNT(*) as count
FROM identifications
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL ? DAY)
GROUP BY DATE(created_at)
ORDER BY date
`;
dataKey = 'identifications';
break;
default:
return res.status(400).json({
code: 400,
message: '不支持的统计类型',
data: null
});
}
const trendData = await dbConnector.query(query, [dayCount]);
res.json({
code: 200,
message: '获取成功',
data: {
type,
days: dayCount,
trend: trendData,
total: trendData.reduce((sum, item) => sum + (item.count || item.amount || 0), 0)
}
});
}));
/**
* 获取系统配置列表
*/
router.get('/config', adminRequired, asyncHandler(async (req, res) => {
const configs = await dbConnector.query(
'SELECT config_key, config_value, config_type, description FROM system_config ORDER BY config_key'
);
res.json({
code: 200,
message: '获取成功',
data: configs
});
}));
/**
* 获取单个系统配置
*/
router.get('/config/:key', adminRequired, asyncHandler(async (req, res) => {
const { key } = req.params;
const configs = await dbConnector.query(
'SELECT config_key, config_value, config_type, description FROM system_config WHERE config_key = ?',
[key]
);
if (configs.length === 0) {
return res.status(404).json({
code: 404,
message: '配置项不存在',
data: null
});
}
res.json({
code: 200,
message: '获取成功',
data: configs[0]
});
}));
/**
* 更新系统配置
*/
router.put('/config/:key', adminRequired, asyncHandler(async (req, res) => {
const { key } = req.params;
const { value } = req.body;
if (value === undefined) {
return res.status(400).json({
code: 400,
message: '配置值不能为空',
data: null
});
}
const result = await dbConnector.query(
'UPDATE system_config SET config_value = ?, updated_at = CURRENT_TIMESTAMP WHERE config_key = ?',
[value, key]
);
if (result.affectedRows === 0) {
return res.status(404).json({
code: 404,
message: '配置项不存在',
data: null
});
}
res.json({
code: 200,
message: '更新成功',
data: null
});
}));
/**
* 获取操作日志
*/
router.get('/logs', adminRequired, asyncHandler(async (req, res) => {
const { page = 1, limit = 20, module, action, username } = req.query;
const offset = (page - 1) * limit;
let whereClause = 'WHERE 1=1';
let queryParams = [];
if (module) {
whereClause += ' AND module = ?';
queryParams.push(module);
}
if (action) {
whereClause += ' AND action = ?';
queryParams.push(action);
}
if (username) {
whereClause += ' AND username LIKE ?';
queryParams.push(`%${username}%`);
}
// 获取日志列表
const logs = await dbConnector.query(
`SELECT id, user_id, username, user_type, module, action, target_id,
description, ip_address, user_agent, created_at
FROM operation_logs ${whereClause}
ORDER BY created_at DESC
LIMIT ? OFFSET ?`,
[...queryParams, parseInt(limit), offset]
);
// 获取总数
const totalResult = await dbConnector.query(
`SELECT COUNT(*) as total FROM operation_logs ${whereClause}`,
queryParams
);
res.json({
code: 200,
message: '获取成功',
data: {
logs,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total: totalResult[0].total,
pages: Math.ceil(totalResult[0].total / limit)
}
}
});
}));
module.exports = router;