Files
MYXY_Web/src/services/systemConfigService.ts
2025-12-12 20:01:39 +08:00

230 lines
10 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.
/**
* 系统配置API服务
* @author MHXY Development Team
* @version 1.0.0
*/
import {
SystemConfig,
SaveConfigRequest
} from '../types/systemConfig';
const API_BASE_URL = '/api/system-config';
class SystemConfigService {
/**
* 获取所有系统配置
*/
async getAllConfigs(): Promise<SystemConfig[]> {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 300));
// 返回模拟数据
return [
// 基本配置
{ id: 1, config_key: 'site_name', config_value: '梦幻西游一站式运营管理系统', config_type: 'string', config_group: 'basic', config_label: '网站名称', config_description: '系统显示名称', sort_order: 1 },
{ id: 2, config_key: 'site_version', config_value: '1.0.0', config_type: 'string', config_group: 'basic', config_label: '系统版本', config_description: '当前系统版本号', sort_order: 2 },
{ id: 3, config_key: 'site_description', config_value: '专业的游戏运营管理平台', config_type: 'string', config_group: 'basic', config_label: '系统描述', config_description: '系统描述信息', sort_order: 3 },
{ id: 4, config_key: 'admin_email', config_value: 'admin@mhxy.com', config_type: 'string', config_group: 'basic', config_label: '管理员邮箱', config_description: '系统管理员联系邮箱', sort_order: 4 },
{ id: 5, config_key: 'maintenance_mode', config_value: '0', config_type: 'boolean', config_group: 'basic', config_label: '维护模式', config_description: '开启后用户无法正常访问系统', sort_order: 5 },
{ id: 6, config_key: 'default_language', config_value: 'zh-CN', config_type: 'string', config_group: 'basic', config_label: '默认语言', config_description: '系统默认语言设置', sort_order: 6 },
// 安全配置
{ id: 7, config_key: 'jwt_secret', config_value: 'JWT_SECRET_32_BYTE_RANDOM_STRING_2025', config_type: 'string', config_group: 'security', config_label: 'JWT密钥', config_description: '用于JWT令牌签名的密钥建议32位字符', sort_order: 1 },
{ id: 8, config_key: 'jwt_expires_in', config_value: '24', config_type: 'number', config_group: 'security', config_label: 'JWT过期时间(小时)', config_description: 'JWT访问令牌的有效期单位小时', sort_order: 2 },
{ id: 9, config_key: 'jwt_refresh_expires_in', config_value: '168', config_type: 'number', config_group: 'security', config_label: 'JWT刷新令牌过期时间(小时)', config_description: 'JWT刷新令牌的有效期单位小时', sort_order: 3 },
{ id: 10, config_key: 'login_attempt_limit', config_value: '5', config_type: 'number', config_group: 'security', config_label: '登录尝试次数限制', config_description: '连续登录失败次数限制', sort_order: 4 },
{ id: 11, config_key: 'session_timeout', config_value: '30', config_type: 'number', config_group: 'security', config_label: '会话超时时间(分钟)', config_description: '用户会话超时时间', sort_order: 5 },
{ id: 12, config_key: 'password_min_length', config_value: '6', config_type: 'number', config_group: 'security', config_label: '密码最小长度', config_description: '用户密码最小长度要求', sort_order: 6 },
{ id: 13, config_key: 'enable_2fa', config_value: '0', config_type: 'boolean', config_group: 'security', config_label: '启用双因子认证', config_description: '是否启用双因子认证功能', sort_order: 7 },
// 游戏通信配置
{ id: 14, config_key: 'game_server_api', config_value: 'http://127.0.0.1:8080/tool/http', config_type: 'string', config_group: 'game', config_label: '游戏服务端API', config_description: '游戏服务端HTTP接口地址', sort_order: 1 },
{ id: 15, config_key: 'game_server_psk', config_value: 'THIS_IS_A_32_BYTE_FIXED_PSK!!!!!', config_type: 'string', config_group: 'game', config_label: '游戏服务端PSK', config_description: '游戏服务端预共享密钥用于API认证', sort_order: 2 },
{ id: 16, config_key: 'game_server_timeout', config_value: '30', config_type: 'number', config_group: 'game', config_label: '请求超时时间(秒)', config_description: '与游戏服务端通信的超时时间', sort_order: 3 },
{ id: 17, config_key: 'game_server_retry_count', config_value: '3', config_type: 'number', config_group: 'game', config_label: '重试次数', config_description: 'API请求失败时的重试次数', sort_order: 4 },
{ id: 18, config_key: 'player_auto_register', config_value: '1', config_type: 'boolean', config_group: 'game', config_label: '玩家自动注册', config_description: '新玩家是否自动创建账号', sort_order: 5 },
{ id: 19, config_key: 'game_log_level', config_value: 'info', config_type: 'string', config_group: 'game', config_label: '游戏日志级别', config_description: '游戏相关操作的日志记录级别', sort_order: 6 }
];
}
/**
* 按分组获取配置
*/
async getConfigsByGroup(group: string): Promise<SystemConfig[]> {
const allConfigs = await this.getAllConfigs();
return allConfigs.filter(config => config.config_group === group);
}
/**
* 保存单个配置项
*/
async saveConfig(request: SaveConfigRequest): Promise<{ success: boolean; message: string }> {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 500));
// 模拟验证逻辑
if (!request.config_key || !request.config_value) {
throw new Error('配置键名和值不能为空');
}
// 特殊验证
if (request.config_key === 'jwt_secret' && request.config_value.length < 32) {
throw new Error('JWT密钥至少需要32位字符');
}
if (request.config_key === 'game_server_api' && !/^https?:\/\/.+/.test(request.config_value)) {
throw new Error('游戏服务端API必须是有效的HTTP/HTTPS地址');
}
return {
success: true,
message: '配置保存成功'
};
}
/**
* 批量保存配置
*/
async saveConfigs(requests: SaveConfigRequest[]): Promise<{ success: boolean; message: string; errors?: string[] }> {
const errors: string[] = [];
for (const request of requests) {
try {
await this.saveConfig(request);
} catch (error) {
errors.push(`${request.config_key}: ${error instanceof Error ? error.message : '未知错误'}`);
}
}
return {
success: errors.length === 0,
message: errors.length === 0 ? '所有配置保存成功' : '部分配置保存失败',
errors: errors.length > 0 ? errors : undefined
};
}
/**
* 获取配置历史记录
*/
async getConfigHistory(configKey?: string, limit: number = 50): Promise<any[]> {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 300));
const mockHistory: any[] = [
{
id: 1,
config_key: 'jwt_secret',
old_value: 'OLD_JWT_SECRET_32_BYTE_STRING_2024',
new_value: 'JWT_SECRET_32_BYTE_RANDOM_STRING_2025',
changed_by: 1,
changed_reason: '更新JWT密钥以提升安全性',
created_at: '2025-12-12T10:30:00.000Z',
admin_user: {
username: 'admin',
real_name: '系统管理员'
}
},
{
id: 2,
config_key: 'game_server_api',
old_value: 'http://192.168.1.100:8080/tool/http',
new_value: 'http://127.0.0.1:8080/tool/http',
changed_by: 1,
changed_reason: '更新为本地开发环境地址',
created_at: '2025-12-12T09:15:00.000Z',
admin_user: {
username: 'admin',
real_name: '系统管理员'
}
}
];
return configKey
? mockHistory.filter(item => item.config_key === configKey)
: mockHistory;
}
/**
* 同步配置到.env文件
*/
async syncToEnvFile(configs: EnvConfig): Promise<{ success: boolean; message: string }> {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 1000));
// 模拟文件写入操作
console.log('同步配置到.env文件:', configs);
return {
success: true,
message: '配置已成功同步到.env文件'
};
}
/**
* 重置指定配置项为默认值
*/
async resetConfig(configKey: string): Promise<{ success: boolean; message: string; defaultValue?: string }> {
// 模拟API调用
await new Promise(resolve => setTimeout(resolve, 300));
const defaultValues: Record<string, string> = {
'jwt_secret': 'JWT_SECRET_32_BYTE_RANDOM_STRING_2025',
'game_server_api': 'http://127.0.0.1:8080/tool/http',
'game_server_psk': 'THIS_IS_A_32_BYTE_FIXED_PSK!!!!!',
'jwt_expires_in': '24',
'login_attempt_limit': '5',
'session_timeout': '30'
};
const defaultValue = defaultValues[configKey];
if (!defaultValue) {
throw new Error('未找到该配置项的默认值');
}
return {
success: true,
message: '配置已重置为默认值',
defaultValue
};
}
/**
* 验证配置值
*/
validateConfigValue(configKey: string, value: any): { valid: boolean; error?: string } {
switch (configKey) {
case 'jwt_secret':
if (typeof value !== 'string' || value.length < 32) {
return { valid: false, error: 'JWT密钥至少需要32位字符' };
}
break;
case 'game_server_api':
if (!/^https?:\/\/.+/.test(value)) {
return { valid: false, error: '请输入有效的HTTP/HTTPS地址' };
}
break;
case 'game_server_psk':
if (typeof value !== 'string' || value.length < 32) {
return { valid: false, error: 'PSK密钥至少需要32位字符' };
}
break;
case 'jwt_expires_in':
case 'login_attempt_limit':
case 'session_timeout':
const num = Number(value);
if (isNaN(num) || num <= 0) {
return { valid: false, error: '请输入有效的正整数' };
}
break;
}
return { valid: true };
}
}
export const systemConfigService = new SystemConfigService();
export default systemConfigService;