fix: 🐛 修复系统配置页在优化过程中产生的新问题
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user