| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /**
- * 配置路由模块
- */
- const express = require('express');
- const router = express.Router();
- const fs = require('fs').promises;
- const path = require('path');
- const logger = require('../logger');
- const { requireLogin } = require('../middleware/auth');
- const configService = require('../services/configService');
- // 修改配置文件路径,使用独立的配置文件
- const configFilePath = path.join(__dirname, '../data/config.json');
- // 默认配置
- const DEFAULT_CONFIG = {
- proxyDomain: 'registry-1.docker.io',
- logo: '',
- theme: 'light'
- };
- // 确保配置文件存在
- async function ensureConfigFile() {
- try {
- // 确保目录存在
- const dir = path.dirname(configFilePath);
- try {
- await fs.access(dir);
- } catch (error) {
- await fs.mkdir(dir, { recursive: true });
- logger.info(`创建目录: ${dir}`);
- }
-
- // 检查文件是否存在
- try {
- await fs.access(configFilePath);
- const data = await fs.readFile(configFilePath, 'utf8');
- return JSON.parse(data);
- } catch (error) {
- // 文件不存在或JSON解析错误,创建默认配置
- await fs.writeFile(configFilePath, JSON.stringify(DEFAULT_CONFIG, null, 2));
- logger.info(`创建默认配置文件: ${configFilePath}`);
- return DEFAULT_CONFIG;
- }
- } catch (error) {
- logger.error(`配置文件操作失败: ${error.message}`);
- // 出错时返回默认配置以确保API不会失败
- return DEFAULT_CONFIG;
- }
- }
- // 获取配置
- router.get('/config', async (req, res) => {
- try {
- const config = await ensureConfigFile();
- res.json(config);
- } catch (error) {
- logger.error('获取配置失败:', error);
- // 即使失败也返回默认配置
- res.json(DEFAULT_CONFIG);
- }
- });
- // 保存配置
- router.post('/config', async (req, res) => {
- try {
- const newConfig = req.body;
-
- // 验证请求数据
- if (!newConfig || typeof newConfig !== 'object') {
- return res.status(400).json({
- error: '无效的配置数据',
- details: '配置必须是一个对象'
- });
- }
-
- // 读取现有配置
- let existingConfig;
- try {
- existingConfig = await ensureConfigFile();
- } catch (error) {
- existingConfig = DEFAULT_CONFIG;
- }
-
- // 合并配置
- const mergedConfig = { ...existingConfig, ...newConfig };
-
- // 保存到文件
- await fs.writeFile(configFilePath, JSON.stringify(mergedConfig, null, 2));
-
- res.json({ success: true, message: '配置已保存' });
- } catch (error) {
- logger.error('保存配置失败:', error);
- res.status(500).json({
- error: '保存配置失败',
- details: error.message
- });
- }
- });
- // 获取监控配置
- router.get('/monitoring-config', async (req, res) => {
- logger.info('收到监控配置请求');
-
- try {
- logger.info('读取监控配置...');
- const config = await configService.getConfig();
-
- if (!config.monitoringConfig) {
- logger.info('监控配置不存在,创建默认配置');
- config.monitoringConfig = {
- notificationType: 'wechat',
- webhookUrl: '',
- telegramToken: '',
- telegramChatId: '',
- monitorInterval: 60,
- isEnabled: false
- };
- await configService.saveConfig(config);
- }
-
- logger.info('返回监控配置');
- res.json({
- notificationType: config.monitoringConfig.notificationType || 'wechat',
- webhookUrl: config.monitoringConfig.webhookUrl || '',
- telegramToken: config.monitoringConfig.telegramToken || '',
- telegramChatId: config.monitoringConfig.telegramChatId || '',
- monitorInterval: config.monitoringConfig.monitorInterval || 60,
- isEnabled: config.monitoringConfig.isEnabled || false
- });
- } catch (error) {
- logger.error('获取监控配置失败:', error);
- res.status(500).json({ error: '获取监控配置失败', details: error.message });
- }
- });
- // 保存监控配置
- router.post('/monitoring-config', requireLogin, async (req, res) => {
- try {
- const {
- notificationType,
- webhookUrl,
- telegramToken,
- telegramChatId,
- monitorInterval,
- isEnabled
- } = req.body;
-
- // 验证必填字段
- if (!notificationType) {
- return res.status(400).json({ error: '通知类型不能为空' });
- }
-
- // 根据通知类型验证对应的字段
- if (notificationType === 'wechat' && !webhookUrl) {
- return res.status(400).json({ error: '企业微信 Webhook URL 不能为空' });
- }
-
- if (notificationType === 'telegram' && (!telegramToken || !telegramChatId)) {
- return res.status(400).json({ error: 'Telegram Token 和 Chat ID 不能为空' });
- }
-
- // 保存配置
- const config = await configService.getConfig();
- config.monitoringConfig = {
- notificationType,
- webhookUrl: webhookUrl || '',
- telegramToken: telegramToken || '',
- telegramChatId: telegramChatId || '',
- monitorInterval: parseInt(monitorInterval) || 60,
- isEnabled: !!isEnabled
- };
-
- await configService.saveConfig(config);
- logger.info('监控配置已更新');
-
- res.json({ success: true, message: '监控配置已保存' });
- } catch (error) {
- logger.error('保存监控配置失败:', error);
- res.status(500).json({ error: '保存监控配置失败', details: error.message });
- }
- });
- // 测试通知
- router.post('/test-notification', requireLogin, async (req, res) => {
- try {
- const { notificationType, webhookUrl, telegramToken, telegramChatId } = req.body;
-
- // 验证参数
- if (!notificationType) {
- return res.status(400).json({ error: '通知类型不能为空' });
- }
-
- if (notificationType === 'wechat' && !webhookUrl) {
- return res.status(400).json({ error: '企业微信 Webhook URL 不能为空' });
- }
-
- if (notificationType === 'telegram' && (!telegramToken || !telegramChatId)) {
- return res.status(400).json({ error: 'Telegram Token 和 Chat ID 不能为空' });
- }
-
- // 构造测试消息
- const testMessage = {
- title: '测试通知',
- content: `这是一条测试通知消息,发送时间: ${new Date().toLocaleString('zh-CN')}`,
- type: 'info'
- };
-
- // 模拟发送通知
- logger.info('发送测试通知:', testMessage);
-
- // TODO: 实际发送通知的逻辑
- // 这里仅做模拟,实际应用中需要实现真正的通知发送逻辑
-
- // 返回成功
- res.json({ success: true, message: '测试通知已发送' });
- } catch (error) {
- logger.error('发送测试通知失败:', error);
- res.status(500).json({ error: '发送测试通知失败', details: error.message });
- }
- });
- // 导出路由
- module.exports = router;
|