Browse Source

GPT工具:移除擴充套件UI 流程,調整顯示結果UI,呼叫 coreAPI - openAI 的功能

Louise lin 1 year ago
parent
commit
783eda771e

+ 4 - 99
HiTeachCC/ClientApp/src/components/Chart/OptionView.vue

@@ -77,8 +77,7 @@
         <div :title="$t('board.optionView.翻牌')" class="listicon AnswerShow" v-if="currentIRS() == 'irsImmediately'" @click="listbtn('default')"><svg-icon icon-class="flop" /></div>
         <div :title="$t('board.optionView.長條圖')" v-show="currentIRS() == 'irsImmediately'" @click="listbtn('bar')" :class="['listicon', current === 'bar' ? 'clickicon' : '']"><svg-icon icon-class="barchart" /></div>
         <div :title="$t('board.optionView.餅圖')" v-show="currentIRS() == 'irsImmediately'" @click="listbtn('pie')" :class="['listicon', current === 'pie' ? 'clickicon' : '']"><svg-icon icon-class="Piechart" /></div>
-        <div title="gpt" class="listicon" style="line-height: 28px" v-if="currentIRS() == 'irsText' && this.$store.state.currentState == 'irsTextEnd' && isAuthAccount() != 0 && isAuthGPT()&&!isAuthOnlyPureScan()" @click="triggerGPTByOpenBox()"><strong style="font-size: 12px">Gpt</strong></div>
-        <div title="gpt" class="listicon" style="line-height: 28px" v-if="currentIRS() == 'irsText' && this.$store.state.currentState == 'irsTextEnd' && isAuthAccount() != 0 && !isAuthGPT()&&!isAuthOnlyPureScan()" @click="hintInstalledGPT()"><strong style="font-size: 12px">Gpt</strong></div>
+        <div title="gpt" class="listicon" style="line-height: 28px" v-if="currentIRS() == 'irsText' && this.$store.state.currentState == 'irsTextEnd' && isAuthAccount() != 0 && isAuthOpenAIAccount()&&!isAuthOnlyPureScan()" @click="triggerGPTByOpenBox()"><strong style="font-size: 12px">Gpt</strong></div>
         <div :title="$t('board.optionView.文字雲')" class="listicon" v-if="currentIRS() == 'irsText' && this.$store.state.currentState == 'irsTextEnd' && isAuthAccount() != 0 && isAuthWordCloud()" @click="triggerWordCloud()"><svg-icon icon-class="word-cloud" /></div>
         <div :title="$t('board.optionView.貼回舞台')" class="listicon" v-if="status == 'cloud' && this.$store.state.currentState == 'irsTextEnd'" @click="requestWordCloudImg()"><svg-icon icon-class="HTPaste" /></div>
         <div :title="$t('board.optionView.統計翻牌自動結束')" v-if="status !== 'cloud' && status !== 'GPT'" class="live-switch"><i-switch :title="$t('board.optionView.統計翻牌自動結束')" v-model="autoOff" /></div>
@@ -90,8 +89,6 @@
       </div>
 
       <div class="righticon-group">
-        <div class="rightlisticon" v-if="currentIRS() == 'irsText' && status == 'GPT' && !boardElement.isWaitingGptFeedbackDone" @click="continueGpt()"><svg-icon icon-class="continue" /></div>
-        <div class="rightlisticon" v-if="currentIRS() == 'irsText' && status == 'GPT' && boardElement.isWaitingGptFeedbackDone" @click="stopGpt()"><svg-icon icon-class="stop" class="stop-icon" /></div>
         <div class="rightlisticon" :title="$t('board.optionView.匿名')" v-if="currentIRS() == 'irsText' && status !== 'cloud' && status !== 'GPT'" @click="hideName"><svg-icon :icon-class="this.$store.state.hideStudentName == false ? 'eye-show' : 'eye-hide'" /></div>
         <div class="rightlisticon" :title="$t('board.optionView.複製到剪貼簿')" v-if="currentIRS() == 'irsText' && status == 'GPT'" @click="copyGPTAnsToClipboard()"><svg-icon icon-class="copy" /></div>
         <div class="rightlisticon" :title="$t('board.optionView.複製到剪貼簿')" v-if="currentIRS() == 'irsText' && status == 'text'" @click="copyToClipboard()"><svg-icon icon-class="copy" /></div>
