소스 검색

Merge branch 'master' of http://59.110.91.129:3000/zhangmengying/AIClass into wanzi

丸子 6 달 전
부모
커밋
787d303e01
1개의 변경된 파일160개의 추가작업 그리고 33개의 파일을 삭제
  1. 160 33
      src/components/blockly/BlocklyEditor.vue

+ 160 - 33
src/components/blockly/BlocklyEditor.vue

@@ -118,7 +118,7 @@
           </div>
           <div v-if="statusMessage" :class="['status', statusType]">
             {{ statusMessage }}
-          </div>
+</div>
         </div>
 
         <!-- 在template部分的适当位置音频播放器组件 -->
@@ -190,6 +190,7 @@
 </template>
 
 <script setup>
+// 仅保留必要的导入和主组件逻辑
 import { ref, onMounted, onUnmounted, reactive } from 'vue';
 import { useRouter } from 'vue-router';
 import { ArrowLeftBold } from '@element-plus/icons-vue';
@@ -238,6 +239,12 @@ const toggleLight = () => {
   startRecordingStatus();
   runCode();
 };
+
+// 添加开始录音状态函数
+const handleMusicEnded = () => {
+  onMusicEnded(state);
+};
+
 // 添加开始录音状态函数
 function startRecordingStatus() {
   isRecording.value = true;
@@ -272,9 +279,119 @@ const handleViewCode = () => {
 };
 
 // 响应式变量
-const jsonData = ref(``);
+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('// 生成的代码将显示在这里\n');
+//输出结果
+const output = ref('');
 const statusMessage = ref('');
 const statusType = ref('');
 let workspace = null;
@@ -721,11 +838,18 @@ const aiService = {
     return validColor;
   }, '设置台灯颜色失败'),
 
-  // 音乐播放相关方法
+  /**
+   * 播放音乐功能
+   * @param {string} musicType - 音乐类型
+   * @returns {Promise<void>} - 返回Promise
+   */
   playMusic: withErrorHandling('播放音乐', async function(musicType) {
     return playMusic(musicType, state, musicPlayer);
   }, '播放音乐失败'),
-
+  /**
+   * 停止音乐播放
+   * @returns {Promise<void>} - 返回Promise
+   */
   stopMusic: withErrorHandling('停止音乐', async function() {
     return stopMusic(state, musicPlayer);
   }, '停止音乐失败'),
@@ -779,7 +903,7 @@ const aiService = {
     if (type === 'image' || type === 'all') {
       pollingManager.startPolling('image', async () => {
         const imageIds = Object.keys(state.inProgressImageMap).map(Number);
-        state.inProgressImageMap = await pollTaskStatus(
+state.inProgressImageMap = await pollTaskStatus(
             'image',
             imageIds,
             PaintingGetMys,
@@ -822,11 +946,6 @@ const aiService = {
   }
 };
 
-// 音乐相关的处理函数
-const handleMusicEnded = () => {
-  onMusicEnded(state);
-};
-
 // 专门的停止音乐处理函数
 const handleStopMusic = () => {
   // 直接调用导入的stopMusic函数并传递正确的参数
@@ -850,22 +969,22 @@ onMounted(() => {
   // 从全局状态初始化年级ID
   state.gradeId = globalState.initGradeId();
 
-  // 注册AI语音输入积木
+  // 注册AI语音识别积木
   Blockly.Blocks["ai_voice_input"] = {
     init: function () {
-      this.appendDummyInput().appendField("语音输入");
+      this.appendDummyInput().appendField("语音识别");
       this.appendValueInput("PROMPT")
           .setCheck("String")
           .appendField("提示文字:");
-      this.appendDummyInput()
-          .appendField("语言:")
-          .appendField(
-              new Blockly.FieldDropdown([
-                ["中文", "zh-CN"],
-                ["英文", "en-US"],
-              ]),
-              "LANGUAGE"
-          );
+      // this.appendDummyInput()
+      //     .appendField("语言:")
+      //     .appendField(
+      //         new Blockly.FieldDropdown([
+      //           ["中文", "zh-CN"],
+      //           ["英文", "en-US"],
+      //         ]),
+      //         "LANGUAGE"
+      //     );
       this.setOutput(true, "String");
       this.setColour(310);
       this.setTooltip("使用语音识别获取文本输入");
@@ -981,7 +1100,7 @@ onMounted(() => {
     init: function () {
       this.appendDummyInput().appendField("设置台灯颜色");
       this.appendValueInput("COLOR").setCheck("String").appendField("颜色:");
-      this.appendDummyInput().appendField("可选颜色: 红,蓝,绿,黄,青,靛,紫");
+      this.appendDummyInput().appendField("可选颜色: 白,黄,紫,橙,青");
       this.setInputsInline(false);
       this.setPreviousStatement(true, null);
       this.setNextStatement(true, null);
@@ -1081,24 +1200,33 @@ onMounted(() => {
 
 // 组件卸载时清除所有资源
 onUnmounted(() => {
-  // 统一的轮询管理器停止所有轮询
-  pollingManager.stopAll();
+  // 清除所有定时器
+  if (countdownInterval) {
+    clearInterval(countdownInterval);
+  }
 
-  // 停止音乐播放
-  aiService.stopMusic();
+  // 停止所有轮询
+  pollingManager.stopAll();
 
-  // 停止文本生成流
-  aiService.stopTextToTextStream();
+  // 关闭语音识别(如果正在进行)
+  if (recognition) {
+    recognition.stop();
+  }
 
-  // 释放工作区资源
+  // 清理工作区
   if (workspace) {
     workspace.dispose();
   }
+
+  // 清理音频资源
+  if (musicPlayer.value) {
+    musicPlayer.value.pause();
+  }
 });
 
 // 注册JavaScript代码生成器
 function registerJavaScriptGenerators() {
-  // 语音输入
+  // 语音识别
   javascriptGenerator.forBlock['ai_voice_input'] = function(block, generator) {
     const prompt = generator.valueToCode(block, 'PROMPT', javascriptGenerator.ORDER_ATOMIC);
     const language = block.getFieldValue('LANGUAGE');
@@ -1169,7 +1297,7 @@ function registerJavaScriptGenerators() {
 
 // 注册Python代码生成器
 function registerPythonGenerators() {
-  // 语音输入
+  // 语音识别
   pythonGenerator.forBlock['ai_voice_input'] = function(block, generator) {
     const prompt = generator.valueToCode(block, 'PROMPT', pythonGenerator.ORDER_ATOMIC);
     const language = block.getFieldValue('LANGUAGE');
@@ -1382,7 +1510,6 @@ const runCode = async () => {
           code.includes('document.write') || code.includes('window.location')) {
         throw new Error('代码包含不安全的操作');
       }
-
       // 包装代码为异步函数执行,支持await
       const wrappedCode = `(async () => { ${code} })()`;
       await new Function(wrappedCode)();