liyanbo 6 ماه پیش
والد
کامیت
7c81190619
1فایلهای تغییر یافته به همراه242 افزوده شده و 306 حذف شده
  1. 242 306
      src/views/Blockly.vue

+ 242 - 306
src/views/Blockly.vue

@@ -8,21 +8,21 @@
         智能台灯
       </div>
     </div>
-    
+
     <img src="@/assets/images/desklamp.png" alt="智能台灯" class="full-screen-image" />
     <!-- 使用动态样式设置灯光遮罩 -->
-     <div v-if="isLightOn" :style="{ '--lamp-color': lampColor,'--lamp-opacity': lampBrightness / 100 }" class="lamp-light-mask"></div>
+     <div v-if="isLightOn"  :style="{ '--lamp-color': state.lamp.color,'--lamp-opacity': state.lamp.brightness / 100 }" class="lamp-light-mask"></div>
 
     <!-- 右下角按钮组 -->
     <div class="button-group">
       <el-button class="control-button run-button" @click="toggleLight">运行</el-button>
       <el-button class="control-button code-button" @click="handleViewCode">查看代码</el-button>
     </div>
-    
+
     <!-- 显示当前灯光信息 -->
     <div v-if="isLightOn" class="lamp-info">
-      <p>颜色: {{ lampColor }}</p>
-      <p>亮度: {{ lampBrightness }}%</p>
+      <p>颜色: {{ state.lamp.color }}</p>
+      <p>亮度: {{ state.lamp.brightness }}%</p>
     </div>
   </div>
 
@@ -43,20 +43,20 @@
           style="height: 100%; width: 100%; background-color: #cccccc"
         ></div>
 
-        <!-- blockly工具栏 -->
-        <template>
-          <xml id="toolbox" style="display: none">
-            <!-- AI模块分类 - 扩展更多功能 -->
-            <category name="AI模块" categorystyle="ai_category">
-              <block type="ai_voice_input"></block>
-              <block type="ai_text_to_image"></block>
-              <block type="ai_text_to_video"></block>
-              <block type="ai_text_to_text"></block>
-              <block type="ai_semantic_analysis"></block>
-              <block type="ai_smart_lamp"></block>
-              <block type="ai_lamp_set_brightness"></block>
-              <block type="ai_lamp_set_color"></block>
-            </category>
+      <!-- blockly工具栏 -->
+      <template>
+        <xml id="toolbox" style="display: none">
+          <!-- AI模块分类 - 扩展更多功能 -->
+          <category name="AI模块" categorystyle="ai_category">
+            <block type="ai_voice_input"></block>
+            <block type="ai_text_to_image"></block>
+            <block type="ai_text_to_video"></block>
+            <block type="ai_text_to_text"></block>
+            <block type="ai_smart_lamp_single_param"></block>
+            <block type="ai_smart_lamp"></block>
+            <block type="ai_lamp_set_brightness"></block>
+            <block type="ai_lamp_set_color"></block>
+          </category>
 
             <!-- 其他原有分类保持不变 -->
             <category name="逻辑" categorystyle="logic_category">