@@ -569,11 +566,7 @@ export default {
           let wordItemIndex = that.wordCloudFreq.findIndex((item) => item.name == e.data.word);
           that.$q.loading.hide();
           that.showWordCloudTableSmartPickBtn(that.wordCloudFreq[wordItemIndex], clientEvent);
-        } else if (e.data?.action == "GPT_done") {
-          that.$parent.$parent.$parent.isWaitingGptFeedbackDone = false;
-        } else if (e.data?.action == "GPT_error") {
-          that.$parent.$parent.$parent.isWaitingGptFeedbackDone = false;
-        }
+        } 
       };
 
       window.addEventListener("resize", () => {
@@ -662,8 +655,8 @@ export default {
     },
   },
   methods: {
-    isAuthGPT() {
-      return this.$parent.$parent.$parent.checkGptExtensionInstalled;
+    isAuthOpenAIAccount() { //改介接OpenAI的權益
+      return this.$parent.$parent.$parent.isAuthOpenAIAccount();
     },
     isAuthWordCloud() {
       return this.$parent.$parent.$parent.isAuthWordCloud();
@@ -1414,37 +1407,6 @@ export default {
       });
       return optionLength;
     },
-    hintInstalledGPT() {
-      this.$parent.$parent.$parent.showHintGptInstalled = true;
-    },
-    continueGpt() {
-      let board = this.$parent.$parent.$parent;
-      if (!board.isWaitingGptFeedbackDone) {
-        setTimeout(() => {
-          window.postMessage({
-            action: "ContinueGPT",
-            id: "IRSChatGptBox",
-            parentLang: board.lang,
-            question: this.$t('gptBox["繼續"]'),
-          });
-          board.isWaitingGptFeedbackDone = true;
-        }, 1000);
-      } else {
-        this.$Message.info(this.$t('gptBox["等候提示字"]'));
-      }
-    },
-    stopGpt() {
-      let board = this.$parent.$parent.$parent;
-      if (board.isWaitingGptFeedbackDone) {
-        window.postMessage({
-          action: "StopGPT",
-          id: "IRSChatGptBox",
-          parentLang: board.lang,
-          question: "",
-        });
-        board.isWaitingGptFeedbackDone = false;
-      }
-    },
     triggerGPTByOpenBox() {
       this.$store.state.mqtt.mqttIoTData.isGpt=1
       this.$store.dispatch('mqtt/saveMqttIoTsessionStorage')
@@ -1461,63 +1423,6 @@ export default {
       this.$parent.$parent.$parent.showGptBox = true
 
     },
-    // triggerGPTBySelect() {
-    //   if (this.currentSelectedGptAct == "") this.currentSelectedGptAct = this.gptActionList[0].value;
-    //   let that = this;
-    //   if (!this.$parent.$parent.$parent.isWaitingGptFeedbackDone) {
-    //     this.current = "GPT";
-    //     this.status = "GPT";
-    //     let allText = "";
-    //     this.student.forEach((stu) => {
-    //       allText = allText + stu.statement;
-    //     });
-    //     setTimeout(() => {
-    //       window.postMessage({
-    //         parentLang: that.lang,
-    //         action: "triggerGPT",
-    //         id: "IRSChatGptBox",
-    //         question: that.$t('gptBox["當前語系指令"]')+that.currentSelectedGptAct + "\n" + allText,
-    //       });
-    //     }, 500);
-
-    //     this.$parent.$parent.$parent.isWaitingGptFeedbackDone = true;
-    //   } else {
-    //     this.$Message.info(this.$t("gptBox['等候提示字']"));
-    //   }
-    // },
-    // triggerGPT() {
-    //   console.log(this.gptActionList, "this.gptActionList");
-    //   if (this.currentSelectedGptAct == "") this.currentSelectedGptAct = this.gptActionList[0].value;
-    //   let that = this;
-    //   if (!this.$parent.$parent.$parent.isWaitingGptFeedbackDone) {
-    //     if (this.current === "GPT") {
-    //       this.current = "";
-    //       this.status = "default";
-    //     } else {
-    //       this.current = "GPT";
-    //       this.status = "GPT";
-    //       let allText = "";
-    //       this.student.forEach((stu) => {
-    //         if (stu.statement != "") {
-    //           allText = allText + stu.statement + ",";
-    //         }
-    //       });
-    //       setTimeout(() => {
-    //         window.postMessage({
-    //           parentLang: that.lang,
-    //           action: "triggerGPT",
-    //           id: "IRSChatGptBox",
-    //           question: that.$t('gptBox["當前語系指令"]')+that.currentSelectedGptAct + "\n" + allText,
-    //         });
-    //       }, 500);
-    //       this.$parent.$parent.$parent.isWaitingGptFeedbackDone = true;
-    //     }
-    //   } else {
-    //     this.$Message.info(this.$t("gptBox['等候提示字']"));
-    //     this.current = "GPT";
-    //     this.status = "GPT";
-    //   }
-    // },
     triggerWordCloud() {
       let that = this;
       if (this.current === "cloud") {

+ 48 - 50
HiTeachCC/ClientApp/src/components/GptBox.vue

@@ -12,9 +12,6 @@
     </div>
 
     <div class="gptBox-card" v-show="!showConfirmDeleteSet">
-      <!-- <div class="close-btn" v-show="!showEditActionsView&&!$parent.isWaitingGptFeedbackDone" @click="closeGptBox()">
-        <svg-icon icon-class="Close" class="close-icon" />
-      </div> -->
       <div class="close-btn" v-show="!showEditActionsView" @click="smallGptBox()">
         <svg-icon class="hideIRSArrow-icon" icon-class="hideIRSArrow" />
       </div>
@@ -55,13 +52,15 @@
         </div>
 
 
-        <div class="gptBox-right" id="GptToolBox"></div>
-        <div class="gptbtn-group">
-          <div class="stop-btn" v-show="$parent.isWaitingGptFeedbackDone" @click="stopGpt()" style="cursor: pointer">
-            <svg-icon icon-class="stop" />
+        <div class="gptBox-right" id="GptToolBox">
+          <div v-show="$parent.isWaitingGptFeedbackDone" style="text-align:center">
+              <img src='/loading2.gif' />
           </div>
-          <div class="continue-btn" v-show="!$parent.isWaitingGptFeedbackDone" @click="continueGpt()"
-            style="cursor: pointer"><svg-icon icon-class="continue" /></div>
+          <div v-show="!$parent.isWaitingGptFeedbackDone" style="text-align: left;">
+            {{ currentGPTAns }}
+          </div>  
+        </div>
+        <div class="gptbtn-group">
           <div class="copy-btn" @click="copyGPTAnsToClipboard()"><svg-icon icon-class="copy" /></div>
         </div>
       </div>
@@ -142,14 +141,13 @@ export default {
       }
       ],
       showEditActionsView: false,
-      currentGPTques: "",
       showConfirmDeleteSet: false,
       currentAddcount: 0,
       currentEditPromptIndex: 0,
       refreshkey: 0,
       currentUseSetId: "",
-      currentSetName:''
-
+      currentSetName:'',
+      currentGPTAns:'',
     };
   },
   computed: {
@@ -196,46 +194,46 @@ export default {
     closeGptBox() {
       this.$parent.showGptBox = false;
     },
-    stopGpt() {
-      if (this.$parent.isWaitingGptFeedbackDone) {
-        window.postMessage({
-          action: "StopGPT",
-          id: "GptToolBox",
-          parentLang: this.$parent.lang,
-          question: "",
-        });
-        this.$parent.isWaitingGptFeedbackDone = false;
-      }
-    },
-    continueGpt() {
-      if (!this.$parent.isWaitingGptFeedbackDone) {
-        setTimeout(() => {
-          window.postMessage({
-            action: "ContinueGPT",
-            id: "GptToolBox",
-            parentLang: this.$parent.lang,
-            question: this.$t('gptBox["繼續"]'),
-          });
-          this.$parent.isWaitingGptFeedbackDone = true;
-        }, 1000);
-      } else {
-        this.$Message.info(this.$t('gptBox["等候提示字"]'));
+    async triggerOpenAI(question){
+      let that=this
+      that.currentGPTAns = ''
+      try {
+      const idToken = sessionStorage.getItem("idToken");
+      const task = await this.$api.coreApi.createAITask(idToken, question);
+      const taskId = task?.taskId;
+
+      let tryCount = 0;  // 初始化重試次數
+      if(taskId) {
+        const checkCompletionText = async () => {
+          const result = await this.$api.coreApi.getAITaskResult(idToken, taskId);
+
+          if (result.hasOwnProperty('completionText')) {
+            that.currentGPTAns = result.completionText;
+            that.$parent.isWaitingGptFeedbackDone = false;
+          } else if (tryCount < 3) {
+            tryCount++;
+            setTimeout(checkCompletionText, 3000);  // 等待 3 秒後再次檢查
+          } else {
+            that.currentGPTAns = this.$t('gptBox["emptyReply"]');
+            that.$parent.isWaitingGptFeedbackDone = false;
+          }
+        };
+
+        setTimeout(checkCompletionText, 3000);  // 初始等待 3 秒後檢查
       }
-    },
-    triggerGPT(actItem) {
-      if (!this.$parent.isWaitingGptFeedbackDone) {
-        window.postMessage({
-          action: "triggerGPT",
-          id: "GptToolBox",
-          parentLang: this.$parent.lang,
-          question: this.$t('gptBox["當前語系指令"]') + `${actItem}\n` + this.currentText,
-        });
-        this.$parent.isWaitingGptFeedbackDone = true;
-        this.currentGPTques = `${actItem}\n` + this.currentText;
-      } else {
-        this.$Message.info(this.$t('gptBox["等候提示字"]'));
+      } catch (error) {
+        console.error("An error occurred:", error);
       }
     },
+      triggerGPT(actItem) {
+        if (!this.$parent.isWaitingGptFeedbackDone) {
+          let question= this.$t('gptBox["當前語系指令"]') + `${actItem}\n` + this.currentText
+          this.triggerOpenAI(question)
+          this.$parent.isWaitingGptFeedbackDone = true;
+        } else {
+          this.$Message.info(this.$t('gptBox["等候提示字"]'));
+        }
+      },
     copyGPTAnsToClipboard() {
       // Create an auxiliary hidden input
       var aux = document.createElement("textarea");
@@ -399,7 +397,7 @@ export default {
           }
 
         })
-      console.log(counthaveContent)
+      // console.log(counthaveContent)
       return counthaveContent == 0
     }
   },

+ 3 - 2
HiTeachCC/ClientApp/src/locale/lang/en-US/index.js

@@ -407,7 +407,7 @@ export default {
     範例名單:`John, 1\nLouise, 2\nGeorge, 3\n`
   },
   gptBox:{
-    Gpt工具:'GPT Tool Box (Connecting your ChatGPT)',
+    Gpt工具:'GPT Tool Box',
     管理指令:'Manage Prompt',
     常用指令:'Commonly used Prompt',
     可輸入一段100字以內的指令:'You can enter a prompt within 100 characters...',
@@ -424,6 +424,7 @@ export default {
     刪除:'Delete',
     新增分類:"Add new category ",
     已達最大上限10個分類:"Maximum limit of 10 categories has been reached",
-    暫無數據:"No prompt"
+    暫無數據:"No prompt",
+    emptyReply:"The GPT response content is empty, please try again!"
   }
 }

+ 3 - 2
HiTeachCC/ClientApp/src/locale/lang/zh-CN/index.js

@@ -380,7 +380,7 @@ export default {
     範例名單: `王大明, 1\n张小凡, 2\n陈士轩, 3\n`
    },
   gptBox:{
-    Gpt工具:'Gpt工具',
+    Gpt工具:'Gpt工具',
     管理指令:'管理指令',
     常用指令:'常用指令',
     可輸入一段100字以內的指令:'可输入一段100字以内的指令...',
@@ -397,6 +397,7 @@ export default {
     刪除:'删除',
     新增分類:"新增分类",
     已達最大上限10個分類:"已达最大上限10个分类",
-    暫無數據:"暂无咒语"
+    暫無數據:"暂无咒语",
+    emptyReply:"GPT回应内容为空,请再试一次!"
   }
 }

+ 3 - 2
HiTeachCC/ClientApp/src/locale/lang/zh-TW/index.js

@@ -408,7 +408,7 @@ export default {
     範例名單:`王大明, 1\n張小凡, 2\n陳士軒, 3\n`
   },
   gptBox:{
-    Gpt工具:'GPT工具箱(連接您的ChatGPT)',
+    Gpt工具:'GPT工具箱',
     管理指令:'管理指令',
     常用指令:'常用指令',
     可輸入一段100字以內的指令:'可輸入一段100字以內的指令...',
@@ -425,6 +425,7 @@ export default {
     刪除:'刪除',
     新增分類:"新增分類",
     已達最大上限10個分類:"已達最大上限10個分類",
-    暫無數據:"暫無指令資料"
+    暫無數據:"暫無指令資料",
+    emptyReply:"GPT回應內容為空,請再試一次!"
   }
 }

+ 10 - 60
HiTeachCC/ClientApp/src/views/Board.vue

@@ -1,22 +1,5 @@
 <template>
   <div class="board">
-    <!--OpenAI測試-->
-    <div @click="triggerOpenAI()" style="z-index: 2000; color: red; position: fixed; top: 10px; left: 10px">
-      OpenAI測試
-    </div>
-    <!--Gpt安裝提示訊息-->
-    <div v-show='showHintGptInstalled' class="textinput-view">>
-      <div class="textinput-card">
-        <p>{{ $t("board['Gpt安裝提示標題']") }}</p>
-        <br>
-        <div v-html="$t('board.GPT安裝提示字')" />
-        <br>
-        <div class="textinputbtn-group">
-          <div class="textinput-btn" @click="openPluginPage()">{{ $t("board['前往']")}}</div>
-          <div class="textinput-btn" @click="showHintGptInstalled=false">{{ $t("board['取消']") }}</div>
-        </div>
-      </div>
-    </div>
     <!--清空畫面提示訊息-->
     <div v-show='showCanvasClearDangerHint' class="textinput-view">>
       <div class="textinput-card">
@@ -223,7 +206,7 @@
       <div class="board-right">
         <div class="boardArea">
 
-        <div id="gpt-drag" @click="dragElement('gpt-drag')" v-drag  v-show="checkGptExtensionInstalled&&!showGptBox&&$refs.gptBox.currentText!=''" > 
+        <div id="gpt-drag" @click="dragElement('gpt-drag')" v-drag  v-show="canShowGptDragBall&&!showGptBox&&$refs.gptBox.currentText!=''" > 
           <div  class='gpt-smallbtn'  @click="showGptBox=true">Gpt</div> 
         </div>
 
@@ -473,8 +456,7 @@
       <p @click="toImageByObjMenu()">{{ $t("board.objMenu.將物件複製為圖片到剪貼簿") }}</p>
       <p @click="toTextByObjMenu()" v-show="showObjMenuTextCopyOption">{{ $t("board.objMenu.將物件複製為文字到剪貼簿") }}</p>
       <p @click="sendTextToIRSByObjMenu()" v-show="showObjMenuTextCopyOption">{{ $t("board.objMenu.發送文字") }}</p>
-      <p @click="openGptBox()" v-show="showObjMenuTextCopyOption&&checkGptExtensionInstalled&&isAuthAccount()!=0&&!isAuthOnlyPureScan()">{{$t('gptBox["Gpt工具"]')}}</p>
-      <p @click="showHintGptInstalled=true" v-show="showObjMenuTextCopyOption&&!checkGptExtensionInstalled&&isAuthAccount()!=0&&!isAuthOnlyPureScan()">{{$t('gptBox["Gpt工具"]')}}</p>
+      <p @click="openGptBox()" v-show="showObjMenuTextCopyOption&&isAuthOpenAIAccount()">{{$t('gptBox["Gpt工具"]')}}</p>
     </div>
     <div class="obj-menu" v-show="showRightClickMenu"  :style="{ left: rightClickMenuPos.x + 'px', top: rightClickMenuPos.y + 'px' }">
       <p @click="pasteFromClipboard()">{{ $t("board.rightClickMenu.從剪貼簿貼上") }}</p>
@@ -809,18 +791,17 @@ export default {
       customMemberlist: [], //最後存到偏好設定的自訂名單,
       currentTA:'',
       showGptBox:false,
-      checkGptExtensionInstalled:false,
-      isWaitingGptFeedbackDone:false,
       startUseGptTool:false,
       showCanvasClearDangerHint:false,
       showWorksClearDangerHint:false,
-      showHintGptInstalled:false,
       showRightClickMenu:false,
       rightClickMenuPos: { x: 0, y: 0 },
       //使用IES5過來的名單
       showIES5studentListBtn:false, //ies5重啟要秀這個來源
       isUseIES5studentList:false, //ies5重啟要秀這個來源
       isEditMemberListAtInit:false,
+      canShowGptDragBall:false,
+      isWaitingGptFeedbackDone:false,
     };
   },
   methods: {
@@ -7063,6 +7044,9 @@ export default {
       console.log(type,'AuthType',this.$store.state.loginType)
       return type;
     },
+    isAuthOpenAIAccount(){
+      return true
+    },
     setMQTTIoTAuthType() {
       this.$store.state.mqtt.mqttIoTData.authType = this.isAuthAccount();
       // console.log(this.getFunc('works').get===null,this.getFunc('clients').get===null,this.getFunc('pageqty').get===null)
@@ -7452,25 +7436,6 @@ export default {
       this.$refs.addImgBox.pasteFromClipboard()
       this.showRightClickMenu=false
     },
-    async triggerOpenAI(){
-      try {
-      const idToken = sessionStorage.getItem("idToken");
-      const task = await this.$api.coreApi.createAITask(idToken, "測試CC");
-      const taskId = task?.taskId;
-
-      if (taskId) {
-        setTimeout(async () => {
-          const result = await this.$api.coreApi.getAITaskResult(idToken, taskId);
-          console.log(task, result, "triggerOpenAI");
-        }, 2000);
-        
-      } else {
-        console.error("Task creation failed, taskId is undefined");
-      }
-      } catch (error) {
-        console.error("An error occurred:", error);
-      }
-      } 
   },
 
   created() {
@@ -7518,12 +7483,10 @@ export default {
     }
    
   },
-
   async mounted() {
-    setTimeout(()=>{
-    const checkGptExtensionInstalled=document.getElementById('Habook_ChatGptExt_Installed')
-    if(checkGptExtensionInstalled) this.checkGptExtensionInstalled=true
-    },3000)
+    setTimeout(() => {
+      this.canShowGptDragBall = true
+    }, 3000);
     // 連線MQTT
     this.$store.dispatch("mqtt/connect");
 
@@ -7786,19 +7749,6 @@ export default {
     }
     // this.CreateGroup();
 
-     //對GPT回應的監聽邏輯=>物件次選單, optionView
-    window.onmessage = function (e) {
-      let ccorigin=window.location.origin
-      console.log(e.data)
-      if (e.origin !== ccorigin) return
-      if (e.data?.action == 'GPT_done') {
-        that.isWaitingGptFeedbackDone=false
-      }
-      else if(e.data?.action == 'GPT_error'){
-         that.isWaitingGptFeedbackDone=false
-      }
-    }
-
     window.onresize = () => {
       // 全屏下监控是否按键了ESC
       if (!this.checkFull()) {