|
|
@@ -0,0 +1,212 @@
|
|
|
+import React, { useEffect, useState } from 'react';
|
|
|
+import { CheckCircleOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
|
|
+import { SPACING } from '../../constants';
|
|
|
+import Space from 'antd/es/space';
|
|
|
+import Card from 'antd/es/card';
|
|
|
+import Typography from 'antd/es/typography';
|
|
|
+import { Button, message, Spin } from 'antd';
|
|
|
+import { useIntl } from 'react-intl';
|
|
|
+import { getConfig, modifyConfig } from '@/API/system/options';
|
|
|
+import { theme } from 'antd';
|
|
|
+
|
|
|
+interface SystemModeOption {
|
|
|
+ label: string;
|
|
|
+ value: string;
|
|
|
+ SimulatorGEN: number;
|
|
|
+ SimulatorFPD: number;
|
|
|
+ desc: string;
|
|
|
+}
|
|
|
+
|
|
|
+const SYSTEM_MODE_OPTIONS: SystemModeOption[] = [
|
|
|
+ {
|
|
|
+ label: '演示模式',
|
|
|
+ value: 'S',
|
|
|
+ SimulatorGEN: 1,
|
|
|
+ SimulatorFPD: 1,
|
|
|
+ desc: '发生器、FPD均为虚拟',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '真机模式(发生器受控)',
|
|
|
+ value: 'R',
|
|
|
+ SimulatorGEN: 0,
|
|
|
+ SimulatorFPD: 0,
|
|
|
+ desc: '发生器、FPD均为真实硬件',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '真机模式(发生器不受控)',
|
|
|
+ value: 'R-S',
|
|
|
+ SimulatorGEN: 1,
|
|
|
+ SimulatorFPD: 0,
|
|
|
+ desc: 'FPD真实、发生器虚拟',
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+export const SystemMode: React.FC = () => {
|
|
|
+ const { Text } = Typography;
|
|
|
+ const intl = useIntl();
|
|
|
+ const [selectedMode, setSelectedMode] = useState<string>('');
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
+ const [saving, setSaving] = useState(false);
|
|
|
+
|
|
|
+ const { useToken } = theme;
|
|
|
+ const colorPrimary = useToken().token.colorPrimary;
|
|
|
+ useEffect(() => {
|
|
|
+ loadCurrentMode();
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ const loadCurrentMode = async () => {
|
|
|
+ setLoading(true);
|
|
|
+ try {
|
|
|
+ const response = await getConfig({
|
|
|
+ uri: ['System/SimulatorGEN', 'System/SimulatorFPD'],
|
|
|
+ });
|
|
|
+
|
|
|
+ const configs = response.data.configs;
|
|
|
+ const SimulatorGEN = parseInt(
|
|
|
+ configs.find((c) => c.config_key === 'SimulatorGEN')?.config_value ||
|
|
|
+ '0'
|
|
|
+ );
|
|
|
+ const SimulatorFPD = parseInt(
|
|
|
+ configs.find((c) => c.config_key === 'SimulatorFPD')?.config_value ||
|
|
|
+ '0'
|
|
|
+ );
|
|
|
+
|
|
|
+ // 根据当前值确定模式
|
|
|
+ const currentMode = SYSTEM_MODE_OPTIONS.find(
|
|
|
+ (option) =>
|
|
|
+ option.SimulatorGEN === SimulatorGEN &&
|
|
|
+ option.SimulatorFPD === SimulatorFPD
|
|
|
+ );
|
|
|
+
|
|
|
+ if (currentMode) {
|
|
|
+ setSelectedMode(currentMode.value);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载系统模式失败:', error);
|
|
|
+ message.error(intl.formatMessage({ id: 'systemMode.loadFailed' }));
|
|
|
+ } finally {
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const saveSystemMode = async () => {
|
|
|
+ const selectedOption = SYSTEM_MODE_OPTIONS.find(
|
|
|
+ (option) => option.value === selectedMode
|
|
|
+ );
|
|
|
+ if (!selectedOption) {
|
|
|
+ message.error(intl.formatMessage({ id: 'systemMode.selectRequired' }));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ setSaving(true);
|
|
|
+ try {
|
|
|
+ await modifyConfig({
|
|
|
+ 'System/SimulatorGEN': selectedOption.SimulatorGEN,
|
|
|
+ 'System/SimulatorFPD': selectedOption.SimulatorFPD,
|
|
|
+ });
|
|
|
+
|
|
|
+ message.success(intl.formatMessage({ id: 'systemMode.saveSuccess' }));
|
|
|
+ } catch (error) {
|
|
|
+ console.error('保存系统模式失败:', error);
|
|
|
+ message.error(intl.formatMessage({ id: 'systemMode.saveFailed' }));
|
|
|
+ } finally {
|
|
|
+ setSaving(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const radioOptions = SYSTEM_MODE_OPTIONS.map((option) => ({
|
|
|
+ ...option,
|
|
|
+ label: intl.formatMessage({ id: `systemMode.${option.value}` }),
|
|
|
+ desc: intl.formatMessage({ id: `systemMode.${option.value}.desc` }),
|
|
|
+ }));
|
|
|
+
|
|
|
+ const handleModeSelect = (modeValue: string) => {
|
|
|
+ setSelectedMode(modeValue);
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div style={{ padding: SPACING.LG }}>
|
|
|
+ <Space direction="vertical" style={{ display: 'flex', width: '100%' }}>
|
|
|
+ <Text strong style={{ fontSize: '16px' }}>
|
|
|
+ {intl.formatMessage({ id: 'systemMode.title' })}
|
|
|
+ </Text>
|
|
|
+
|
|
|
+ {loading ? (
|
|
|
+ <div style={{ textAlign: 'center', padding: '20px' }}>
|
|
|
+ <Spin />
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>
|
|
|
+ {radioOptions.map((option) => (
|
|
|
+ <Card
|
|
|
+ key={option.value}
|
|
|
+ hoverable
|
|
|
+ style={{
|
|
|
+ flex: '1',
|
|
|
+ minWidth: '200px',
|
|
|
+ cursor: 'pointer',
|
|
|
+ borderColor:
|
|
|
+ selectedMode === option.value ? colorPrimary : 'inherit',
|
|
|
+ borderWidth: '2px',
|
|
|
+ // border: `2px solid ${
|
|
|
+ // selectedMode === option.value ? colorPrimary
|
|
|
+ // }`,
|
|
|
+
|
|
|
+ transition: 'all 0.2s ease',
|
|
|
+ position: 'relative',
|
|
|
+ }}
|
|
|
+ onClick={() => handleModeSelect(option.value)}
|
|
|
+ styles={{
|
|
|
+ body: { padding: '16px' },
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
|
|
|
+ >
|
|
|
+ <div style={{ flex: 1 }}>
|
|
|
+ <Text
|
|
|
+ strong
|
|
|
+ style={{
|
|
|
+ display: 'block',
|
|
|
+ marginBottom: '4px',
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {option.label}
|
|
|
+ </Text>
|
|
|
+ <Text type="secondary" style={{ fontSize: '12px' }}>
|
|
|
+ {option.desc}
|
|
|
+ </Text>
|
|
|
+ </div>
|
|
|
+ {selectedMode === option.value && (
|
|
|
+ <CheckCircleOutlined
|
|
|
+ style={{
|
|
|
+ color: colorPrimary,
|
|
|
+ fontSize: '20px',
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </Card>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <Text type="secondary" style={{ marginTop: '16px' }}>
|
|
|
+ <InfoCircleOutlined style={{ marginRight: 6 }} />
|
|
|
+ {intl.formatMessage({ id: 'systemMode.hint' })}
|
|
|
+ </Text>
|
|
|
+
|
|
|
+ <div style={{ marginTop: '16px' }}>
|
|
|
+ <Button
|
|
|
+ type="primary"
|
|
|
+ onClick={saveSystemMode}
|
|
|
+ loading={saving}
|
|
|
+ disabled={!selectedMode}
|
|
|
+ >
|
|
|
+ {intl.formatMessage({ id: 'systemMode.save' })}
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </Space>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|