feat: 代码节点验证
This commit is contained in:
parent
8311f2a6c5
commit
58a07f310a
@ -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>
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user