初次提交
This commit is contained in:
321
routes/system.js
Normal file
321
routes/system.js
Normal file
@@ -0,0 +1,321 @@
|
||||
const express = require('express');
|
||||
const { auth } = require('../middleware/auth');
|
||||
const { validateQuery, validate } = require('../middleware/validation');
|
||||
const { logger } = require('../config/logger');
|
||||
const { HTTP_STATUS } = require('../config/constants');
|
||||
const { getDB } = require('../database');
|
||||
const Joi = require('joi');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* 系统设置验证规则
|
||||
*/
|
||||
const systemSchemas = {
|
||||
// 更新系统设置
|
||||
updateSettings: Joi.object({
|
||||
basic: Joi.object({
|
||||
siteName: Joi.string().max(100).allow(''),
|
||||
siteDescription: Joi.string().max(500).allow(''),
|
||||
siteKeywords: Joi.string().max(200).allow(''),
|
||||
siteLogo: Joi.string().allow(''),
|
||||
siteFavicon: Joi.string().allow(''),
|
||||
|
||||
icp: Joi.string().max(100).allow('')
|
||||
}).optional(),
|
||||
features: Joi.object({
|
||||
allowRegister: Joi.boolean(),
|
||||
allowTransfer: Joi.boolean(),
|
||||
allowExchange: Joi.boolean(),
|
||||
allowReview: Joi.boolean(),
|
||||
allowComment: Joi.boolean()
|
||||
}).optional(),
|
||||
|
||||
security: Joi.object({
|
||||
maxLoginAttempts: Joi.number().integer().min(1).max(100),
|
||||
lockoutDuration: Joi.number().integer().min(1).max(86400),
|
||||
ipWhitelist: Joi.string().allow('')
|
||||
}).optional()
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取系统设置 (公开接口,不需要认证)
|
||||
* GET /api/system/settings
|
||||
*/
|
||||
router.get('/settings', async (req, res, next) => {
|
||||
try {
|
||||
|
||||
const db = getDB();
|
||||
|
||||
// 获取系统设置
|
||||
const [settings] = await db.execute(
|
||||
'SELECT setting_key, setting_value FROM system_settings'
|
||||
);
|
||||
|
||||
// 组织设置数据
|
||||
const settingsData = {
|
||||
basic: {
|
||||
siteName: '',
|
||||
siteDescription: '',
|
||||
siteKeywords: '',
|
||||
siteLogo: '',
|
||||
siteFavicon: '',
|
||||
|
||||
icp: ''
|
||||
},
|
||||
features: {
|
||||
allowRegister: true,
|
||||
allowTransfer: true,
|
||||
allowExchange: true,
|
||||
allowReview: true,
|
||||
allowComment: true
|
||||
},
|
||||
|
||||
security: {
|
||||
maxLoginAttempts: 5,
|
||||
lockoutDuration: 300,
|
||||
ipWhitelist: ''
|
||||
}
|
||||
};
|
||||
|
||||
// 填充数据库中的设置
|
||||
settings.forEach(setting => {
|
||||
const keys = setting.setting_key.split('.');
|
||||
if (keys.length === 2 && settingsData[keys[0]]) {
|
||||
try {
|
||||
// 尝试解析JSON值,如果失败则使用原始值
|
||||
settingsData[keys[0]][keys[1]] = JSON.parse(setting.setting_value);
|
||||
} catch {
|
||||
settingsData[keys[0]][keys[1]] = setting.setting_value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
logger.info('System settings retrieved', {
|
||||
settingsCount: settings.length
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: settingsData
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 更新系统设置
|
||||
* PUT /api/system/settings
|
||||
*/
|
||||
router.put('/settings',
|
||||
auth,
|
||||
validate(systemSchemas.updateSettings),
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
// 检查管理员权限
|
||||
if (req.user.role !== 'admin') {
|
||||
return res.status(HTTP_STATUS.FORBIDDEN).json({
|
||||
success: false,
|
||||
message: '权限不足'
|
||||
});
|
||||
}
|
||||
|
||||
const db = getDB();
|
||||
const settings = req.body;
|
||||
|
||||
// 开始事务
|
||||
await db.beginTransaction();
|
||||
|
||||
try {
|
||||
// 更新设置
|
||||
for (const [category, categorySettings] of Object.entries(settings)) {
|
||||
for (const [key, value] of Object.entries(categorySettings)) {
|
||||
const settingKey = `${category}.${key}`;
|
||||
const settingValue = JSON.stringify(value);
|
||||
|
||||
await db.execute(
|
||||
`INSERT INTO system_settings (setting_key, setting_value, updated_at)
|
||||
VALUES (?, ?, NOW())
|
||||
ON DUPLICATE KEY UPDATE
|
||||
setting_value = VALUES(setting_value),
|
||||
updated_at = VALUES(updated_at)`,
|
||||
[settingKey, settingValue]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await db.commit();
|
||||
|
||||
logger.info('System settings updated', {
|
||||
userId: req.user.id,
|
||||
categories: Object.keys(settings)
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: '系统设置更新成功'
|
||||
});
|
||||
} catch (error) {
|
||||
await db.rollback();
|
||||
throw error;
|
||||
}
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取系统信息
|
||||
* GET /api/system/info
|
||||
*/
|
||||
router.get('/info', auth, async (req, res, next) => {
|
||||
try {
|
||||
// 检查管理员权限
|
||||
if (req.user.role !== 'admin') {
|
||||
return res.status(HTTP_STATUS.FORBIDDEN).json({
|
||||
success: false,
|
||||
message: '权限不足'
|
||||
});
|
||||
}
|
||||
|
||||
const systemInfo = {
|
||||
version: '1.0.0',
|
||||
nodeVersion: process.version,
|
||||
platform: process.platform,
|
||||
uptime: process.uptime(),
|
||||
memoryUsage: process.memoryUsage(),
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: systemInfo
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取维护模式状态(公开接口)
|
||||
* GET /api/system/maintenance-status
|
||||
*/
|
||||
router.get('/maintenance-status', async (req, res, next) => {
|
||||
try {
|
||||
const db = getDB();
|
||||
|
||||
// 从系统设置表获取维护模式状态
|
||||
const [rows] = await db.execute(
|
||||
'SELECT setting_value FROM system_settings WHERE setting_key = ?',
|
||||
['maintenance_mode']
|
||||
);
|
||||
|
||||
const maintenanceMode = rows.length > 0 ? rows[0].setting_value === 'true' : false;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
maintenance_mode: maintenanceMode
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取维护模式状态失败:', error);
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取维护模式状态(管理员接口)
|
||||
* GET /api/system/admin/maintenance-status
|
||||
*/
|
||||
router.get('/admin/maintenance-status', auth, async (req, res, next) => {
|
||||
try {
|
||||
// 检查管理员权限
|
||||
if (req.user.role !== 'admin') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: {
|
||||
code: 'FORBIDDEN',
|
||||
message: '权限不足'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const db = getDB();
|
||||
|
||||
// 从系统设置表获取维护模式状态
|
||||
const [rows] = await db.execute(
|
||||
'SELECT setting_value FROM system_settings WHERE setting_key = ?',
|
||||
['maintenance_mode']
|
||||
);
|
||||
|
||||
const maintenanceMode = rows.length > 0 ? rows[0].setting_value === 'true' : false;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
maintenance_mode: maintenanceMode
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取维护模式状态失败:', error);
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 切换维护模式
|
||||
* POST /api/system/toggle-maintenance
|
||||
*/
|
||||
router.post('/toggle-maintenance', auth, async (req, res, next) => {
|
||||
try {
|
||||
// 检查管理员权限
|
||||
if (req.user.role !== 'admin') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: {
|
||||
code: 'FORBIDDEN',
|
||||
message: '权限不足'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const { maintenance_mode } = req.body;
|
||||
const db = getDB();
|
||||
|
||||
// 更新或插入维护模式设置
|
||||
await db.execute(
|
||||
`INSERT INTO system_settings (setting_key, setting_value, updated_at)
|
||||
VALUES ('maintenance_mode', ?, NOW())
|
||||
ON DUPLICATE KEY UPDATE
|
||||
setting_value = VALUES(setting_value),
|
||||
updated_at = NOW()`,
|
||||
[maintenance_mode ? 'true' : 'false']
|
||||
);
|
||||
|
||||
logger.info('Maintenance mode toggled', {
|
||||
userId: req.user.id,
|
||||
username: req.user.username,
|
||||
maintenanceMode: maintenance_mode
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
maintenance_mode: maintenance_mode
|
||||
},
|
||||
message: maintenance_mode ? '维护模式已开启' : '维护模式已关闭'
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('切换维护模式失败:', error);
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user