|
|
@@ -111,7 +111,7 @@
|
|
|
|
|
|
<div class="json-section">
|
|
|
<h3> 数据</h3>
|
|
|
- <textarea v-model="jsonData" rows="10" placeholder="在此输入JSON格式的积木块数据..."></textarea>
|
|
|
+ <textarea v-model="jsonDataString" rows="10" placeholder="在此输入JSON格式的积木块数据..."></textarea>
|
|
|
<div class="controls">
|
|
|
<button @click="loadWorkspaceFromJson">加载JSON到工作区</button>
|
|
|
<button @click="exportWorkspaceToJson">导出工作区为JSON</button>
|
|
|
@@ -191,7 +191,7 @@
|
|
|
|
|
|
<script setup>
|
|
|
// 仅保留必要的导入和主组件逻辑
|
|
|
-import { ref, onMounted, onUnmounted, reactive } from 'vue';
|
|
|
+import {ref, onMounted, onUnmounted, reactive, computed} from 'vue';
|
|
|
import { useRouter } from 'vue-router';
|
|
|
import { ArrowLeftBold } from '@element-plus/icons-vue';
|
|
|
import * as Blockly from "blockly";
|
|
|
@@ -217,6 +217,14 @@ import { playMusic, stopMusic, onMusicEnded } from "@/api/blockly/music.js";
|
|
|
import {ElButton} from "element-plus";
|
|
|
|
|
|
const router = useRouter();
|
|
|
+
|
|
|
+// 设备信息
|
|
|
+const device = ref({
|
|
|
+ name: "",
|
|
|
+ image: "",
|
|
|
+ jsonData: {}
|
|
|
+});
|
|
|
+
|
|
|
// 台灯预览显示状态
|
|
|
const showLampPreview = ref(true);
|
|
|
// 语音识别
|
|
|
@@ -278,118 +286,135 @@ const handleViewCode = () => {
|
|
|
showLampPreview.value = false;
|
|
|
};
|
|
|
|
|
|
-// 响应式变量
|
|
|
-const jsonData = ref({
|
|
|
- "blocks": {
|
|
|
- "languageVersion": 0,
|
|
|
- "blocks": [
|
|
|
- {
|
|
|
- "type": "variables_set",
|
|
|
- "id": "kM:Fgf:wd4U3Z$j0x8oK",
|
|
|
- "x": 90,
|
|
|
- "y": 130,
|
|
|
- "fields": {
|
|
|
- "VAR": {
|
|
|
- "id": "MHW(ZbOKhL!/An`5N@6`"
|
|
|
- }
|
|
|
- },
|
|
|
- "inputs": {
|
|
|
- "VALUE": {
|
|
|
- "block": {
|
|
|
- "type": "ai_voice_input",
|
|
|
- "id": "l5E=g|1L+4hThQ8v})lQ",
|
|
|
- "fields": {
|
|
|
- "LANGUAGE": "zh-CN"
|
|
|
- },
|
|
|
- "inputs": {
|
|
|
- "PROMPT": {
|
|
|
- "block": {
|
|
|
- "type": "text",
|
|
|
- "id": "Q*n.c_)@7j^E2=s5/X!n",
|
|
|
- "fields": {
|
|
|
- "TEXT": "请发言:"
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- "next": {
|
|
|
- "block": {
|
|
|
- "type": "variables_set",
|
|
|
- "id": "]g.xbBe.i=a9B*Kfw@|`",
|
|
|
- "fields": {
|
|
|
- "VAR": {
|
|
|
- "id": "zn.7{ZqbUaH1?P,R05hF"
|
|
|
- }
|
|
|
- },
|
|
|
- "inputs": {
|
|
|
- "VALUE": {
|
|
|
- "block": {
|
|
|
- "type": "ai_text_to_text",
|
|
|
- "id": "R$h+R!6#@+4=+WX1*nvh",
|
|
|
- "inputs": {
|
|
|
- "PROMPT": {
|
|
|
- "block": {
|
|
|
- "type": "variables_get",
|
|
|
- "id": "h$S$nt)3VU.=nX*W-mo~",
|
|
|
- "fields": {
|
|
|
- "VAR": {
|
|
|
- "id": "MHW(ZbOKhL!/An`5N@6`"
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- "提示词": {
|
|
|
- "block": {
|
|
|
- "type": "text",
|
|
|
- "id": "7k%sgLP?i]e[,m^49P++",
|
|
|
- "fields": {
|
|
|
- "TEXT": "请只回复我指定格式:白,100,热闹"
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- "next": {
|
|
|
- "block": {
|
|
|
- "type": "ai_smart_lamp_single_param",
|
|
|
- "id": "!.0;Ktwm+Z?o8_9FRa}G",
|
|
|
- "inputs": {
|
|
|
- "PARAMS": {
|
|
|
- "block": {
|
|
|
- "type": "variables_get",
|
|
|
- "id": "d{cIJ-kEFFQcn~%A,g@g",
|
|
|
- "fields": {
|
|
|
- "VAR": {
|
|
|
- "id": "zn.7{ZqbUaH1?P,R05hF"
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
+// 创建计算属性处理 JSON 字符串的序列化和反序列化
|
|
|
+const jsonDataString = computed({
|
|
|
+ get() {
|
|
|
+ // 获取时序列化对象为字符串
|
|
|
+ return JSON.stringify(device.value.jsonData, null, 2);
|
|
|
},
|
|
|
- "variables": [
|
|
|
- {
|
|
|
- "name": "inputText",
|
|
|
- "id": "MHW(ZbOKhL!/An`5N@6`"
|
|
|
- },
|
|
|
- {
|
|
|
- "name": "lampConfig",
|
|
|
- "id": "zn.7{ZqbUaH1?P,R05hF"
|
|
|
+ set(value) {
|
|
|
+ // 设置时解析字符串为对象
|
|
|
+ try {
|
|
|
+ device.value.jsonData = JSON.parse(value);
|
|
|
+ } catch (e) {
|
|
|
+ console.error("无效的JSON格式", e);
|
|
|
+ // 可以添加错误提示给用户
|
|
|
}
|
|
|
- ]
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
+// 响应式变量
|
|
|
+// const jsonData = ref({
|
|
|
+// "blocks": {
|
|
|
+// "languageVersion": 0,
|
|
|
+// "blocks": [
|
|
|
+// {
|
|
|
+// "type": "variables_set",
|
|
|
+// "id": "kM:Fgf:wd4U3Z$j0x8oK",
|
|
|
+// "x": 90,
|
|
|
+// "y": 130,
|
|
|
+// "fields": {
|
|
|
+// "VAR": {
|
|
|
+// "id": "MHW(ZbOKhL!/An`5N@6`"
|
|
|
+// }
|
|
|
+// },
|
|
|
+// "inputs": {
|
|
|
+// "VALUE": {
|
|
|
+// "block": {
|
|
|
+// "type": "ai_voice_input",
|
|
|
+// "id": "l5E=g|1L+4hThQ8v})lQ",
|
|
|
+// "fields": {
|
|
|
+// "LANGUAGE": "zh-CN"
|
|
|
+// },
|
|
|
+// "inputs": {
|
|
|
+// "PROMPT": {
|
|
|
+// "block": {
|
|
|
+// "type": "text",
|
|
|
+// "id": "Q*n.c_)@7j^E2=s5/X!n",
|
|
|
+// "fields": {
|
|
|
+// "TEXT": "请发言:"
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// },
|
|
|
+// "next": {
|
|
|
+// "block": {
|
|
|
+// "type": "variables_set",
|
|
|
+// "id": "]g.xbBe.i=a9B*Kfw@|`",
|
|
|
+// "fields": {
|
|
|
+// "VAR": {
|
|
|
+// "id": "zn.7{ZqbUaH1?P,R05hF"
|
|
|
+// }
|
|
|
+// },
|
|
|
+// "inputs": {
|
|
|
+// "VALUE": {
|
|
|
+// "block": {
|
|
|
+// "type": "ai_text_to_text",
|
|
|
+// "id": "R$h+R!6#@+4=+WX1*nvh",
|
|
|
+// "inputs": {
|
|
|
+// "PROMPT": {
|
|
|
+// "block": {
|
|
|
+// "type": "variables_get",
|
|
|
+// "id": "h$S$nt)3VU.=nX*W-mo~",
|
|
|
+// "fields": {
|
|
|
+// "VAR": {
|
|
|
+// "id": "MHW(ZbOKhL!/An`5N@6`"
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// },
|
|
|
+// "提示词": {
|
|
|
+// "block": {
|
|
|
+// "type": "text",
|
|
|
+// "id": "7k%sgLP?i]e[,m^49P++",
|
|
|
+// "fields": {
|
|
|
+// "TEXT": "请只回复我指定格式:白,100,热闹"
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// },
|
|
|
+// "next": {
|
|
|
+// "block": {
|
|
|
+// "type": "ai_smart_lamp_single_param",
|
|
|
+// "id": "!.0;Ktwm+Z?o8_9FRa}G",
|
|
|
+// "inputs": {
|
|
|
+// "PARAMS": {
|
|
|
+// "block": {
|
|
|
+// "type": "variables_get",
|
|
|
+// "id": "d{cIJ-kEFFQcn~%A,g@g",
|
|
|
+// "fields": {
|
|
|
+// "VAR": {
|
|
|
+// "id": "zn.7{ZqbUaH1?P,R05hF"
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+// ]
|
|
|
+// },
|
|
|
+// "variables": [
|
|
|
+// {
|
|
|
+// "name": "inputText",
|
|
|
+// "id": "MHW(ZbOKhL!/An`5N@6`"
|
|
|
+// },
|
|
|
+// {
|
|
|
+// "name": "lampConfig",
|
|
|
+// "id": "zn.7{ZqbUaH1?P,R05hF"
|
|
|
+// }
|
|
|
+// ]
|
|
|
+// });
|
|
|
+
|
|
|
//输出结果
|
|
|
const output = ref('');
|
|
|
const statusMessage = ref('');
|
|
|
@@ -980,7 +1005,11 @@ onMounted(() => {
|
|
|
// 从全局状态初始化年级ID
|
|
|
state.gradeId = globalState.initGradeId();
|
|
|
|
|
|
- // 注册AI语音识别积木
|
|
|
+ device.value.name = router.currentRoute.value.query.name || "";
|
|
|
+ device.value.image = router.currentRoute.value.query.image || "";
|
|
|
+ device.value.jsonData = JSON.parse(router.currentRoute.value.query.jsonData || {});
|
|
|
+
|
|
|
+ // 注册AI语音识别积木
|
|
|
Blockly.Blocks["ai_voice_input"] = {
|
|
|
init: function () {
|
|
|
this.appendDummyInput().appendField("语音识别");
|
|
|
@@ -1381,7 +1410,8 @@ function registerPythonGenerators() {
|
|
|
const loadWorkspaceFromJson = () => {
|
|
|
try {
|
|
|
// const json = JSON.parse(jsonData.value);
|
|
|
- const json = jsonData.value;
|
|
|
+ const json = device.value.jsonData;
|
|
|
+ console.log(typeof json);
|
|
|
Blockly.serialization.workspaces.load(json, workspace);
|
|
|
showStatus('工作区已成功从JSON加载!');
|
|
|
} catch (error) {
|
|
|
@@ -1395,7 +1425,7 @@ const exportWorkspaceToJson = () => {
|
|
|
try {
|
|
|
const state = Blockly.serialization.workspaces.save(workspace);
|
|
|
// jsonData.value = JSON.stringify(state, null, 2);
|
|
|
- jsonData.value = state;
|
|
|
+ device.value.jsonData = state;
|
|
|
showStatus('工作区已成功导出为JSON!');
|
|
|
} catch (error) {
|
|
|
showStatus('导出错误: ' + error.message, 'error');
|
|
|
@@ -1428,7 +1458,8 @@ const generateCode = (language = 'javascript') => {
|
|
|
}
|
|
|
};
|
|
|
// 将JSON对象格式化为字符串并设置到JSON框
|
|
|
- jsonData.value = JSON.stringify(codeJson, null, 2);
|
|
|
+ // jsonData.value = JSON.stringify(codeJson, null, 2);
|
|
|
+ device.value.jsonData = codeJson;
|
|
|
|
|
|
showStatus('代码生成成功!已同时输出到JSON框');
|
|
|
} catch (error) {
|