|
|
|
@ -1,25 +1,22 @@
|
|
|
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
|
|
import React, { useCallback, useState, useEffect } from 'react';
|
|
|
|
import { Select } from '@arco-design/web-react';
|
|
|
|
import { Select } from '@arco-design/web-react';
|
|
|
|
import CodeMirror from '@uiw/react-codemirror';
|
|
|
|
import CodeMirror from '@uiw/react-codemirror';
|
|
|
|
import { java } from '@codemirror/lang-java';
|
|
|
|
import { java } from '@codemirror/lang-java';
|
|
|
|
import { python } from '@codemirror/lang-python';
|
|
|
|
import { python } from '@codemirror/lang-python';
|
|
|
|
import { githubLight } from '@uiw/codemirror-theme-github';
|
|
|
|
import { githubLight } from '@uiw/codemirror-theme-github';
|
|
|
|
|
|
|
|
import { isJSON } from '@/utils/common';
|
|
|
|
|
|
|
|
|
|
|
|
const Option = Select.Option;
|
|
|
|
const Option = Select.Option;
|
|
|
|
|
|
|
|
|
|
|
|
interface TableDataItem {
|
|
|
|
interface initData {
|
|
|
|
key: number | string;
|
|
|
|
customDef?: string | Record<string, string>;
|
|
|
|
id: string;
|
|
|
|
type: string;
|
|
|
|
dataType: string;
|
|
|
|
|
|
|
|
arrayType: string;
|
|
|
|
|
|
|
|
desc: string;
|
|
|
|
|
|
|
|
defaultValue: string;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[key: string]: any; // 允许其他自定义字段
|
|
|
|
[key: string]: any; // 允许其他自定义字段
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
interface CodeMirrorProps {
|
|
|
|
interface CodeMirrorProps {
|
|
|
|
initialData: TableDataItem[],
|
|
|
|
initialData: initData,
|
|
|
|
onUpdateData: (data) => void,
|
|
|
|
onUpdateData: (data) => void,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -45,40 +42,82 @@ const nameToCode = {
|
|
|
|
'java': '63',
|
|
|
|
'java': '63',
|
|
|
|
'python': '70'
|
|
|
|
'python': '70'
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const codeToName = {
|
|
|
|
|
|
|
|
'63': 'java',
|
|
|
|
|
|
|
|
'70': 'python'
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CodeMirrorComp: React.FC<CodeMirrorProps> = ({
|
|
|
|
const CodeMirrorComp: React.FC<CodeMirrorProps> = ({
|
|
|
|
initialData,
|
|
|
|
initialData,
|
|
|
|
onUpdateData
|
|
|
|
onUpdateData
|
|
|
|
}) => {
|
|
|
|
}) => {
|
|
|
|
const [value, setValue] = useState('console.log(\'hello world!\');');
|
|
|
|
|
|
|
|
const [language, setLanguage] = useState('java');
|
|
|
|
const [language, setLanguage] = useState('java');
|
|
|
|
|
|
|
|
const [codeMap, setCodeMap] = useState<Record<string, string>>({
|
|
|
|
|
|
|
|
java: defaultCode.java,
|
|
|
|
|
|
|
|
python: defaultCode.python
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onChange = useCallback((val) => {
|
|
|
|
|
|
|
|
// 更新当前语言的代码
|
|
|
|
|
|
|
|
const newCodeMap = {
|
|
|
|
|
|
|
|
...codeMap,
|
|
|
|
|
|
|
|
[language]: val
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
setCodeMap(newCodeMap);
|
|
|
|
|
|
|
|
|
|
|
|
const onChange = useCallback((val, viewUpdate) => {
|
|
|
|
|
|
|
|
setValue(val);
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
const data = {
|
|
|
|
customDef: {
|
|
|
|
customDef: {
|
|
|
|
languageId: nameToCode[language],
|
|
|
|
languageId: nameToCode[language],
|
|
|
|
sourceCode: val
|
|
|
|
sourceCode: val
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
extra: newCodeMap, // 前端存储所有语言的代码
|
|
|
|
|
|
|
|
type: 'CODE'
|
|
|
|
};
|
|
|
|
};
|
|
|
|
console.log('data:', data);
|
|
|
|
|
|
|
|
onUpdateData(data);
|
|
|
|
onUpdateData(data);
|
|
|
|
}, []);
|
|
|
|
}, [language, codeMap, onUpdateData]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleLanguageChange = useCallback((newLanguage: string) => {
|
|
|
|
|
|
|
|
setLanguage(newLanguage);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 切换语言时也要更新数据
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
|
|
|
customDef: {
|
|
|
|
|
|
|
|
languageId: nameToCode[newLanguage],
|
|
|
|
|
|
|
|
sourceCode: codeMap[newLanguage]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
extra: codeMap, // 前端存储所有语言的代码
|
|
|
|
|
|
|
|
type: 'CODE'
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
onUpdateData(data);
|
|
|
|
|
|
|
|
}, [codeMap, onUpdateData]);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
useEffect(() => {
|
|
|
|
setValue(defaultCode[language]);
|
|
|
|
const parseData = isJSON(initialData.customDef) ? JSON.parse(initialData.customDef as string) : initialData.customDef;
|
|
|
|
|
|
|
|
const currentLanguage = codeToName[parseData?.languageId] || 'java';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有 extra,优先使用它来恢复所有语言的代码
|
|
|
|
|
|
|
|
if (initialData.extra && typeof initialData.extra === 'object') {
|
|
|
|
|
|
|
|
setCodeMap(initialData.extra as Record<string, string>);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (parseData?.sourceCode) {
|
|
|
|
|
|
|
|
// 否则只恢复当前语言的代码
|
|
|
|
|
|
|
|
setCodeMap(prev => ({
|
|
|
|
|
|
|
|
...prev,
|
|
|
|
|
|
|
|
[currentLanguage]: parseData.sourceCode
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setLanguage(currentLanguage);
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<>
|
|
|
|
<Select
|
|
|
|
<Select
|
|
|
|
defaultValue={'java'}
|
|
|
|
value={language}
|
|
|
|
placeholder="请选择语言"
|
|
|
|
placeholder="请选择语言"
|
|
|
|
style={{ width: 154 }}
|
|
|
|
style={{ width: 154 }}
|
|
|
|
onChange={(value) => {
|
|
|
|
onChange={handleLanguageChange}
|
|
|
|
setLanguage(value);
|
|
|
|
|
|
|
|
setValue(defaultCode[value]);
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{options.map((option, index) => (
|
|
|
|
{options.map((option, index) => (
|
|
|
|
<Option key={option} disabled={index === 3} value={option}>
|
|
|
|
<Option key={option} disabled={index === 3} value={option}>
|
|
|
|
@ -87,7 +126,7 @@ const CodeMirrorComp: React.FC<CodeMirrorProps> = ({
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</Select>
|
|
|
|
</Select>
|
|
|
|
<CodeMirror
|
|
|
|
<CodeMirror
|
|
|
|
value={value}
|
|
|
|
value={codeMap[language]}
|
|
|
|
height="300px"
|
|
|
|
height="300px"
|
|
|
|
extensions={extensions}
|
|
|
|
extensions={extensions}
|
|
|
|
onChange={onChange} />
|
|
|
|
onChange={onChange} />
|
|
|
|
|