feat: 代码节点验证

This commit is contained in:
zhanghao 2026-03-04 16:18:04 +08:00
parent 8311f2a6c5
commit 58a07f310a
2 changed files with 46 additions and 70 deletions

View File

@ -41,7 +41,7 @@
@zoom="zoom" @zoom="zoom"
@setNodeName="setNodeName" @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="title">
<div class="left"> <div class="left">
<div class="tag"></div> <div class="tag"></div>

View File

@ -41,7 +41,7 @@
@zoom="zoom" @zoom="zoom"
@setNodeName="setNodeName" @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="title">
<div class="left"> <div class="left">
<div class="tag"></div> <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 IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue";
import FormItemRecursive from "../common/FormItemRecursive.vue"; import FormItemRecursive from "../common/FormItemRecursive.vue";
import * as monaco from 'monaco-editor'; import * as monaco from 'monaco-editor';
import { ElMessage } from "element-plus";
const props = defineProps({ const props = defineProps({
model: Object, model: Object,
@ -287,16 +286,13 @@ const setNodeProperties = async () => {
if (outputFormRef.value) { if (outputFormRef.value) {
flag = await outputFormRef.value.validate(); flag = await outputFormRef.value.validate();
} }
const errorLength = validateCode() if (hasErrors()) {
if (errorLength > 0) { console.log('编辑器中有错误')
ElMessage.error("代码节点内JS代码错误") return
return
} }
if (result && flag) { if (result && flag) {
const data = toRaw(formData); const data = toRaw(formData);
const targetObj = data.nodeParams.find(item => item.name === 'code'); const targetObj = data.nodeParams.find(item => item.name === 'code');
if (targetObj) { if (targetObj) {
// input // input
targetObj.input = editorInstance.getValue(); 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 = () => { 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, { editorInstance = monaco.editor.create(codeRef.value, {
value: [` value: [`
// //
@ -470,8 +493,21 @@ const initEditor = () => {
}`].join('\n'), }`].join('\n'),
language: 'javascript', language: 'javascript',
fontSize: 14, fontSize: 14,
lineNumbers: 'on',
roundedSelection: true,
scrollBeyondLastLine: false,
formatOnPaste: true, 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 = () => { const disposeEditor = () => {
if (editorInstance) { if (editorInstance) {