Просмотр исходного кода

feat: 增加产品详情中数据解析支持多个函数的功能,并同时支持提调试多个函数

yanglzh 1 год назад
Родитель
Сommit
96a0aa87cc
2 измененных файлов с 99 добавлено и 20 удалено
  1. 53 0
      public/worker.js
  2. 46 20
      src/views/iot/device/product/component/dataParse.vue

+ 53 - 0
public/worker.js

@@ -0,0 +1,53 @@
+// worker.js
+
+self.addEventListener('message', ({ data }) => {
+  // console.log(data)
+  const { type, functionString, functionName, params } = data
+
+  // 校验函数字符串是否合法,是否含有parse和send函数
+  if (type === 'validateFunctionString') {
+    try {
+      eval(functionString)
+    } catch (_err) {
+      // throw new Error('请确保语法正确')
+      self.postMessage({ isOk: false, message: '请确保语法正确' });
+    }
+    try {
+      if (parse) {
+        try {
+          if (send) {
+            self.postMessage({ isOk: true, data: 'xxx' });
+          }
+        } catch (_err) {
+          // throw new Error('请确保含有【send】函数')
+          self.postMessage({ isOk: false, message: '请确保含有【send】函数' });
+        }
+      }
+    } catch (_err) {
+      self.postMessage({ isOk: false, message: '请确保含有【parse】函数' });
+      // throw new Error('请确保含有【parse】函数')
+    }
+    return
+  }
+
+  // 执行函数
+  if (type === 'runFunction') {
+    eval(functionString)
+    try {
+      const func = eval(functionName)
+      // 先尝试转换为json,如果失败再当做字符串使用
+      try {
+        const parseParams = JSON.parse(params)
+        const data = func(parseParams)
+        self.postMessage({ isOk: true, data });
+      } catch (_err) {
+        const data = func(params)
+        self.postMessage({ isOk: true, data });
+      }
+    } catch (_err) {
+      self.postMessage({ isOk: false, message: _err.message });
+    }
+    return
+  }
+
+});

+ 46 - 20
src/views/iot/device/product/component/dataParse.vue

@@ -2,8 +2,12 @@
 	<div class="flex">
 		<codeEditor class="params flex1" ref="mirrorRef" mode="" :content="content"></codeEditor>
 		<div class="mock" style="width: 300px;margin-left: 20px;">
+			<el-radio-group v-model="functionName">
+				<el-radio-button label="parse">parse</el-radio-button>
+				<el-radio-button label="send">send</el-radio-button>
+			</el-radio-group>
 			<el-input class="input" v-model="inputData" type="textarea" placeholder="请输入入参,以字符串的方式,如果是对象字符串会在执行时自动转换为对象再执行"></el-input>
-			<el-input class="output" v-model="outputData" type="textarea" readonly placeholder="此处显示执行结果"></el-input>
+			<el-input class="input" v-model="outputData" type="textarea" readonly placeholder="此处显示执行结果"></el-input>
 		</div>
 	</div>
 	<el-button type="primary" style="margin-top:20px" v-auth="'save'" @click="saveCode">保存脚本</el-button>
@@ -37,6 +41,7 @@ function send (data) {
 	return data
 }
 `
+
 const route = useRoute();
 
 const emit = defineEmits(['updateScript'])
@@ -48,6 +53,7 @@ const props = defineProps({
 const inputData = ref('')
 const outputData = ref('')
 const content = ref('')
+const functionName = ref('parse')
 const mirrorRef = ref()
 
 onMounted(() => {
@@ -79,7 +85,30 @@ function toSave(data: string) {
 	})
 }
 
-function mock() {
+function validate() {
+
+	return new Promise((resolve, reject) => {
+		const funStr = mirrorRef.value.getValue()
+		const worker = new Worker('./worker.js');
+
+		// 向 Worker 发送消息
+		worker.postMessage({ type: 'validateFunctionString', functionString: funStr });
+
+		// 监听 Worker 返回的消息
+		worker.addEventListener('message', ({ data }) => {
+			worker.terminate()
+			if (data.isOk) return resolve(true)
+			ElMessage.error(data.message)
+			reject()
+		});
+	})
+}
+
+async function mock() {
+	outputData.value = ''
+	
+	await validate()
+
 	if (!inputData.value) return ElMessage.error('请输入参数')
 
 	const funStr = mirrorRef.value.getValue()
@@ -88,34 +117,31 @@ function mock() {
 		return ElMessage.error('请先输入可执行脚本')
 	}
 
-	try {
-		const fun = eval("(" + funStr + ")")
-		try {
-			const res = fun(JSON.parse(inputData.value))
-			outputData.value = typeof res === 'object' ? JSON.stringify(res, null, 2) : res
-		} catch {
-			const res = fun(inputData.value)
-			outputData.value = typeof res === 'object' ? JSON.stringify(res, null, 2) : res
-		}
-	} catch (error) {
-		ElMessage.error('数据解析脚本语法校验未通过或参数类型有误')
-	}
 
+	const worker = new Worker('./worker.js');
+	// 向 Worker 发送消息
+	worker.postMessage({ type: 'runFunction', functionString: funStr, functionName: functionName.value, params: inputData.value });
+	// 监听 Worker 返回的消息
+	worker.addEventListener('message', ({ data }) => {
+		worker.terminate()
+		if (data.isOk) {
+			return outputData.value = typeof data.data === 'object' ? JSON.stringify(data.data, null, 2) : data.data
+		}
+		ElMessage.error(data.message)
+	});
 }
 </script>
+
 <style lang="scss" scoped>
 :deep(.CodeMirror) {
-	height: calc(100vh - 320px);
+	height: calc(100vh - 340px);
 }
 
 .input,
 .output {
+	margin-top: 14px;
 	:deep(.el-textarea__inner) {
-		height: calc(50vh - 170px);
+		height: calc(50vh - 200px);
 	}
 }
-
-.output {
-	margin-top: 20px;
-}
 </style>