/** * 系统管理控制器 * @file systemController.js * @description 处理系统配置和菜单权限管理相关业务逻辑 */ const { SystemConfig, MenuPermission, User, Role } = require('../models'); const logger = require('../utils/logger'); const { validationResult } = require('express-validator'); const { Op } = require('sequelize'); /** * 获取系统配置列表 * @route GET /api/system/configs */ const getSystemConfigs = async (req, res) => { try { const { category, is_public } = req.query; const whereClause = {}; if (category) { whereClause.category = category; } if (is_public !== undefined) { whereClause.is_public = is_public === 'true'; } const configs = await SystemConfig.findAll({ where: whereClause, order: [['category', 'ASC'], ['sort_order', 'ASC']], attributes: { exclude: ['updated_by'] } // 隐藏敏感字段 }); // 解析配置值 const parsedConfigs = configs.map(config => ({ ...config.dataValues, parsed_value: SystemConfig.parseValue(config.config_value, config.config_type) })); logger.info(`用户 ${req.user.username} 获取系统配置列表,分类: ${category || '全部'}`); res.json({ success: true, data: parsedConfigs, total: parsedConfigs.length }); } catch (error) { logger.error('获取系统配置列表失败:', error); res.status(500).json({ success: false, message: '获取系统配置失败', error: error.message }); } }; /** * 获取公开系统配置(前端使用) * @route GET /api/system/configs/public */ const getPublicConfigs = async (req, res) => { try { const configs = await SystemConfig.getPublicConfigs(); res.json({ success: true, data: configs }); } catch (error) { logger.error('获取公开系统配置失败:', error); res.status(500).json({ success: false, message: '获取系统配置失败', error: error.message }); } }; /** * 更新系统配置 * @route PUT /api/system/configs/:id */ const updateSystemConfig = async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, message: '参数验证失败', errors: errors.array() }); } const { id } = req.params; const { config_value, description } = req.body; const config = await SystemConfig.findByPk(id); if (!config) { return res.status(404).json({ success: false, message: '配置项不存在' }); } if (!config.is_editable) { return res.status(403).json({ success: false, message: '该配置项不允许编辑' }); } await config.update({ config_value: SystemConfig.stringifyValue(config_value), config_type: SystemConfig.detectType(config_value), description, updated_by: req.user.id }); logger.info(`用户 ${req.user.username} 更新系统配置: ${config.config_key}`); res.json({ success: true, message: '配置更新成功', data: { ...config.dataValues, parsed_value: SystemConfig.parseValue(config.config_value, config.config_type) } }); } catch (error) { logger.error('更新系统配置失败:', error); res.status(500).json({ success: false, message: '更新配置失败', error: error.message }); } }; /** * 创建系统配置 * @route POST /api/system/configs */ const createSystemConfig = async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, message: '参数验证失败', errors: errors.array() }); } const { config_key, config_value, category = 'general', description, is_public = false, is_editable = true, sort_order = 0 } = req.body; const config = await SystemConfig.create({ config_key, config_value: SystemConfig.stringifyValue(config_value), config_type: SystemConfig.detectType(config_value), category, description, is_public, is_editable, sort_order, updated_by: req.user.id }); logger.info(`用户 ${req.user.username} 创建系统配置: ${config_key}`); res.status(201).json({ success: true, message: '配置创建成功', data: { ...config.dataValues, parsed_value: SystemConfig.parseValue(config.config_value, config.config_type) } }); } catch (error) { logger.error('创建系统配置失败:', error); res.status(500).json({ success: false, message: '创建配置失败', error: error.message }); } }; /** * 删除系统配置 * @route DELETE /api/system/configs/:id */ const deleteSystemConfig = async (req, res) => { try { const { id } = req.params; const config = await SystemConfig.findByPk(id); if (!config) { return res.status(404).json({ success: false, message: '配置项不存在' }); } if (!config.is_editable) { return res.status(403).json({ success: false, message: '该配置项不允许删除' }); } await config.destroy(); logger.info(`用户 ${req.user.username} 删除系统配置: ${config.config_key}`); res.json({ success: true, message: '配置删除成功' }); } catch (error) { logger.error('删除系统配置失败:', error); res.status(500).json({ success: false, message: '删除配置失败', error: error.message }); } }; /** * 获取配置分类列表 * @route GET /api/system/configs/categories */ const getConfigCategories = async (req, res) => { try { const categories = await SystemConfig.findAll({ attributes: ['category'], group: ['category'], order: [['category', 'ASC']] }); const categoryList = categories.map(item => item.category); res.json({ success: true, data: categoryList }); } catch (error) { logger.error('获取配置分类失败:', error); res.status(500).json({ success: false, message: '获取配置分类失败', error: error.message }); } }; /** * 获取菜单权限列表 * @route GET /api/system/menus */ const getMenuPermissions = async (req, res) => { try { const menus = await MenuPermission.findAll({ order: [['sort_order', 'ASC']], include: [ { model: MenuPermission, as: 'children', required: false }, { model: MenuPermission, as: 'parent', required: false } ] }); // 构建菜单树 const menuTree = MenuPermission.buildMenuTree(menus); logger.info(`用户 ${req.user.username} 获取菜单权限列表`); res.json({ success: true, data: menuTree, total: menus.length }); } catch (error) { logger.error('获取菜单权限列表失败:', error); res.status(500).json({ success: false, message: '获取菜单权限失败', error: error.message }); } }; /** * 获取用户菜单(根据权限过滤) * @route GET /api/system/menus/user */ const getUserMenus = async (req, res) => { try { const user = await User.findByPk(req.user.id, { include: [{ model: Role, as: 'role', attributes: ['name'] }] }); if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }); } // 获取用户角色 const userRoles = [user.role?.name || 'user']; // 获取用户权限菜单 const userMenus = await MenuPermission.getUserMenus(userRoles, []); res.json({ success: true, data: userMenus, userRoles }); } catch (error) { logger.error('获取用户菜单失败:', error); res.status(500).json({ success: false, message: '获取用户菜单失败', error: error.message }); } }; /** * 更新菜单权限 * @route PUT /api/system/menus/:id */ const updateMenuPermission = async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, message: '参数验证失败', errors: errors.array() }); } const { id } = req.params; const { menu_name, menu_path, required_roles, required_permissions, icon, sort_order, is_visible, is_enabled, description } = req.body; const menu = await MenuPermission.findByPk(id); if (!menu) { return res.status(404).json({ success: false, message: '菜单项不存在' }); } await menu.update({ menu_name, menu_path, required_roles: required_roles ? JSON.stringify(required_roles) : null, required_permissions: required_permissions ? JSON.stringify(required_permissions) : null, icon, sort_order, is_visible, is_enabled, description }); logger.info(`用户 ${req.user.username} 更新菜单权限: ${menu.menu_key}`); res.json({ success: true, message: '菜单权限更新成功', data: menu }); } catch (error) { logger.error('更新菜单权限失败:', error); res.status(500).json({ success: false, message: '更新菜单权限失败', error: error.message }); } }; /** * 获取系统统计信息 * @route GET /api/system/stats */ const getSystemStats = async (req, res) => { try { const stats = { configs: { total: await SystemConfig.count(), public: await SystemConfig.count({ where: { is_public: true } }), editable: await SystemConfig.count({ where: { is_editable: true } }) }, menus: { total: await MenuPermission.count(), visible: await MenuPermission.count({ where: { is_visible: true } }), enabled: await MenuPermission.count({ where: { is_enabled: true } }) }, users: { total: await User.count(), active: await User.count({ where: { status: 'active' } }) }, roles: { total: await Role.count() } }; res.json({ success: true, data: stats }); } catch (error) { logger.error('获取系统统计信息失败:', error); res.status(500).json({ success: false, message: '获取系统统计失败', error: error.message }); } }; /** * 初始化系统配置 * @route POST /api/system/init */ const initializeSystem = async (req, res) => { try { // 初始化默认菜单权限 await MenuPermission.initDefaultMenus(); // 初始化默认系统配置 const defaultConfigs = [ { config_key: 'system.name', config_value: '宁夏智慧养殖监管平台', category: 'general', description: '系统名称', is_public: true }, { config_key: 'system.version', config_value: '2.1.0', category: 'general', description: '系统版本', is_public: true, is_editable: false }, { config_key: 'pagination.default_page_size', config_value: '10', config_type: 'number', category: 'ui', description: '默认分页大小', is_public: true }, { config_key: 'notification.email_enabled', config_value: 'true', config_type: 'boolean', category: 'notification', description: '启用邮件通知' }, { config_key: 'security.session_timeout', config_value: '3600', config_type: 'number', category: 'security', description: '会话超时时间(秒)' }, { config_key: 'monitoring.realtime_enabled', config_value: 'true', config_type: 'boolean', category: 'monitoring', description: '启用实时监控', is_public: true }, { config_key: 'report.auto_cleanup_days', config_value: '30', config_type: 'number', category: 'report', description: '报表文件自动清理天数' } ]; for (const configData of defaultConfigs) { const existing = await SystemConfig.findOne({ where: { config_key: configData.config_key } }); if (!existing) { await SystemConfig.create({ ...configData, updated_by: req.user.id }); } } logger.info(`管理员 ${req.user.username} 初始化系统配置`); res.json({ success: true, message: '系统初始化完成' }); } catch (error) { logger.error('系统初始化失败:', error); res.status(500).json({ success: false, message: '系统初始化失败', error: error.message }); } }; /** * 批量更新系统配置 * @route PUT /api/system/configs/batch */ const batchUpdateConfigs = async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, message: '参数验证失败', errors: errors.array() }); } const { configs } = req.body; if (!Array.isArray(configs)) { return res.status(400).json({ success: false, message: 'configs必须是数组' }); } const results = []; for (const configData of configs) { try { const { config_key, config_value } = configData; const existingConfig = await SystemConfig.findOne({ where: { config_key } }); if (existingConfig && existingConfig.is_editable) { await existingConfig.update({ config_value: SystemConfig.stringifyValue(config_value), config_type: SystemConfig.detectType(config_value), updated_by: req.user.id }); results.push({ config_key, success: true }); } else if (!existingConfig) { results.push({ config_key, success: false, reason: '配置不存在' }); } else { results.push({ config_key, success: false, reason: '配置不可编辑' }); } } catch (error) { results.push({ config_key: configData.config_key, success: false, reason: error.message }); } } logger.info(`用户 ${req.user.username} 批量更新系统配置`); res.json({ success: true, message: '批量更新完成', data: results }); } catch (error) { logger.error('批量更新系统配置失败:', error); res.status(500).json({ success: false, message: '批量更新失败', error: error.message }); } }; /** * 重置系统配置到默认值 * @route POST /api/system/configs/:id/reset */ const resetSystemConfig = async (req, res) => { try { const { id } = req.params; const config = await SystemConfig.findByPk(id); if (!config) { return res.status(404).json({ success: false, message: '配置项不存在' }); } if (!config.is_editable) { return res.status(403).json({ success: false, message: '该配置项不允许重置' }); } // 这里可以根据需要实现默认值重置逻辑 // 暂时返回成功消息 logger.info(`用户 ${req.user.username} 重置系统配置: ${config.config_key}`); res.json({ success: true, message: '配置重置成功' }); } catch (error) { logger.error('重置系统配置失败:', error); res.status(500).json({ success: false, message: '重置配置失败', error: error.message }); } }; module.exports = { getSystemConfigs, getPublicConfigs, updateSystemConfig, createSystemConfig, deleteSystemConfig, getConfigCategories, getMenuPermissions, getUserMenus, updateMenuPermission, getSystemStats, initializeSystem, batchUpdateConfigs, resetSystemConfig };