feat: 代码节点验证
This commit is contained in:
parent
8311f2a6c5
commit
58a07f310a
@ -41,7 +41,7 @@
|
||||
@zoom="zoom"
|
||||
@setNodeName="setNodeName"
|
||||
/>
|
||||
<div class="input__container" v-show="nodeZoom">
|
||||
<div class="input__container" v-show="nodeZoom" @mousedown="(e) => e.stopPropagation()" @keydown="handleInputKeydown">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<div class="tag"></div>
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
@zoom="zoom"
|
||||
@setNodeName="setNodeName"
|
||||
/>
|
||||
<div class="input__container" v-show="nodeZoom">
|
||||
<div class="input__container" v-show="nodeZoom" @mousedown="(e) => e.stopPropagation()" @keydown="handleInputKeydown">
|
||||
<div class="title">
|
||||
<div class="left">
|
||||
<div class="tag"></div>
|
||||
@ -227,7 +227,6 @@ import { emitter } from "@/utils/eventBus";
|
||||
import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue";
|
||||
import FormItemRecursive from "../common/FormItemRecursive.vue";
|
||||
import * as monaco from 'monaco-editor';
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
model: Object,
|
||||
@ -287,16 +286,13 @@ const setNodeProperties = async () => {
|
||||
if (outputFormRef.value) {
|
||||
flag = await outputFormRef.value.validate();
|
||||
}
|
||||
const errorLength = validateCode()
|
||||
if (errorLength > 0) {
|
||||
ElMessage.error("代码节点内JS代码错误")
|
||||
return
|
||||
if (hasErrors()) {
|
||||
console.log('编辑器中有错误')
|
||||
return
|
||||
}
|
||||
if (result && flag) {
|
||||
const data = toRaw(formData);
|
||||
|
||||
const targetObj = data.nodeParams.find(item => item.name === 'code');
|
||||
|
||||
if (targetObj) {
|
||||
// 存在:修改该对象的 input 属性
|
||||
targetObj.input = editorInstance.getValue();
|
||||
@ -453,7 +449,34 @@ const handleInputKeydown = (e) => {
|
||||
}
|
||||
};
|
||||
|
||||
function hasErrors() {
|
||||
const model = editorInstance.getModel();
|
||||
if (!model) return false;
|
||||
|
||||
// 获取当前模型的所有标记
|
||||
const markers = monaco.editor.getModelMarkers({ resource: model.uri });
|
||||
// 检查是否存在错误级别标记
|
||||
return markers.some(marker => marker.severity === monaco.MarkerSeverity.Error);
|
||||
}
|
||||
|
||||
const initEditor = () => {
|
||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
||||
allowNonTsExtensions: true, // 允许非 ts 扩展名(.js)
|
||||
checkJs: true, // 对 .js 文件进行类型检查
|
||||
strict: true, // 启用所有严格检查
|
||||
noImplicitAny: false, // 禁止隐式 any
|
||||
noUnusedLocals: true, // 未使用的局部变量报错(可选)
|
||||
noUnusedParameters: true, // 未使用的参数报错(可选)
|
||||
});
|
||||
|
||||
// 确保语义验证开启(默认就是开启的,但可以显式设置)
|
||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||
noSemanticValidation: false, // 开启语义检查
|
||||
noSyntaxValidation: false, // 开启语法检查
|
||||
});
|
||||
|
||||
|
||||
editorInstance = monaco.editor.create(codeRef.value, {
|
||||
value: [`
|
||||
// 方法定义不能修改
|
||||
@ -470,8 +493,21 @@ const initEditor = () => {
|
||||
}`].join('\n'),
|
||||
language: 'javascript',
|
||||
fontSize: 14,
|
||||
lineNumbers: 'on',
|
||||
roundedSelection: true,
|
||||
scrollBeyondLastLine: false,
|
||||
formatOnPaste: true,
|
||||
formatOnType: true
|
||||
formatOnType: true,
|
||||
quickSuggestions: true,
|
||||
suggestOnTriggerCharacters: true,
|
||||
// 自动完成
|
||||
suggest: {
|
||||
showWords: true,
|
||||
showFunctions: true,
|
||||
showVariables: true,
|
||||
showClasses: true,
|
||||
showModules: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -482,66 +518,6 @@ const setValue = (value) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 验证代码
|
||||
const validateCode = () => {
|
||||
if (!editorInstance) return
|
||||
|
||||
const code = editorInstance.getValue()
|
||||
const errors = []
|
||||
|
||||
try {
|
||||
// 1. 基础语法检查
|
||||
try {
|
||||
new Function(code)
|
||||
} catch (syntaxError) {
|
||||
errors.push({
|
||||
type: 'syntax',
|
||||
message: syntaxError.message,
|
||||
line: extractLineNumber(syntaxError)
|
||||
})
|
||||
}
|
||||
// 2. 检查运行时错误(通过尝试执行)
|
||||
if (errors.length === 0) {
|
||||
try {
|
||||
const fn = new Function(code);
|
||||
fn(); // 尝试执行
|
||||
} catch (runtimeError) {
|
||||
errors.push({ type: 'runtime', message: runtimeError.message });
|
||||
}
|
||||
}
|
||||
|
||||
// 设置 Monaco 标记
|
||||
const markers = []
|
||||
|
||||
errors.forEach(error => {
|
||||
markers.push({
|
||||
severity: monaco.MarkerSeverity.Error,
|
||||
startLineNumber: error.line || 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: error.line || 1,
|
||||
endColumn: 100,
|
||||
message: error.message
|
||||
})
|
||||
})
|
||||
monaco.editor.setModelMarkers(editorInstance.getModel(), 'validation', markers)
|
||||
} catch (error) {
|
||||
console.error('验证过程中出错:', error)
|
||||
}
|
||||
|
||||
return errors.length
|
||||
}
|
||||
|
||||
// 格式化代码
|
||||
const formatCode = () => {
|
||||
if (!editorInstance) return
|
||||
try {
|
||||
editorInstance.getAction('editor.action.formatDocument').run()
|
||||
|
||||
} catch (error) {
|
||||
console.error('格式化失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 销毁编辑器
|
||||
const disposeEditor = () => {
|
||||
if (editorInstance) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user