Files
2025-03-28 14:45:54 +08:00

128 lines
3.2 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
interface CodeEditorProps {
id: string;
initialValue?: string;
language?: 'javascript' | 'python';
onChange?: (value: string) => void;
}
export function CodeEditor({
id,
initialValue = '',
language = 'javascript',
onChange
}: CodeEditorProps) {
const [code, setCode] = useState(initialValue);
const [copySuccess, setCopySuccess] = useState(false);
// 当语言变化时更新编辑器
const extensions = [language === 'javascript' ? javascript() : javascript()];
// 处理代码变化
const handleChange = (value: string) => {
setCode(value);
if (onChange) {
onChange(value);
}
};
// 复制代码到剪贴板
const copyToClipboard = () => {
navigator.clipboard.writeText(code).then(() => {
setCopySuccess(true);
setTimeout(() => setCopySuccess(false), 2000);
});
};
// 初始示例代码
const getDefaultCode = (lang: string) => {
if (lang === 'javascript') {
return `// 示例代码
function checkRule(data) {
// data 包含抽取的字段
try {
// 在此编写检查逻辑
if (data.fieldName && condition) {
return {
pass: true,
message: "检查通过"
};
} else {
return {
pass: false,
message: "检查不通过,原因:..."
};
}
} catch (error) {
return {
pass: false,
message: "执行出错:" + error.message
};
}
}`;
} else {
return `# 示例代码
def check_rule(data):
# data 包含抽取的字段
try:
# 在此编写检查逻辑
if 'field_name' in data and condition:
return {
'pass': True,
'message': "检查通过"
}
else:
return {
'pass': False,
'message': "检查不通过,原因:..."
}
except Exception as error:
return {
'pass': False,
'message': f"执行出错:{str(error)}"
}`;
}
};
// 如果初始值为空,则使用默认示例代码
useEffect(() => {
if (!initialValue) {
setCode(getDefaultCode(language));
}
}, [language, initialValue]);
return (
<div>
<div className="code-editor-wrapper">
<div className="code-editor-header">
<div className="code-editor-filename">{language === 'javascript' ? 'script.js' : 'script.py'}</div>
<div className="code-editor-actions">
<i
className="ri-file-copy-line"
title="复制代码"
onClick={copyToClipboard}
></i>
</div>
</div>
<CodeMirror
id={id}
value={code}
height="400px"
theme={oneDark}
extensions={extensions}
onChange={handleChange}
style={{ fontSize: '14px' }}
/>
</div>
{copySuccess && (
<div className="code-copy-success show">
</div>
)}
</div>
);
}