@@ -526,6 +526,9 @@ const goBack = () => {
 // 切换灯光状态
 const toggleLight = () => {
   isLightOn.value = true;
+
+  generateCode('javascript');
+  runCode()
 }
 // 查看代码编程界面显示状态
 const handleViewCode = () =>{
@@ -674,27 +677,23 @@ onMounted(async () => {
     },
   };
 
-  // 注册AI语义识别积木
-  Blockly.Blocks["ai_semantic_analysis"] = {
-    init: function () {
-      this.appendDummyInput().appendField("语义识别");
-      this.appendValueInput("TEXT").setCheck("String").appendField("分析文本:");
+  //AI智能台灯单参数积木
+  Blockly.Blocks['ai_smart_lamp_single_param'] = {
+    init: function() {
       this.appendDummyInput()
-        .appendField("分析类型:")
-        .appendField(
-          new Blockly.FieldDropdown([
-            ["通用", "general"],
-            ["情感", "sentiment"],
-            ["关键词", "keywords"],
-            ["意图", "intent"],
-          ]),
-          "TYPE"
-        );
-      this.setOutput(true, "String");
-      this.setColour(290);
-      this.setTooltip("使用AI分析文本的语义内容并返回结果");
-      this.setHelpUrl("");
-    },
+          .appendField('智能台灯控制(单参数)');
+      this.appendValueInput('PARAMS')
+          .setCheck('String')
+          .appendField('参数(格式: 颜色,亮度,音乐):');
+      this.appendDummyInput()
+          .appendField('例如: 蓝,50,平静');
+      this.setInputsInline(false);
+      this.setPreviousStatement(true, null);
+      this.setNextStatement(true, null);
+      this.setColour(280);
+      this.setTooltip('通过一个参数字符串控制智能台灯的亮度、颜色和音乐\n格式: 颜色,亮度,音乐\n例如: 蓝,50,平静');
+      this.setHelpUrl('');
+    }
   };
 
   // 注册AI智能台灯积木
@@ -758,8 +757,74 @@ onMounted(async () => {
     trashcan: true,
   });
 
-  // 工作区变化时自动生成JavaScript代码
-  state.workspace.addChangeListener(() => generateCode("javascript"));
+// 加载初始XML内容
+  try {
+    // 使用字符串拼接代替模板字符串,避免特殊字符问题
+    const initialXml = '<xml xmlns="https://developers.google.com/blockly/xml">\n' +
+        '  <block type="ai_smart_lamp_single_param" id="]t3dfZuv34^1VI%c+Vww" x="50" y="90">\n' +
+        '    <value name="PARAMS">\n' +
+        '      <block type="ai_text_to_text" id="iIw6Y|#j@Kh_}]!6A;Ef">\n' +
+        '        <field name="MODEL">default</field>\n' +
+        '        <value name="PROMPT">\n' +
+        '          <block type="ai_voice_input" id="qo`+VHZpJ0^Y_;J2T!VT">\n' +
+        '            <field name="LANGUAGE">zh-CN</field>\n' +
+        '            <value name="PROMPT">\n' +
+        '              <block type="text" id="uoH(8P)Q{|IMHBw=Gv">\n' +
+        '                <field name="TEXT">请说话:</field>\n' +
+        '              </block>\n' +
+        '            </value>\n' +
+        '          </block>\n' +
+        '        </value>\n' +
+        '      </block>\n' +
+        '    </value>\n' +
+        '  </block>\n' +
+        '</xml>';
+
+    const xml = Blockly.utils.xml.textToDom(initialXml);
+    Blockly.Xml.domToWorkspace(xml, state.workspace);
+
+    // 强制重新渲染工作区
+    state.workspace.render();
+
+    // 添加更长的延迟确保DOM完全更新后再设置属性
+    setTimeout(() => {
+      // 确保所有块都可移动和可删除
+      const blocks = state.workspace.getAllBlocks();
+      blocks.forEach(block => {
+        // 直接设置块的可移动和可删除属性为true
+        block.setMovable(true);
+        block.setDeletable(true);
+        // 设置嵌套连接点也可编辑
+        if (block.inputList) {
+          block.inputList.forEach(input => {
+            if (input.connection) {
+              input.connection.setCheck(null); // 允许任何类型的连接
+              input.connection.setHangingPriority(10); // 设置较高的连接优先级
+            }
+          });
+        }
+      });
+
+      // 再次渲染以应用属性更改
+      state.workspace.render();
+
+      // 初始化完成后手动生成一次代码
+      generateCode("javascript");
+
+      // 初始化完成后添加工作区变化监听器
+      setTimeout(() => {
+        state.workspace.addChangeListener(() => generateCode("javascript"));
+      }, 500);
+    }, 1500);
+  } catch (error) {
+    console.error('加载初始XML内容失败:', error);
+  }
+
+// 工作区变化时自动生成JavaScript代码
+// 注意:这里设置监听器的位置移到了初始化完成后
+  setTimeout(() => {
+    state.workspace.addChangeListener(() => generateCode("javascript"));
+  }, 1500);
 });
 // 组件卸载时清除定时器
 onUnmounted(() => {
@@ -1148,7 +1213,7 @@ const aiService = {
       // 如果没有活跃的对话ID,创建新对话
       if (!state.activeConversationId) {
         // 使用与TextToText.vue相同的方式创建对话
-        const res = await CreateDialogue({ roleId: 10 });
+        const res = await CreateDialogue({ roleId: 75 });
         state.activeConversationId = res.data;
         console.log("创建会话:", res.data);
       }
@@ -1244,52 +1309,12 @@ const aiService = {
     state.conversationInProgress = false;
   },
 
-  // 语义识别分析
-  async semanticAnalysis(text, type = "general") {
-    console.log("semanticAnalysis", text, type);
-    state.isProcessing = true;
-    try {
-      const response = await fetch(
-        `${aiServiceConfig.baseUrl}${aiServiceConfig.endpoints.semanticAnalysis}`,
-        {
-          method: "POST",
-          headers: { "Content-Type": "application/json" },
-          body: JSON.stringify({
-            text,
-            type,
-          }),
-        }
-      );
-
-      if (!response.ok) throw new Error("语义分析失败");
-
-      const data = await response.json();
-      state.generatedContent.text = data.result;
-
-      // 显示预览
-      state.previewType = "text";
-      state.previewContent = data.result;
-      state.previewVisible = true;
-
-      return data.result;
-    } catch (error) {
-      console.error("语义分析失败:", error);
-      ElMessage.error("语义分析失败: " + error.message);
-      return null;
-    } finally {
-      state.isProcessing = false;
-    }
-  },
-
   // 设置台灯亮度
   async setLampBrightness(brightness) {
     // console.log('setLampBrightness', brightness);
 
     // 验证亮度值在0-100之间
-    const validBrightness = Math.max(
-      0,
-      Math.min(100, parseInt(brightness) || 0)
-    );
+    const validBrightness = Math.max(0, Math.min(100, parseInt(brightness) || 0));
 
     // 更新状态
     state.lamp.brightness = validBrightness;
@@ -1306,15 +1331,15 @@ const aiService = {
 
     // 预定义的颜色映射
     const colorMap = {
-      红: "#ff0000",
-      蓝: "#0000ff",
-      绿: "#00ff00",
-      黄: "#ffff00",
-      青: "#00ffff",
-      靛: "#4b0082",
-      紫: "#800080",
-      白: "#ffffff",
-      黑: "#000000",
+      '红': '#ff0000',
+      '蓝': '#0000ff',
+      '绿': '#00ff00',
+      '黄': '#ffff00',
+      '青': '#00ffff',
+      '靛': '#4b0082',
+      '紫': '#800080',
+      '白': '#ffffff',
+      '黑': '#000000'
     };
 
     // 获取有效的颜色值
@@ -1334,7 +1359,38 @@ const aiService = {
     return validColor;
   },
 
-  // 综合控制台灯
+  // 综合控制台灯(参数格式:"颜色, 亮度, 音乐")
+  async controlLampWithSingleParam(params) {
+    // 解析参数字符串
+    let color = '白'; // 默认颜色
+    let brightness = 0; // 默认亮度
+    let music = ''; // 音乐信息(暂不处理)
+
+    if (params && typeof params === 'string') {
+      // 根据逗号分割参数
+      const paramArray = params.split(',').map(p => p.trim());
+
+      // 提取颜色(第一个参数)
+      if (paramArray.length > 0 && paramArray[0]) {
+        color = paramArray[0];
+      }
+
+      // 提取亮度(第二个参数)
+      if (paramArray.length > 1 && paramArray[1]) {
+        brightness = paramArray[1];
+      }
+
+      // 提取音乐(第三个参数,暂不处理)
+      if (paramArray.length > 2 && paramArray[2]) {
+        music = paramArray[2];
+        console.log('音乐信息(暂不处理):', music);
+      }
+    }
+    // 调用控制台灯方法
+    return await this.controlLamp(brightness, color);
+  },
+
+  // 综合控制台灯(参数格式:"颜色, 亮度, 音乐")
   async controlLamp(brightness, color) {
     console.log("controlLamp", brightness, color);
 
@@ -1351,128 +1407,66 @@ const aiService = {
 // 注册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");
-    const code = `await aiService.recognizeVoice(${
-      prompt || "''"
-    }, '${language}')`;
-    console.log("ai_voice_input", prompt, language);
+  javascriptGenerator.forBlock['ai_voice_input'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', javascriptGenerator.ORDER_ATOMIC);
+    const language = block.getFieldValue('LANGUAGE');
+    const code = `await aiService.recognizeVoice(${prompt || "''"}, '${language}')`;
+    console.log('ai_voice_input', prompt, language);
     return [code, javascriptGenerator.ORDER_ATOMIC];
   };
 
   // 文本生成图片
-  javascriptGenerator.forBlock["ai_text_to_image"] = function (
-    block,
-    generator
-  ) {
-    const prompt = generator.valueToCode(
-      block,
-      "PROMPT",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const waitForCompletion =
-      block.getFieldValue("WAIT_FOR_COMPLETION") === "TRUE";
+  javascriptGenerator.forBlock['ai_text_to_image'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', javascriptGenerator.ORDER_ATOMIC);
+    const waitForCompletion = block.getFieldValue('WAIT_FOR_COMPLETION') === 'TRUE';
     const code = `await aiService.textToImage(${prompt}, ${waitForCompletion});`;
-    console.log("ai_text_to_image", prompt, waitForCompletion);
+    console.log('ai_text_to_image', prompt, waitForCompletion);
     return code;
   };
 
   // 文本生成视频
-  javascriptGenerator.forBlock["ai_text_to_video"] = function (
-    block,
-    generator
-  ) {
-    const prompt = generator.valueToCode(
-      block,
-      "PROMPT",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const waitForCompletion =
-      block.getFieldValue("WAIT_FOR_COMPLETION") === "TRUE";
+  javascriptGenerator.forBlock['ai_text_to_video'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', javascriptGenerator.ORDER_ATOMIC);
+    const waitForCompletion = block.getFieldValue('WAIT_FOR_COMPLETION') === 'TRUE';
     const code = `await aiService.textToVideo(${prompt}, ${waitForCompletion});`;
-    console.log("ai_text_to_video", prompt, waitForCompletion);
+    console.log('ai_text_to_video', prompt, waitForCompletion);
     return code;
   };
 
   // 文本生成文本
-  javascriptGenerator.forBlock["ai_text_to_text"] = function (
-    block,
-    generator
-  ) {
-    const prompt = generator.valueToCode(
-      block,
-      "PROMPT",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const model = block.getFieldValue("MODEL");
+  javascriptGenerator.forBlock['ai_text_to_text'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', javascriptGenerator.ORDER_ATOMIC);
+    const model = block.getFieldValue('MODEL');
     const code = `await aiService.textToText(${prompt}, '${model}')`;
-    console.log("ai_text_to_text", prompt, model);
+    console.log('ai_text_to_text', prompt, model);
     return [code, javascriptGenerator.ORDER_ATOMIC];
   };
 
-  // 语义识别
-  javascriptGenerator.forBlock["ai_semantic_analysis"] = function (
-    block,
-    generator
-  ) {
-    const text = generator.valueToCode(
-      block,
-      "TEXT",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const type = block.getFieldValue("TYPE");
-    const code = `await aiService.semanticAnalysis(${text || "''"}, '${type}')`;
-    console.log("ai_semantic_analysis", text, type);
-    return [code, javascriptGenerator.ORDER_ATOMIC];
+  // 智能台灯控制(单参数)
+  javascriptGenerator.forBlock['ai_smart_lamp_single_param'] = function(block, generator) {
+    const params = generator.valueToCode(block, 'PARAMS', javascriptGenerator.ORDER_ATOMIC);
+    const code = `await aiService.controlLampWithSingleParam(${params || "'白,0,平静'"});`;
+    return code;
   };
 
-  // 智能台灯控制
-  javascriptGenerator.forBlock["ai_smart_lamp"] = function (block, generator) {
-    const brightness = generator.valueToCode(
-      block,
-      "BRIGHTNESS",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const color = generator.valueToCode(
-      block,
-      "COLOR",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const code = `await aiService.controlLamp(${brightness || "0"}, ${
-      color || "'白'"
-    });`;
+  // 智能台灯控制(多参数)
+  javascriptGenerator.forBlock['ai_smart_lamp'] = function(block, generator) {
+    const brightness = generator.valueToCode(block, 'BRIGHTNESS', javascriptGenerator.ORDER_ATOMIC);
+    const color = generator.valueToCode(block, 'COLOR', javascriptGenerator.ORDER_ATOMIC);
+    const code = `await aiService.controlLamp(${brightness || '0'}, ${color || "'白'"});`;
     return code;
   };
 
   // 设置台灯亮度
-  javascriptGenerator.forBlock["ai_lamp_set_brightness"] = function (
-    block,
-    generator
-  ) {
-    const brightness = generator.valueToCode(
-      block,
-      "BRIGHTNESS",
-      javascriptGenerator.ORDER_ATOMIC
-    );
-    const code = `await aiService.setLampBrightness(${brightness || "0"});`;
+  javascriptGenerator.forBlock['ai_lamp_set_brightness'] = function(block, generator) {
+    const brightness = generator.valueToCode(block, 'BRIGHTNESS', javascriptGenerator.ORDER_ATOMIC);
+    const code = `await aiService.setLampBrightness(${brightness || '0'});`;
     return code;
   };
 
   // 设置台灯颜色
-  javascriptGenerator.forBlock["ai_lamp_set_color"] = function (
-    block,
-    generator
-  ) {
-    const color = generator.valueToCode(
-      block,
-      "COLOR",
-      javascriptGenerator.ORDER_ATOMIC
-    );
+  javascriptGenerator.forBlock['ai_lamp_set_color'] = function(block, generator) {
+    const color = generator.valueToCode(block, 'COLOR', javascriptGenerator.ORDER_ATOMIC);
     const code = `await aiService.setLampColor(${color || "'白'"});`;
     return code;
   };
@@ -1481,109 +1475,55 @@ 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");
+  pythonGenerator.forBlock['ai_voice_input'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', pythonGenerator.ORDER_ATOMIC);
+    const language = block.getFieldValue('LANGUAGE');
     const code = `ai_service.recognize_voice(${prompt || "''"}, '${language}')`;
     return [code, pythonGenerator.ORDER_ATOMIC];
   };
 
   // 文本生成图片
-  pythonGenerator.forBlock["ai_text_to_image"] = function (block, generator) {
-    const prompt = generator.valueToCode(
-      block,
-      "PROMPT",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const waitForCompletion =
-      block.getFieldValue("WAIT_FOR_COMPLETION") === "TRUE";
+  pythonGenerator.forBlock['ai_text_to_image'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', pythonGenerator.ORDER_ATOMIC);
+    const waitForCompletion = block.getFieldValue('WAIT_FOR_COMPLETION') === 'TRUE';
     const code = `ai_service.text_to_image(${prompt}, ${waitForCompletion})\n`;
     return code;
   };
 
   // 文本生成视频
-  pythonGenerator.forBlock["ai_text_to_video"] = function (block, generator) {
-    const prompt = generator.valueToCode(
-      block,
-      "PROMPT",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const waitForCompletion =
-      block.getFieldValue("WAIT_FOR_COMPLETION") === "TRUE";
+  pythonGenerator.forBlock['ai_text_to_video'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', pythonGenerator.ORDER_ATOMIC);
+    const waitForCompletion = block.getFieldValue('WAIT_FOR_COMPLETION') === 'TRUE';
     const code = `ai_service.text_to_video(${prompt}, ${waitForCompletion})\n`;
     return code;
   };
 
   // 文本生成文本
-  pythonGenerator.forBlock["ai_text_to_text"] = function (block, generator) {
-    const prompt = generator.valueToCode(
-      block,
-      "PROMPT",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const model = block.getFieldValue("MODEL");
+  pythonGenerator.forBlock['ai_text_to_text'] = function(block, generator) {
+    const prompt = generator.valueToCode(block, 'PROMPT', pythonGenerator.ORDER_ATOMIC);
+    const model = block.getFieldValue('MODEL');
     const code = `ai_service.text_to_text(${prompt}, '${model}')`;
     return [code, pythonGenerator.ORDER_ATOMIC];
   };
 
-  // 语义识别
-  pythonGenerator.forBlock["ai_semantic_analysis"] = function (
-    block,
-    generator
-  ) {
-    const text = generator.valueToCode(
-      block,
-      "TEXT",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const type = block.getFieldValue("TYPE");
-    const code = `ai_service.semantic_analysis(${text || "''"}, '${type}')`;
-    return [code, pythonGenerator.ORDER_ATOMIC];
-  };
-
   // 智能台灯控制
-  pythonGenerator.forBlock["ai_smart_lamp"] = function (block, generator) {
-    const brightness = generator.valueToCode(
-      block,
-      "BRIGHTNESS",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const color = generator.valueToCode(
-      block,
-      "COLOR",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const code = `ai_service.control_lamp(${brightness || "0"}, ${
-      color || "'白'"
-    })`;
+  pythonGenerator.forBlock['ai_smart_lamp'] = function(block, generator) {
+    const brightness = generator.valueToCode(block, 'BRIGHTNESS', pythonGenerator.ORDER_ATOMIC);
+    const color = generator.valueToCode(block, 'COLOR', pythonGenerator.ORDER_ATOMIC);
+    const code = `ai_service.control_lamp(${brightness || '0'}, ${color || "'白'"})`;
     return code;
   };
 
   // 设置台灯亮度
-  pythonGenerator.forBlock["ai_lamp_set_brightness"] = function (
-    block,
-    generator
-  ) {
-    const brightness = generator.valueToCode(
-      block,
-      "BRIGHTNESS",
-      pythonGenerator.ORDER_ATOMIC
-    );
-    const code = `ai_service.set_lamp_brightness(${brightness || "0"})`;
+  pythonGenerator.forBlock['ai_lamp_set_brightness'] = function(block, generator) {
+    const brightness = generator.valueToCode(block, 'BRIGHTNESS', pythonGenerator.ORDER_ATOMIC);
+    const code = `ai_service.set_lamp_brightness(${brightness || '0'})`;
     return code;
   };
 
   // 设置台灯颜色
-  pythonGenerator.forBlock["ai_lamp_set_color"] = function (block, generator) {
-    const color = generator.valueToCode(
-      block,
-      "COLOR",
-      pythonGenerator.ORDER_ATOMIC
-    );
+  pythonGenerator.forBlock['ai_lamp_set_color'] = function(block, generator) {
+    const color = generator.valueToCode(block, 'COLOR', pythonGenerator.ORDER_ATOMIC);
     const code = `ai_service.set_lamp_color(${color || "'白'"})`;
     return code;
   };
@@ -1618,8 +1558,7 @@ async function runCode() {
     const resultElement = document.getElementById("run-result");
 
     // 清空之前的结果
-    resultElement.innerHTML =
-      '<div class="running-indicator">代码运行中...</div>';
+    resultElement.innerHTML = '<div class="running-indicator">代码运行中...</div>';
 
     // 保存原始console方法
     const originalConsoleLog = console.log;
@@ -1632,13 +1571,11 @@ async function runCode() {
     // 重定义console方法
     console.log = (...args) => {
       // 过滤掉包含Vue警告的日志
-      const message = args
-        .map((arg) => (typeof arg === "object" ? JSON.stringify(arg) : arg))
-        .join(" ");
+      const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : arg).join(' ');
 
       // 只显示不包含Vue warn的日志
-      if (!message.includes("[Vue warn]")) {
-        outputBuffer += '<div class="log-message">' + message + "</div>";
+      if (!message.includes('[Vue warn]')) {
+        outputBuffer += '<div class="log-message">' + message + '</div>';
         resultElement.innerHTML = outputBuffer;
       }
       originalConsoleLog.apply(console, args);
@@ -1646,13 +1583,11 @@ async function runCode() {
 
     console.error = (...args) => {
       // 过滤掉包含Vue警告的日志
-      const message = args
-        .map((arg) => (typeof arg === "object" ? JSON.stringify(arg) : arg))
-        .join(" ");
+      const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : arg).join(' ');
 
       // 只显示不包含Vue warn的日志
-      if (!message.includes("[Vue warn]")) {
-        outputBuffer += '<div class="error-message">' + message + "</div>";
+      if (!message.includes('[Vue warn]')) {
+        outputBuffer += '<div class="error-message">' + message + '</div>';
         resultElement.innerHTML = outputBuffer;
       }
       originalConsoleError.apply(console, args);
@@ -1660,13 +1595,11 @@ async function runCode() {
 
     console.warn = (...args) => {
       // 过滤掉包含Vue警告的日志
-      const message = args
-        .map((arg) => (typeof arg === "object" ? JSON.stringify(arg) : arg))
-        .join(" ");
+      const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : arg).join(' ');
 
       // 只显示不包含Vue warn的日志
-      if (!message.includes("[Vue warn]")) {
-        outputBuffer += '<div class="warn-message">' + message + "</div>";
+      if (!message.includes('[Vue warn]')) {
+        outputBuffer += '<div class="warn-message">' + message + '</div>';
         resultElement.innerHTML = outputBuffer;
       }
       originalConsoleWarn.apply(console, args);
@@ -1674,20 +1607,16 @@ async function runCode() {
 
     try {
       // 添加安全检查
-      if (
-        code.includes("eval(") ||
-        code.includes("Function(") ||
-        code.includes("document.write") ||
-        code.includes("window.location")
-      ) {
-        throw new Error("代码包含不安全的操作");
+      if (code.includes('eval(') || code.includes('Function(') ||
+          code.includes('document.write') || code.includes('window.location')) {
+        throw new Error('代码包含不安全的操作');
       }
 
       // 包装代码为异步函数执行,支持await
       const wrappedCode = `(async () => { ${code} })()`;
       await new Function(wrappedCode)();
 
-      if (outputBuffer === "") {
+      if (outputBuffer === '') {
         outputBuffer += '<div class="success-message">代码执行成功</div>';
         resultElement.innerHTML = outputBuffer;
       }
@@ -1701,26 +1630,31 @@ async function runCode() {
       console.warn = originalConsoleWarn;
     }
   } catch (err) {
-    console.error("运行代码时发生错误:", err);
-    document.getElementById(
-      "run-result"
-    ).innerHTML = `<div class="error-message">运行代码时发生错误: ${err.message}</div>`;
+    console.error('运行代码时发生错误:', err);
+    document.getElementById('run-result').innerHTML =
+        `<div class="error-message">运行代码时发生错误: ${err.message}</div>`;
   }
 }
 
 // 保存JSON
 function saveJson() {
-  const output = document.getElementById("textarea");
-  const json = Blockly.serialization.workspaces.save(state.workspace);
-  output.value = JSON.stringify(json, null, 2);
-  output.focus();
-  output.select();
-  taChange();
+  try {
+    const output = document.getElementById('textarea');
+    const json = Blockly.serialization.workspaces.save(state.workspace);
+    output.value = JSON.stringify(json, null, 2);
+    output.focus();
+    output.select();
+    taChange();
+    ElMessage.success('JSON保存成功');
+  } catch (error) {
+    console.error('保存JSON失败:', error);
+    ElMessage.error('保存JSON失败: ' + error.message);
+  }
 }
 
 // 保存XML
 function saveXml() {
-  const output = document.getElementById("textarea");
+  const output = document.getElementById('textarea');
   const xml = Blockly.Xml.workspaceToDom(state.workspace);
   output.value = Blockly.Xml.domToPrettyText(xml);
   output.focus();
@@ -1730,7 +1664,7 @@ function saveXml() {
 
 // 重新加载
 function load() {
-  const input = document.getElementById("textarea");
+  const input = document.getElementById('textarea');
   if (!input.value) return;
 
   try {
@@ -1823,15 +1757,17 @@ window.aiService = aiService;
 /* 台灯灯光样式 - 使用动态颜色 */
 .lamp-light-mask {
   position: absolute;
-  width: rpx(100);
+  width: rpx(78);
   height: rpx(350);
-  margin-top: rpx(20);
-  margin-left: rpx(250);
-  background: radial-gradient(circle, var(--lamp-color) 0%, var(--lamp-color) 50%, rgba(255, 255, 255, 0) 70%);
-  filter: blur(50px);
-  transform: rotate(25deg);
+  margin-top: rpx(148.5);
+  margin-left: rpx(192);
+  background: linear-gradient(to bottom, var(--lamp-color) 0%, var(--lamp-color) 20%, rgba(255, 255, 255, 0) 80%);
+  filter: blur(40px);
+  transform: rotate(8.5deg);
   transform-origin: top center;
   opacity: var(--lamp-opacity, 0.6);
+  /* 创建扇形效果 */
+  clip-path: polygon(0% 0%, 100% 0%, 200% 100%, -100% 100%);
 }
 
 /* 灯光信息显示 */
@@ -1980,7 +1916,7 @@ window.aiService = aiService;
     align-items: flex-start;
   }
 
-  .button-container >>> .el-button {
+  .button-container :deep(.el-button) {
     flex-shrink: 0;
   }