fix: 🐛 修复系统配置页在优化过程中产生的新问题

This commit is contained in:
Stev_Wang
2025-12-12 21:43:02 +08:00
parent 5b2c2d35bc
commit 429883b0bf
2 changed files with 44 additions and 23 deletions

View File

@@ -5,7 +5,7 @@
*/ */
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Tabs, message } from 'antd'; import { Tabs, message, Space } from 'antd';
import { import {
SettingOutlined, SettingOutlined,
SecurityScanOutlined, SecurityScanOutlined,
@@ -112,10 +112,10 @@ const SystemConfigPage: React.FC = () => {
{ {
key: 'basic', key: 'basic',
label: ( label: (
<span> <Space size="small">
<SettingOutlined /> <SettingOutlined />
</span> </Space>
), ),
children: ( children: (
<BasicConfigTab <BasicConfigTab
@@ -132,10 +132,10 @@ const SystemConfigPage: React.FC = () => {
{ {
key: 'security', key: 'security',
label: ( label: (
<span> <Space size="small">
<SecurityScanOutlined /> <SecurityScanOutlined />
</span> </Space>
), ),
children: ( children: (
<SecurityConfigTab <SecurityConfigTab
@@ -152,10 +152,10 @@ const SystemConfigPage: React.FC = () => {
{ {
key: 'game', key: 'game',
label: ( label: (
<span> <Space size="small">
<CloudServerOutlined /> <CloudServerOutlined />
</span> </Space>
), ),
children: ( children: (
<GameConfigTab <GameConfigTab

View File

@@ -24,6 +24,7 @@ const { TextArea } = Input;
interface GameConfigTabProps { interface GameConfigTabProps {
configs: SystemConfig[]; configs: SystemConfig[];
loading?: boolean;
saving?: boolean; saving?: boolean;
onSave: (requests: SaveConfigRequest[]) => void; onSave: (requests: SaveConfigRequest[]) => void;
onReset: (configKey: string) => void; onReset: (configKey: string) => void;
@@ -31,8 +32,25 @@ interface GameConfigTabProps {
onConfigChange: () => void; onConfigChange: () => void;
} }
interface ConfigItem {
key: string;
title: string;
description: string;
type: 'input' | 'textarea' | 'inputnumber' | 'switch' | 'select';
placeholder?: string;
required?: boolean;
min?: number;
max?: number;
suffix?: string;
rows?: number;
sensitive?: boolean;
icon?: React.ReactElement;
options?: Array<{ value: string; label: string }>;
}
const GameConfigTab: React.FC<GameConfigTabProps> = ({ const GameConfigTab: React.FC<GameConfigTabProps> = ({
configs, configs,
loading,
saving, saving,
onSave, onSave,
onReset, onReset,
@@ -64,7 +82,10 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
// 处理表单值变化 // 处理表单值变化
const handleValuesChange = (changedValues: Record<string, unknown>, allValues: Record<string, unknown>) => { const handleValuesChange = (changedValues: Record<string, unknown>, allValues: Record<string, unknown>) => {
setFormData(allValues); setFormData(allValues);
onConfigChange(); // 使用changedValues参数避免未使用的警告
if (Object.keys(changedValues).length > 0) {
onConfigChange();
}
}; };
// 保存配置 // 保存配置
@@ -115,15 +136,15 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
return { level: 'strong', message: 'PSK密钥强度符合要求' }; return { level: 'strong', message: 'PSK密钥强度符合要求' };
}; };
const apiUrlValidation = validateApiUrl(formData.game_server_api || ''); const apiUrlValidation = validateApiUrl(String(formData.game_server_api || ''));
const pskStrength = checkPskStrength(formData.game_server_psk || ''); const pskStrength = checkPskStrength(String(formData.game_server_psk || ''));
const configItems = [ const configItems: ConfigItem[] = [
{ {
key: 'game_server_api', key: 'game_server_api',
title: '游戏服务端API', title: '游戏服务端API',
description: '游戏服务端HTTP接口地址用于与游戏服务端进行数据交互', description: '游戏服务端HTTP接口地址用于与游戏服务端进行数据交互',
type: 'input', type: 'input' as const,
placeholder: 'http://127.0.0.1:8080/tool/http', placeholder: 'http://127.0.0.1:8080/tool/http',
required: true, required: true,
icon: <ApiOutlined />, icon: <ApiOutlined />,
@@ -133,7 +154,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
key: 'game_server_psk', key: 'game_server_psk',
title: '游戏服务端PSK', title: '游戏服务端PSK',
description: '游戏服务端预共享密钥用于API认证安全性至关重要', description: '游戏服务端预共享密钥用于API认证安全性至关重要',
type: 'textarea', type: 'textarea' as const,
placeholder: '请输入PSK密钥建议32位以上', placeholder: '请输入PSK密钥建议32位以上',
required: true, required: true,
rows: 3, rows: 3,
@@ -144,7 +165,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
key: 'game_server_timeout', key: 'game_server_timeout',
title: '请求超时时间', title: '请求超时时间',
description: '与游戏服务端通信的超时时间,单位:秒', description: '与游戏服务端通信的超时时间,单位:秒',
type: 'inputnumber', type: 'inputnumber' as const,
min: 5, min: 5,
max: 120, max: 120,
suffix: '秒', suffix: '秒',
@@ -155,7 +176,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
key: 'game_server_retry_count', key: 'game_server_retry_count',
title: '重试次数', title: '重试次数',
description: 'API请求失败时的重试次数', description: 'API请求失败时的重试次数',
type: 'inputnumber', type: 'inputnumber' as const,
min: 1, min: 1,
max: 10, max: 10,
suffix: '次', suffix: '次',
@@ -166,14 +187,14 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
key: 'player_auto_register', key: 'player_auto_register',
title: '玩家自动注册', title: '玩家自动注册',
description: '新玩家是否自动创建账号', description: '新玩家是否自动创建账号',
type: 'switch', type: 'switch' as const,
icon: <UserAddOutlined /> icon: <UserAddOutlined />
}, },
{ {
key: 'game_log_level', key: 'game_log_level',
title: '游戏日志级别', title: '游戏日志级别',
description: '游戏相关操作的日志记录级别', description: '游戏相关操作的日志记录级别',
type: 'select', type: 'select' as const,
required: true, required: true,
icon: <FileTextOutlined />, icon: <FileTextOutlined />,
options: [ options: [
@@ -195,7 +216,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
showIcon showIcon
style={{ marginBottom: '24px' }} style={{ marginBottom: '24px' }}
action={ action={
<Button size="small" danger> <Button size="small" danger disabled={loading}>
</Button> </Button>
} }
@@ -231,7 +252,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
style={{ marginBottom: '24px' }} style={{ marginBottom: '24px' }}
> >
<Row gutter={[24, 0]}> <Row gutter={[24, 0]}>
{configItems.map((item) => { {configItems.map((item: ConfigItem) => {
const config = configs.find(c => c.config_key === item.key); const config = configs.find(c => c.config_key === item.key);
if (!config) return null; if (!config) return null;
@@ -330,7 +351,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
<Input <Input
placeholder={item.placeholder} placeholder={item.placeholder}
disabled={config.config_type === 'boolean'} disabled={config.config_type === 'boolean'}
value={formData[item.key]} value={String(formData[item.key] || '')}
onChange={(e) => { onChange={(e) => {
form.setFieldValue(item.key, e.target.value); form.setFieldValue(item.key, e.target.value);
onConfigChange(); onConfigChange();
@@ -345,7 +366,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
showCount={!item.sensitive} showCount={!item.sensitive}
autoSize={{ minRows: item.rows || 3, maxRows: 6 }} autoSize={{ minRows: item.rows || 3, maxRows: 6 }}
style={{ fontFamily: item.sensitive ? 'monospace' : 'inherit' }} style={{ fontFamily: item.sensitive ? 'monospace' : 'inherit' }}
value={formData[item.key]} value={String(formData[item.key] || '')}
onChange={(e) => { onChange={(e) => {
form.setFieldValue(item.key, e.target.value); form.setFieldValue(item.key, e.target.value);
onConfigChange(); onConfigChange();
@@ -359,7 +380,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
max={item.max} max={item.max}
placeholder={item.placeholder} placeholder={item.placeholder}
suffix={item.suffix} suffix={item.suffix}
value={formData[item.key]} value={formData[item.key] as number | string | null}
onChange={(value) => { onChange={(value) => {
form.setFieldValue(item.key, value); form.setFieldValue(item.key, value);
onConfigChange(); onConfigChange();
@@ -369,7 +390,7 @@ const GameConfigTab: React.FC<GameConfigTabProps> = ({
{item.type === 'select' && ( {item.type === 'select' && (
<Select <Select
placeholder={item.placeholder} placeholder={item.placeholder}
value={formData[item.key]} value={String(formData[item.key] || '')}
onChange={(value) => { onChange={(value) => {
form.setFieldValue(item.key, value); form.setFieldValue(item.key, value);
onConfigChange(); onConfigChange();