Files
MHXY_WEB_VUE/backend/src/controllers/configController.ts

262 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Request, Response } from 'express';
import { AppDataSource } from '../config/database';
import { Config } from '../models/Config';
import { EnvHelper } from '../utils/envHelper';
import nodemailer from 'nodemailer';
/**
* 系统配置控制器
* 处理系统配置相关的操作,包括获取配置、更新配置、测试邮件等
*/
export class ConfigController {
/**
* 获取所有配置
* 按配置类型分组返回
* @param req - Express请求对象
* @param res - Express响应对象
*/
async getAllConfigs(req: Request, res: Response) {
try {
const configRepository = AppDataSource.getRepository(Config);
const configs = await configRepository.find({
order: { configType: 'ASC', id: 'ASC' }
});
const groupedConfigs: Record<string, any[]> = {
basic: [],
security: [],
game: [],
payment: [],
email: []
};
configs.forEach(config => {
if (groupedConfigs[config.configType]) {
groupedConfigs[config.configType].push({
id: config.id,
configKey: config.configKey,
configValue: config.configValue,
description: config.description
});
}
});
return res.json({
success: true,
data: groupedConfigs
});
} catch (error) {
console.error('获取配置失败:', error);
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
/**
* 更新配置
* 批量更新配置,同时更新数据库和.env文件
* @param req - Express请求对象
* @param res - Express响应对象
*/
async updateConfigs(req: Request, res: Response) {
try {
const { configs } = req.body;
if (!configs || !Array.isArray(configs)) {
return res.status(400).json({
success: false,
message: '配置数据格式错误'
});
}
const configRepository = AppDataSource.getRepository(Config);
const envUpdates: Record<string, string> = {};
for (const config of configs) {
if (!config.configKey || config.configValue === undefined) {
continue;
}
const existingConfig = await configRepository.findOne({
where: { configKey: config.configKey }
});
if (existingConfig) {
existingConfig.configValue = String(config.configValue);
await configRepository.save(existingConfig);
}
const envKey = this.mapConfigKeyToEnvKey(config.configKey);
if (envKey) {
envUpdates[envKey] = String(config.configValue);
}
}
const envFilePath = EnvHelper.getEnvFilePath(process.env.NODE_ENV || 'development');
const updateSuccess = EnvHelper.updateEnvFile(envFilePath, envUpdates);
if (!updateSuccess) {
return res.status(500).json({
success: false,
message: '更新.env文件失败'
});
}
return res.json({
success: true,
message: '配置更新成功'
});
} catch (error) {
console.error('更新配置失败:', error);
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
/**
* 测试邮件发送
* @param req - Express请求对象
* @param res - Express响应对象
*/
async testEmail(req: Request, res: Response) {
try {
const { to } = req.body;
if (!to || !this.isValidEmail(to)) {
return res.status(400).json({
success: false,
message: '请输入有效的邮箱地址'
});
}
const configRepository = AppDataSource.getRepository(Config);
const mailConfigs = await configRepository.find({
where: [
{ configKey: 'mail_from' },
{ configKey: 'mail_smtp_host' },
{ configKey: 'mail_smtp_port' },
{ configKey: 'mail_smtp_user' },
{ configKey: 'mail_smtp_password' }
]
});
const configMap = new Map(mailConfigs.map(c => [c.configKey, c.configValue]));
const mailFrom = configMap.get('mail_from');
const smtpHost = configMap.get('mail_smtp_host');
const smtpPort = configMap.get('mail_smtp_port');
const smtpUser = configMap.get('mail_smtp_user');
const smtpPassword = configMap.get('mail_smtp_password');
if (!mailFrom || !smtpHost || !smtpPort || !smtpUser || !smtpPassword) {
return res.status(400).json({
success: false,
message: '邮件配置不完整,请先配置邮件信息'
});
}
const transporter = nodemailer.createTransport({
host: smtpHost,
port: Number(smtpPort),
secure: Number(smtpPort) === 465,
auth: {
user: smtpUser,
pass: smtpPassword
}
});
const mailOptions = {
from: mailFrom,
to: to,
subject: '梦幻西游运营管理系统 - 邮件测试',
text: '这是一封测试邮件,如果您收到此邮件,说明邮件配置正确。'
};
await transporter.sendMail(mailOptions);
return res.json({
success: true,
message: '邮件发送成功'
});
} catch (error) {
console.error('测试邮件发送失败:', error);
return res.status(500).json({
success: false,
message: '邮件发送失败,请检查配置'
});
}
}
/**
* 将配置键映射到.env文件中的环境变量键
* @param configKey - 配置键
* @returns 环境变量键如果不映射则返回null
*/
private mapConfigKeyToEnvKey(configKey: string): string | null {
const mapping: Record<string, string> = {
'backend_host': 'BACKEND_HOST',
'backend_port': 'PORT',
'log_level': 'LOG_LEVEL',
'cors_origin': 'CORS_ORIGIN',
'jwt_secret': 'JWT_SECRET',
'jwt_expires_in': 'JWT_EXPIRES_IN',
'game_server_proxy_url': 'GAME_SERVER_PROXY_URL',
'game_server_psk': 'GAME_PSK'
};
return mapping[configKey] || null;
}
/**
* 验证邮箱格式
* @param email - 邮箱地址
* @returns 是否有效
*/
private isValidEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
/**
* 检查玩家服务中心状态
* @param req - Express请求对象
* @param res - Express响应对象
*/
async checkPlayerServiceStatus(req: Request, res: Response) {
try {
const configRepository = AppDataSource.getRepository(Config);
const playerServiceEnabledConfig = await configRepository.findOne({
where: { configKey: 'player_service_enabled' }
});
const playerServiceCloseMsgConfig = await configRepository.findOne({
where: { configKey: 'player_service_close_msg' }
});
const enabled = playerServiceEnabledConfig?.configValue === 'true';
const closeMsg = playerServiceCloseMsgConfig?.configValue || '玩家服务中心系统维护中';
return res.json({
success: true,
data: {
enabled,
closeMsg
}
});
} catch (error) {
console.error('检查玩家服务中心状态失败:', error);
return res.status(500).json({
success: false,
message: '服务器内部错误'
});
}
}
}