15 Commits 3fa30f5780 ... d81a24a627

Author SHA1 Message Date
  lsc d81a24a627 Merge branch 'beta' 1 month ago
  lsc 8efb8e8c4f update 1 month ago
  lsc 942962ea93 update 1 month ago
  SanHQin 7e01475914 更新 1 month ago
  SanHQin 5bcfc2251c Merge branch 'beta' of https://git.cocorobo.cn/CocoRoboLabs/pbl-teacher-table into beta 1 month ago
  SanHQin bbe9c6cf0b 1 1 month ago
  lsc 3be7c5b7f4 Merge branch 'beta' of https://git.cocorobo.cn/CocoRoboLabs/pbl-teacher-table into beta 1 month ago
  lsc a991c5dda2 update 1 month ago
  11wqe1 36fb2870b0 导出学生报告 1 month ago
  11wqe1 853ce69e79 # 1 month ago
  lsc fc682d593c update 1 month ago
  lsc c8b5ec6695 update 1 month ago
  11wqe1 363a00863a # 1 month ago
  11wqe1 33be1bfd6a # 1 month ago
  11wqe1 37801c2000 # 1 month ago
33 changed files with 2371 additions and 1141 deletions
  1. 1 1
      dist/index.html
  2. 0 0
      dist/static/css/app.309d5348d2cc3da1921d07183fc363d0.css
  3. 0 0
      dist/static/css/app.309d5348d2cc3da1921d07183fc363d0.css.map
  4. 0 0
      dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css
  5. 0 0
      dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css.map
  6. 0 0
      dist/static/js/app.416b004d7e6511edb5bd.js
  7. 0 0
      dist/static/js/app.416b004d7e6511edb5bd.js.map
  8. 0 0
      dist/static/js/manifest.571c38d63f24b1ae9e16.js.map
  9. 0 8
      src/App.vue
  10. 1 0
      src/assets/icon/classroomObservation/echartIcon.svg
  11. BIN
      src/assets/icon/classroomObservation/recordLeft.png
  12. BIN
      src/assets/icon/classroomObservation/wordBg2.png
  13. BIN
      src/assets/icon/course/pasete.png
  14. 135 32
      src/components/pages/aiAddCourse/addCourse.vue
  15. 119 24
      src/components/pages/aiAddCourse/aiBoxRight.vue
  16. 15 3
      src/components/pages/aiAddCourse/aiCreateVideoDialog.vue
  17. 633 0
      src/components/pages/aiAddCourse/aiCreateVideoDialogHK.vue
  18. 50 14
      src/components/pages/classroomObservation/components/addNewAnalysisDialog.vue
  19. 204 45
      src/components/pages/classroomObservation/components/addNewTeacherVoiceprintDialog.vue
  20. 3 1
      src/components/pages/classroomObservation/components/analysis.vue
  21. 37 1
      src/components/pages/classroomObservation/components/analysisItem.vue
  22. 3 1
      src/components/pages/classroomObservation/components/analysisSpecialItem.vue
  23. 0 46
      src/components/pages/classroomObservation/components/analysisTemplateDialog.vue
  24. 1 1
      src/components/pages/classroomObservation/components/chatArea.vue
  25. 215 182
      src/components/pages/classroomObservation/components/messageArea.vue
  26. 17 9
      src/components/pages/classroomObservation/components/saveTemplateDialog.vue
  27. 781 724
      src/components/pages/classroomObservation/index.vue
  28. 115 39
      src/components/pages/components/exportDataDialog.vue
  29. 3 1
      src/components/pages/components/exportWorksDialog.vue
  30. 1 1
      src/components/pages/components/studentWorksDetail.vue
  31. 22 4
      src/components/pages/components/worksDetail2.vue
  32. 1 1
      src/components/pages/components/worksDetail3.vue
  33. 14 3
      src/components/pages/works.vue

+ 1 - 1
dist/index.html

@@ -32,7 +32,7 @@
       width: 100%;
       background: #e6eaf0;
       font-family: '黑体';
-    }</style><link href=./static/css/app.eca8c790dce1209ec8667c6b5b52d134.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.571c38d63f24b1ae9e16.js></script><script type=text/javascript src=./static/js/vendor.a82b79982b082928b294.js></script><script type=text/javascript src=./static/js/app.ddad82df5f4e10f122b5.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.309d5348d2cc3da1921d07183fc363d0.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.571c38d63f24b1ae9e16.js></script><script type=text/javascript src=./static/js/vendor.a82b79982b082928b294.js></script><script type=text/javascript src=./static/js/app.416b004d7e6511edb5bd.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.309d5348d2cc3da1921d07183fc363d0.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.309d5348d2cc3da1921d07183fc363d0.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.eca8c790dce1209ec8667c6b5b52d134.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.416b004d7e6511edb5bd.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.416b004d7e6511edb5bd.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/manifest.571c38d63f24b1ae9e16.js.map


+ 0 - 8
src/App.vue

@@ -517,12 +517,4 @@ html::-webkit-scrollbar-thumb {
   display: flex;
   justify-content: flex-end;
 }
-
-.el-message-box__wrapper{
-  z-index: 9999999 !important;
-}
-.el-message-box__wrapper + .v-modal{
-  z-index: 9999998 !important;
-
-}
 </style>

+ 1 - 0
src/assets/icon/classroomObservation/echartIcon.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726640886428" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4312" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M63.5 145v735.3h895.7V145H63.5z m863.7 127.9v127.9H703.3V272.9h223.9zM383.4 496.7h287.9v127.9H383.4V496.7z m-32 127.9H95.5V496.7h255.9v127.9z m351.9-127.9h223.9v127.9H703.3V496.7z m-32-223.8v127.9H383.4V272.9h287.9z m-319.9 0v127.9H95.5V272.9h255.9zM95.5 848.4V720.5h255.9v127.9H95.5z m287.9 0V720.5h287.9v127.9H383.4z m319.9 0V720.5h223.9v127.9H703.3z" p-id="4313"></path></svg>

BIN
src/assets/icon/classroomObservation/recordLeft.png


BIN
src/assets/icon/classroomObservation/wordBg2.png


BIN
src/assets/icon/course/pasete.png


+ 135 - 32
src/components/pages/aiAddCourse/addCourse.vue

@@ -1,8 +1,8 @@
 <template>
-  <div class="pb_content" style="background: #f0f2f5" v-loading="loading" element-loading-text="小可正在努力生成中,请稍等...">
+  <div class="pb_content" style="background: #f0f2f5;overflow: hidden;" v-loading="loading" element-loading-text="小可正在努力生成中,请稍等...">
     <div class="c_pub_button_confirm stopBtn" v-if="loading && isOutlineCancelToken" @click="cancelAjax('outline')">停止</div>
     <div class="c_pub_button_confirm stopBtn" v-if="loading && isTeacherTaskCancelToken" @click="cancelAjax('teacherTask')">停止</div>
-    <div class="pb_content_body" style="position: relative; margin: 0">
+    <div class="pb_content_body" style="position: relative; margin: 0;overflow: hidden;">
       <div class="right" :style="{width:istemplate == 1 ? 'calc(100% - 300px)' : '100%'}">
         <div class="courseTop">
           <div class="stepsNav">
@@ -198,7 +198,7 @@
                           <span>生成模式:</span>
                           <el-radio-group v-model="isuseT" style="display: flex; align-items: center" @change="changeIsuseT">
                             <div class="all_choose info_radio">
-                              <el-radio :label="1">引导模式生成</el-radio>
+                              <el-radio :label="1">对话模式生成</el-radio>
                             </div>
                             <div class="all_choose info_radio" style="margin-left: 10px">
                               <el-radio :label="true">从已有教案生成</el-radio>
@@ -5141,7 +5141,7 @@
                               ">
                               <div class="lineTitle clineTitle">评价设置</div>
                               <div style="margin-left:auto;display: flex;">
-                                <el-tooltip effect="light" content="右键单击可配置提示词" placement="bottom">
+                                <el-tooltip effect="light" content="右键单击可配置提示词" placement="bottom" v-if="itemTask.eList && itemTask.eList.length">
                                   <div class="r_pub_button_op"
                                     @contextmenu.prevent="openAiDialog(1, 'aiRateRuleA', itemTaskIndex)"
                                     @click="openAiDialog(2, 'aiRateRuleA', itemTaskIndex)">一键生成评价细则</div>
@@ -8440,6 +8440,22 @@ export default {
       }
       this.$refs.stepBox.scrollTop = 0;
     },
+    setTipsIndex(){
+      // 使用 setTimeout 确保对话框已经渲染完成
+      this.$nextTick(() => {
+        const dialog = document.querySelector('.custom-confirm-box');
+        if (dialog) {
+          const parent = dialog.parentElement;
+          if (parent) {
+            parent.style.zIndex = 9999999;
+            const adjacentElement = parent.nextElementSibling;
+            if (adjacentElement) {
+              adjacentElement.style.zIndex = 9999998;
+            }
+          }
+        }
+      });
+    },
     nextSteps(clickType, ttype) {
       if(!this.time()){
         return
@@ -8591,7 +8607,8 @@ export default {
                 confirmButtonText: "确定",
                 cancelButtonText: "取消",
                 distinguishCancelAndClose: true,
-                type: "warning"
+                type: "warning",
+                customClass: 'custom-confirm-box'
               })
                 .then(() => {
                   if(this.isTeacherTaskCancelToken2){
@@ -8621,6 +8638,9 @@ export default {
               }).catch((v) => {
                 console.log(v);
               })
+              setTimeout(() => {
+                this.setTipsIndex()
+              }, 500)
             }
             return;
           }
@@ -11233,11 +11253,45 @@ export default {
         let _file = this.knowFileArray[fi]
         let fileM = _file.grade ? converter(_file.grade).split('/') : 1
         let fileS = _file.name ? converter(_file.name).split('/') : 1
-        let _sub = fileS == 1 ? [1] : this.arrayToArray(fileS, sub)
-        let _mclass = fileM == 1 ? [1] : this.arrayToArray(fileM, mclass)
+        let _sub = fileS == 1 ? [] : this.arrayToArray(fileS, sub)
+        let _mclass = fileM == 1 ? [] : mclass.length ? this.arrayToArray(fileM, mclass) : [2]
         let fileids = this.knowInfoData.map((item) => item.fileid)
 
-        if(_sub.length > 0 && _mclass.length > 0 && fileids.indexOf(_file.fileid) == -1){
+        if(_sub.length > 0 && _mclass.length > 0 && _mclass[0] == 2 && fileids.indexOf(_file.fileid) == -1){
+          this.knowInfoData.push({
+            name: _file.filename,
+            url: _file.url,
+            uid: '',
+            type: 3,
+            fileid: _file.fileid,
+          });
+          this.knowFileids.push(_file.fileid)
+        }
+        fileids = this.knowInfoData.map((item) => item.fileid)
+        if(_mclass.length > 0 && fileS == 1 && _mclass[0] != 2 && fileids.indexOf(_file.fileid) == -1){
+          this.knowInfoData.push({
+            name: _file.filename,
+            url: _file.url,
+            uid: '',
+            type: 3,
+            fileid: _file.fileid,
+          });
+          this.knowFileids.push(_file.fileid)
+        }
+        fileids = this.knowInfoData.map((item) => item.fileid)
+        if(_sub.length > 0 && fileM == 1 && fileids.indexOf(_file.fileid) == -1){
+          this.knowInfoData.push({
+            name: _file.filename,
+            url: _file.url,
+            uid: '',
+            type: 3,
+            fileid: _file.fileid,
+          });
+          this.knowFileids.push(_file.fileid)
+        }
+        fileids = this.knowInfoData.map((item) => item.fileid)
+
+        if(_sub.length > 0 && _mclass.length > 0 && _mclass[0] != 2 && fileids.indexOf(_file.fileid) == -1){
           this.knowInfoData.push({
             name: _file.filename,
             url: _file.url,
@@ -11862,6 +11916,8 @@ export default {
             targetCourseText2: this.targetCourseText2,
             chatid: this.chatid,
             languageSetting: this.languageSetting,
+            knowInfoData: this.knowInfoData,
+            knowFileids: this.knowFileids,
           }),
           iresearch: this.isFileSearch ? 1 : 2,
         },
@@ -12135,6 +12191,8 @@ export default {
             targetCourseText2: this.targetCourseText2,
             chatid: this.chatid,
             languageSetting: this.languageSetting,
+            knowInfoData: this.knowInfoData,
+            knowFileids: this.knowFileids,
           }),
           iresearch: this.isFileSearch ? 1 : 2,
         },
@@ -14265,6 +14323,8 @@ export default {
                 this.targetCourseText2 = JSON.parse(res.data[0][0].setting).targetCourseText2 ? JSON.parse(res.data[0][0].setting).targetCourseText2 : '';
                 this.chatid = JSON.parse(res.data[0][0].setting).chatid ? JSON.parse(res.data[0][0].setting).chatid : uuidv4();
                 this.languageSetting = (JSON.parse(res.data[0][0].setting).languageSetting || JSON.parse(res.data[0][0].setting).languageSetting == 0) ? JSON.parse(res.data[0][0].setting).languageSetting : 0;
+                this.knowInfoData = (JSON.parse(res.data[0][0].setting).knowInfoData) ? JSON.parse(res.data[0][0].setting).knowInfoData : [];
+                this.knowFileids = (JSON.parse(res.data[0][0].setting).knowFileids) ? JSON.parse(res.data[0][0].setting).knowFileids : [];
                 if(this.targetCourseText2 || (!this.teacherCourseText)){
                   this.courseTextBool = true
                 }
@@ -14415,6 +14475,8 @@ export default {
                 this.targetCourseText2 = JSON.parse(res.data[0][0].setting).targetCourseText2 ? JSON.parse(res.data[0][0].setting).targetCourseText2 : '';
                 this.chatid = JSON.parse(res.data[0][0].setting).chatid ? JSON.parse(res.data[0][0].setting).chatid : uuidv4();
                 this.languageSetting = (JSON.parse(res.data[0][0].setting).languageSetting || JSON.parse(res.data[0][0].setting).languageSetting == 0) ? JSON.parse(res.data[0][0].setting).languageSetting : 0;
+                this.knowInfoData = (JSON.parse(res.data[0][0].setting).knowInfoData) ? JSON.parse(res.data[0][0].setting).knowInfoData : [];
+                this.knowFileids = (JSON.parse(res.data[0][0].setting).knowFileids) ? JSON.parse(res.data[0][0].setting).knowFileids : [];
                 if(this.targetCourseText2 || (!this.teacherCourseText)){
                   this.courseTextBool = true
                 }
@@ -16534,12 +16596,23 @@ export default {
         this.$message.error("请补充填写课程名称");
         return;
       }
-      this.openAiDialog(2, 'aiDetail',1)
+      let functionA = ''
       if(this.templateid != '4480d65a-1e48-11ef-bee5-005056b86db5' && this.templateid != 'cf5722a4-401b-11ef-b873-005056b86dc3'){
-        setTimeout(() => {
+        // setTimeout(() => {
           // this.openAiDialog(2, 'aitargetTextDetail2',1)
+        //   this.openAiDialog(2, 'aitargetTextDetail3',1)
+        // }, 500);
+        functionA = ()=>{
           this.openAiDialog(2, 'aitargetTextDetail3',1)
-        }, 500);
+        }
+      }
+
+      this.openAiDialog(2, 'aiDetail',1, functionA)
+      if(this.templateid != '4480d65a-1e48-11ef-bee5-005056b86db5' && this.templateid != 'cf5722a4-401b-11ef-b873-005056b86dc3'){
+        // setTimeout(() => {
+          // this.openAiDialog(2, 'aitargetTextDetail2',1)
+        //   this.openAiDialog(2, 'aitargetTextDetail3',1)
+        // }, 500);
       }
 
       this.courseTextBool = true
@@ -16660,7 +16733,7 @@ export default {
         this.aitype = "aiDetail"
         // this.aiText = `请根据${this.courseText}设计一个名为${this.courseName}的${sub.length ? sub.join(",") + "学科的" : ""},面向${this.getListClassC(this.checkboxList2)}的项目式学习课程。`
         this.aiText = this.aiJson.aiDetail
-        this.aiCallBack = callback
+        this.aiCallBack = [callback, index]
       } else if (type == "aiOutline") {
         this.aitype = "aiOutline"
         // this.aiText = `请根据${this.courseText}设计一个名为${this.courseName}的${sub.length ? sub.join(",") + "学科的" : ""},面向${this.getListClassC(this.checkboxList2)}的项目式学习课程设计序列教学活动(需要每个任务都需要至少50个token的详细描述),每个教学活动的活动设计(可以直接使用文件内容)以及每个教学活动的评价量规(学生能做到...)。`
@@ -16834,6 +16907,7 @@ export default {
             cancelButtonText: "取消",
             distinguishCancelAndClose: true,
             type: "warning",
+            customClass: 'custom-confirm-box'
           })
             .then(() => {
 
@@ -16856,6 +16930,9 @@ export default {
           }).catch((v) => {
             console.log(v);
           })
+          setTimeout(() => {
+            this.setTipsIndex()
+          }, 500)
           return;
         }else {
           this.aitype = "teacherDetail2"
@@ -16953,6 +17030,10 @@ export default {
           });
           return;
         }
+        if(!this.courseText){
+          this.$message.error("请生成简要描述后再生成目标");
+          return;
+        }
         this.aitype = type
         this.aiText = this.aiJson.aiTargetGet
         this.aiText2 = this.aiJson.aiTarget2
@@ -17670,16 +17751,14 @@ ${sub.length ? '学科:' + sub.join(",") : ''}
 ${mclass.length ? '面向年级:' + mclass.join(",") : ''}
 ${(this.mode == 1 && (!this.yiKeTemplateArray.includes(this.templateid)) && this.teacherCourseText) ? '提取教案摘要:'+this.teacherCourseText : ''}
 ${(this.mode == 1 && (!this.yiKeTemplateArray.includes(this.templateid)) && target) ? '提取教案目标:'+target : ''}
-${this.courseText && this.aiCallBack == 2 ? '参考内容:'+this.courseText : ''}
+${this.courseText && this.aiCallBack[0] == 2 ? '参考内容:'+this.courseText : ''}
 
 ## 要求
 ${message} 以及##参考资料 ${(!this.yiKeTemplateArray.includes(this.templateid)) ? "" : '以文本格式输出项目概况,驱动性问题,最终作品'}
 
 ${(this.templateid != 'cf5722a4-401b-11ef-b873-005056b86dc4') && '## Format example 课程简要描述:课程内容的简单叙述。 驱动性问题:1个驱动整个项目的问题。 最终作品:对应解决驱动性问题的作品,可个人可团队。'}
 
-${this.courseText && this.aiCallBack == 2 ? '注意,优化原有的<参考内容>即可不用重新生成,让内容更具体化,更具体' : ''}
-
-如果在上传的文件中没有找到相关的课程简要描述、驱动性问题和最终作品的信息,请用自身的理解输出`
+${this.courseText && this.aiCallBack[0] == 2 ? '注意,优化原有的<参考内容>即可不用重新生成,让内容更具体化,更具体' : ''}`
       this.aiGet(msg)
     },
     setUnitJson() {
@@ -17835,6 +17914,7 @@ ${this.courseText && this.aiCallBack == 2 ? '注意,优化原有的<参考内
           this.ttextLoading = false
           this.courseTextB = false
           this.isTextCancelToken = null
+          this.aiCallBack[1] ? this.aiCallBack[1]() : ''
           return;
         } else {
           _iindex++
@@ -19713,7 +19793,7 @@ ${mclass.length ? '面向年级:' + mclass.join(",") : ''}
 ${_this.unitJson[0].chapterInfo[0].taskJson[task].taskDetail3.replaceAll('#','').replaceAll('*','').replaceAll('-','').replaceAll('\n','')}
 
 # Format example
-{answerQ:"问题"}
+{"answerQ":"问题"}
 `
         }else if(type == 45){
           messages = `NOTICE
@@ -19785,8 +19865,16 @@ ${_this.unitJson[0].chapterInfo[0].taskJson[task].taskDetail3.replaceAll('#','')
                         let match = data.message.match(regex);
                         // eval("var aaa = " + match[0])
                         tArray = JSON.parse(match[0].replace(/\n/g, '').replace(/\s{2,}/g, ' '));
-
                     } catch (error) {
+                      try {
+                          let regex = new RegExp("(?<=```json)([\\s\\S]*?)(?=```)");
+                          let regex2 = new RegExp("([a-zA-Z]+)(?=:)", "g")
+                          let match = data.message.match(regex.replace(regex2, '"$1"'));
+                          // eval("var aaa = " + match[0])
+                          tArray = JSON.parse(match[0].replace(/\n/g, '').replace(/\s{2,}/g, ' '));
+                      } catch (error) {
+                        console.log("error_________________" + error);
+                      }
                       console.log("error_________________" + error);
                     }
                     console.log("error_________________" + error);
@@ -19884,7 +19972,7 @@ ${mclass.length ? '面向年级:' + mclass.join(",") : ''}
 ${_this.unitJson[0].chapterInfo[0].taskJson[_this.taskCount].taskDetail3.replaceAll('#','').replaceAll('*','').replaceAll('-','').replaceAll('\n','')}
 
 # Format example
-{answerQ:"问题"}
+{"answerQ":"问题"}
 `
       }else if(type == 45){
         messages = `NOTICE
@@ -19953,7 +20041,8 @@ ${_this.unitJson[0].chapterInfo[0].taskJson[_this.taskCount].taskDetail3.replace
                 } catch (error) {
                   try {
                       let regex = new RegExp("(?<=```json)([\\s\\S]*?)(?=```)");
-                      let match = data.message.match(regex);
+                      let regex2 = new RegExp("([a-zA-Z]+)(?=:)", "g")
+                      let match = data.message.match(regex.replace(regex2, '"$1"'));
                       // eval("var aaa = " + match[0])
                       tArray = JSON.parse(match[0].replace(/\n/g, '').replace(/\s{2,}/g, ' '));
 
@@ -21739,7 +21828,8 @@ ${(_this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" || _this.templatei
             confirmButtonText: "确定",
             cancelButtonText: "取消",
             distinguishCancelAndClose: true,
-            type: "warning"
+            type: "warning",
+            customClass: 'custom-confirm-box'
           })
             .then(() => {
             _this.aiDetail52(msg, index, callback)
@@ -21747,6 +21837,9 @@ ${(_this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" || _this.templatei
             console.log(v);
             callback ? callback() : ''
           })
+          setTimeout(() => {
+            _this.setTipsIndex()
+          }, 500)
         }
         console.log(error);
       });
@@ -21771,7 +21864,8 @@ ${(_this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" || _this.templatei
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           distinguishCancelAndClose: true,
-          type: "warning"
+          type: "warning",
+          customClass: 'custom-confirm-box'
         })
           .then(() => {
           _this.aiDetail52(msg, _tindex2, callback)
@@ -21779,6 +21873,9 @@ ${(_this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" || _this.templatei
           console.log(v);
           callback ? callback() : ''
         })
+        setTimeout(() => {
+          _this.setTipsIndex()
+        }, 500)
         return;
       }
       
@@ -21848,7 +21945,8 @@ ${(_this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" || _this.templatei
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           distinguishCancelAndClose: true,
-          type: "warning"
+          type: "warning",
+          customClass: 'custom-confirm-box'
         })
           .then(() => {
           _this.aiDetail52(msg, _tindex2, callback)
@@ -21856,6 +21954,9 @@ ${(_this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" || _this.templatei
           console.log(v);
           callback ? callback() : ''
         })
+        setTimeout(() => {
+          _this.setTipsIndex()
+        }, 500)
       };
     },
     aiDetail52getAiContentText(_e, loading, _tindex2, _source){
@@ -22743,8 +22844,8 @@ ${this.targetCourseText && this.aiCallBack == 2 ? '注意,优化原有的<参
       }
 
       if(!msg2 && sub.length){
-        let _fileid = _this.importFileid(sub)
-        fileid = [...fileid, ..._fileid]
+        // let _fileid = _this.importFileid(sub)
+        // fileid = [...fileid, ..._fileid]
       }
 
       let messages = `NOTICE
@@ -22785,7 +22886,7 @@ ${this.targetCourseText && this.aiCallBack == 2 ? '注意,优化原有的<参
       _this.isTargetCancelToken2 = _this.ajax.setCancelSource();
 
       let params = {
-        assistant_id: 'f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b',
+        assistant_id: 'b19f1a1a-7586-11ef-8ce0-12e77c4cb76b',
         message: [{"type":"text", "text":this.languageSetting == 1 ? converter2(messages.replaceAll('\n', " ").replaceAll('*', "")) : messages.replaceAll('\n', " ").replaceAll('*', "")}],
         session_name: _uuid,
         userId: _this.userid,
@@ -22845,7 +22946,7 @@ ${this.targetCourseText && this.aiCallBack == 2 ? '注意,优化原有的<参
         this.isTargetCancelToken2 = null
         return;
       }
-      
+      let text1 = this.targetCourseText2 ? JSON.parse(JSON.stringify(this.targetCourseText2)) : ''
       let _allText = "";
       let _mdText = "";
       let _iindex = 0
@@ -22856,7 +22957,7 @@ ${this.targetCourseText && this.aiCallBack == 2 ? '注意,优化原有的<参
           _mdText = _mdText.replace("_", "").replace(/【[^】]*source[^】]*】/g, '').replaceAll("<br>", "");
           this.isTargetCancelSource2.close();
           this.isTargetCancelSource2 = null;
-          this.targetCourseText2 = _mdText;
+          this.targetCourseText2 = text1+'    \n    '+_mdText;
           this.targetTextLoading2 = false
           this.ttargetTextLoading2 = false
           this.targetCourseText2B = false
@@ -22878,7 +22979,7 @@ ${this.targetCourseText && this.aiCallBack == 2 ? '注意,优化原有的<参
           if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
           //转化返回的回复流数据
           if(_iindex == 10){
-            this.targetCourseText2 = _mdText;
+            this.targetCourseText2 = text1+'     \n    '+_mdText;
             _iindex = 0
           }
           if(this.targetTextLoading2){
@@ -22975,6 +23076,7 @@ ${this.targetCourseText && this.aiCallBack == 2 ? '注意,优化原有的<参
 
 ## 课程信息
 课程名字:${this.courseName}
+课程概况:${this.courseText}
 ${sub.length ? '学科:' + sub.join(",") : ''}
 ${mclass.length ? '年级:' + mclass.join(",") : ''}`
       let _uuid = uuidv4();
@@ -23034,6 +23136,7 @@ ${mclass.length ? '年级:' + mclass.join(",") : ''}`
         // }
         if (data.message) {
           console.log('返回回来的目标:',data.message);
+          _this.targetCourseText2 = data.message
           _this.aitargetTextDetail22(_this.aiJson.aiTarget2, data.message.replaceAll('#', " ").replaceAll('*', "").replaceAll('\n', ""))
         
         }
@@ -23341,10 +23444,10 @@ ${msg}
             console.log(data.message);
             let dArray = []
             try {
-              let regex2 = new RegExp("/([{,])(\w+):/g")
-              let regex3 = new RegExp('/(?<!")content(?!")/g')
+              // let regex2 = new RegExp("/([{,])(\w+):/g") .replace(regex2, '$1"$2":')
+              let regex3 = new RegExp('(?<!")content(?!")','g')
               // 
-              dArray = JSON.parse(data.message.replaceAll('```json','').replaceAll('```','').replaceAll('\'',"\"").replace(regex2, '$1"$2":').replace(regex3, '"content"'))
+              dArray = JSON.parse(data.message.replaceAll('```json','').replaceAll('```','').replaceAll('\'',"\"").replace(regex3, '"content"'))
             } catch (error) {
                 // callback ? callback() : ''
                 console.log("error_________________" + error);

+ 119 - 24
src/components/pages/aiAddCourse/aiBoxRight.vue

@@ -8,7 +8,7 @@
             <img src="../../../assets/icon/new/role2.png" />
           </div>
         </div>
-        <div style="margin-top:20px;margin-bottom:20px ; margin-right: auto;">
+        <div style="margin-top:20px;margin-bottom:20px ; margin-right: auto;" v-if="item.aiContent || item.loading">
           <div class="role">
             <img :src="item.fileid
                 ? item.fileid
@@ -19,8 +19,11 @@
             minHeight: item.loading ? '50px' : 'unset',
             minWidth: item.loading ? '50px' : 'unset'
           }" class="content" v-loading="item.loading">
-            <span class="vditor-reset" v-html="item.aiContent"></span><span class="createTime"
-              v-text="item.createtime"></span>
+            <span class="vditor-reset" v-html="item.aiContent"></span>
+            <span class="createTime" v-text="item.createtime"></span>
+          </div>
+          <div class="ai_btn_box" v-if="!pan(item.aiContent).length && !item.loading">
+            <img src="../../../assets/icon/course/pasete.png" @click="onCopy(item.aiContent)" >
           </div>
         </div>
       </div>
@@ -113,7 +116,7 @@
       <div class="ai_b_i_jListPanel" @click="showjList = !showjList" v-if="showjList && jArray.length > 0"></div>
       <div class="ai_b_i_jListBox" v-if="showjList && jArray.length > 0">
         <div class="jlist_box" v-for="(item, index) in jArray" :key="index">
-          <el-tooltip :content="item.area + ':' + item.value" placement="top" effect="dark" popper-class="text_tooltip2">
+          <el-tooltip :content="item.area + ':' + item.value" placement="left" effect="dark" popper-class="text_tooltip2">
             <!-- content to trigger tooltip here -->
             <span>{{ item.area }}:{{ item.value }}</span>
           </el-tooltip>
@@ -126,14 +129,15 @@
 			</div> -->
       <!-- @input="inputChange" -->
 
-      <textarea class="ai_body_input_textarea" @keydown="textareaKeydown" ref="textareaRef" v-model.trim="courseText"
+      <textarea class="ai_body_input_textarea" @input="inputChange" @keydown="textareaKeydown" ref="textareaRef" v-model.trim="courseText"
         placeholder="在此输入您想了解的内容"></textarea>
       <div :class="[
         'c_pub_button_confirm',
         courseText ? '' : 'c_pub_button_confirmDisabled'
-      ]" v-if="!loading" @click="addContent">
+      ]" v-if="!faloading" @click="addContent">
         发送
       </div>
+      <div class='c_pub_button_confirm' v-else @click="stopSend">终止</div>
     </div>
     <!-- <div class="ai_body_input">
       <textarea
@@ -162,6 +166,9 @@ import checkImg from "../../../assets/icon/sourceFile/check.png";
 import checkIsImg from "../../../assets/icon/sourceFile/check_is.png";
 import { v4 as uuidv4 } from "uuid";
 import MarkdownIt from "markdown-it";
+import TurndownService from 'turndown';
+
+
 export default {
   props: {
     unitJson: {
@@ -286,8 +293,11 @@ export default {
       showRoleList: false,
       choseRoleItem: 0,
       choseTextItem: 0,
-      continuous: false,
-      showjList: false
+      continuous: true,
+      showjList: false,
+      faloading: false,
+      fasource: null,
+      saveUid: "",
     };
   },
   watch: {
@@ -458,6 +468,7 @@ export default {
       }
     },
     addContent() {
+      if (this.courseText.trim().length == 0) return this.$message.error("请输入内容");
       let message = this.courseText;
       if (this.courseText) {
         let msg = ``;
@@ -521,7 +532,7 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
             _atRoleList.push(i);
           }
         });
-
+        this.faloading = true;
         if (_atRoleList.length > 0) {
           //有@角色
           let _replaceText = message;
@@ -603,6 +614,7 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
                 console.log(err);
               });
             this.getAtAuContent(_uid);
+            this.saveUid = _uid;
           });
           this.courseText = "";
         } else {
@@ -662,19 +674,21 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
               console.log(e);
             });
           this.getAiContent(_uuid);
+          this.saveUid = _uuid;
         }
       }
     },
     getAiContent(_uid) {
-      let _source = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`); //http://gpt4.cocorobo.cn:8011/stream/     https://gpt4.cocorobo.cn/stream/
+      this.fasource = new EventSource(`https://gpt4.cocorobo.cn/stream/${_uid}`); //http://gpt4.cocorobo.cn:8011/stream/     https://gpt4.cocorobo.cn/stream/
       let _allText = "";
       let _mdText = "";
       const md = new MarkdownIt();
-      _source.onmessage = _e => {
+      this.fasource.onmessage = _e => {
         if (_e.data.replace("'", "").replace("'", "") == "[DONE]") {
           //对话已经完成
           _mdText = _mdText.replace("_", "");
-          _source.close();
+          this.fasource.close();
+          this.fasource = null
           this.$nextTick(() => {
             this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
           });
@@ -712,13 +726,13 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
       };
     },
     getAtAuContent(_uid) {
-      let _source = new EventSource(
+      this.fasource = new EventSource(
         `https://gpt4.cocorobo.cn/question/${_uid}`
       ); //http://gpt4.cocorobo.cn:8011/question/   https://gpt4.cocorobo.cn/question/
       let _allText = "";
       let _mdText = "";
       const md = new MarkdownIt();
-      _source.onmessage = _e => {
+      this.fasource.onmessage = _e => {
         let _eData = JSON.parse(_e.data);
         if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
           let _result = [];
@@ -736,7 +750,11 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
           this.$nextTick(() => {
             this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
           });
-          this.insertChat(_uid);
+          this.fasource.close();
+          this.fasource = null;
+          if (this.courseId) {
+            this.insertChat(_uid);
+          }
         } else {
           let _text = _eData.content.replace("'", "").replace("'", "");
           if (_allText == "") {
@@ -762,6 +780,8 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
     //保存消息
     insertChat(_uid) {
       let _data = this.array.find(i => i.uid == _uid);
+      this.saveUid = ''
+      this.faloading = false
       if (!_data) return;
       let params = {
         userId: this.userid,
@@ -782,7 +802,7 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
     // 获取对应的聊天记录
     getChatList() {
       return new Promise((resolve, reject) => {
-        if (this.loading) return this.$message.info("请稍等...");
+        if (this.loading) return ;
         this.array = [];
         this.loading = true;
         let params = {
@@ -1007,9 +1027,74 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
         } `;
       this.$refs.textareaRef.focus();
       this.showRoleList = false;
-    }
+    },
+    onCopy(content) {
+      const turndownService = new TurndownService();
+      // 添加自定义规则来处理表格
+      turndownService.addRule('table', {
+        filter: 'table',
+        replacement: (content, node) => {
+          const rows = node.querySelectorAll('tr');
+          let markdown = '';
+
+          rows.forEach((row) => {
+            const cells = row.querySelectorAll('th, td');
+            const rowMarkdown = Array.from(cells).map(cell => cell.textContent).join(' | ');
+            markdown += `| ${rowMarkdown} |\n`;
+            if(cells && cells.length && cells[0].tagName == 'TH'){
+              let a = Array.from(cells).map(cell => '').join(' --- |')
+              markdown += `| --- |${a}\n`;
+            }
+          });
+
+          // 添加分隔行
+          // markdown = markdown.replace(/^/, '| --- |\n');
+          return markdown;
+        },
+      });
+      // 创建临时textarea元素
+      const tempInput = document.createElement("textarea");
+      
+      tempInput.value = turndownService.turndown(content); // 设置要复制的内容
+      // 隐藏元素
+      tempInput.style.position = "absolute";
+      tempInput.style.left = "-9999px";
+      // 将元素添加到DOM中
+      document.body.appendChild(tempInput);
+      // 选中元素内容
+      tempInput.select();
+      // 执行复制操作
+      document.execCommand("copy");
+      // 移除临时元素
+      document.body.removeChild(tempInput);
+      this.$message({
+        message: "复制成功",
+        type: "success"
+      });
+    },
+    stopSend() {
+      if (this.fasource) {
+        this.fasource.close();
+        if (this.array[this.array.length - 1].content == "wanSearch") {
+          this.array.pop();
+        }
+        this.array.find(i => i.uid == this.saveUid).loading = false;
+        this.faloading = false;
+        this.fasource = null;
+        this.insertChat(this.saveUid);
+      }
+    },
   },
   computed: {
+    pan() {
+      return content => {
+        try {
+          return JSON.parse(content);
+        } catch (error) {
+          return [];
+        }
+      };
+    },
     courseTextLength() {
       return this.courseText.length;
     },
@@ -1040,12 +1125,12 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
     }
   },
   mounted() {
-    this.getChatList().then(_ => {
-      this.$nextTick(() => {
-        console.log(this.$refs.chatDialog.scrollHeight);
-        this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
-      });
-    });
+    // this.getChatList().then(_ => {
+    //   this.$nextTick(() => {
+    //     console.log(this.$refs.chatDialog.scrollHeight);
+    //     this.$refs.chatDialog.scrollTop = this.$refs.chatDialog.scrollHeight;
+    //   });
+    // });
     this.getRoleList();
     this.getPublicRoleList();
     this.jArray = this.getString();
@@ -1429,7 +1514,7 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
   word-break: break-word;
   box-sizing: border-box;
   /* white-space: pre-line; */
-  max-width: calc(100% - 50px);
+  max-width: calc(100% - 85px);
   background: #f6f9ff;
   /* overflow: hidden; */
   margin: 0 10px;
@@ -1665,4 +1750,14 @@ ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully reference
   overflow: hidden;
   word-break: break-all;
 }
+
+.ai_btn_box{
+  min-width: fit-content;
+  margin-top: auto;
+}
+
+.ai_btn_box > img{
+  cursor: pointer;
+  width: 15px;
+}
 </style>

+ 15 - 3
src/components/pages/aiAddCourse/aiCreateVideoDialog.vue

@@ -23,7 +23,11 @@
                     <span class="author">作者:{{ item.author }}</span>
                     <span class="detail">{{ item.description }}</span>
                     <div class="tag" v-if="item.tag.split(',').length > 0">
-                        <span v-for="(tag, index) in item.tag.split(',')" :key="index">{{ tag }}</span>
+                        <el-tooltip :content="tag" placement="top" effect="dark" v-for="(tag, index) in item.tag.split(',').slice(0, 5)" :key="index">
+                            <!-- content to trigger tooltip here -->
+                            <span >{{ tag }}</span>
+                        </el-tooltip>
+                        
                     </div>
                     <div class="btn">
                         <span @click="openUrl(item.bvid)">查看</span>
@@ -263,7 +267,7 @@ export default {
                         console.log(data.message);
 
                         let content = data.message;
-                        _this.detail = content
+                        _this.detail = _this.courseName+"," + content
                         let _content = content.split(",")
                         if(content.split(",").length>1){
                             _content = content.split(",")
@@ -272,6 +276,7 @@ export default {
                         }
                         _this.data = []
                         let data2 = []
+                        _content.unshift(_this.courseName)
                         for (var a = 0; a < _content.length; a++) {
                             let _data = await _this.aiGet2(_content[a])
                             data2[a] = _data
@@ -537,8 +542,9 @@ export default {
 
 .video_box>.tag{
     display: flex;
-    flex-wrap: wrap;
+    flex-wrap: nowrap;
     margin-top: auto;
+    width: 100%;
 }
 
 .video_box>.tag>span{
@@ -548,6 +554,12 @@ export default {
     border-radius: 15px;
     font-size: 0.9em;
     margin: 0 5px 5px 0;
+    max-width: 100%;
+    overflow: hidden;
+    box-sizing: border-box;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    text-align: center;
 }
 
 .btn {

+ 633 - 0
src/components/pages/aiAddCourse/aiCreateVideoDialogHK.vue

@@ -0,0 +1,633 @@
+<template>
+    <el-dialog title="智能检索" :visible.sync="dialogVisibleAiCreateVideo" :append-to-body="true" width="90%"
+        :before-close="handleClose" class="dialog_diy">
+        <div style="box-sizing:border-box;padding:15px" v-loading="loading" element-loading-text="小可正在努力生成中,请稍等...">
+            <div style="position: relative; width: 100%;height: 40px;margin-bottom: 10px;">
+                <el-input class="inputC" style="height: 100%;" placeholder="搜索视频关键字(如需搜索多个可“,”隔开)" v-model="detail"
+                    @keyup.enter.native="searchA()"></el-input>
+                <div class="search_img" @click="searchA" style="right: 10px">
+                    <img src="../../../assets/icon/search.png" alt />
+                </div>
+            </div>
+            <div class="nav_box">
+                <div class="nav" :class="{ active: navActive == 0 }" @click="navClick(0)">综合排序</div>
+                <div class="nav" :class="{ active: navActive == 1 }" @click="navClick(1)">相关程度</div>
+                <div class="nav" :class="{ active: navActive == 2 }" @click="navClick(2)">上传日期</div>
+                <div class="nav" :class="{ active: navActive == 3 }" @click="navClick(3)">观看次数</div>
+                <div class="nav" :class="{ active: navActive == 4 }" @click="navClick(4)">评分</div>
+            </div>
+            <div class="Box">
+                <div class="video_box video_box2" v-for="(item, index) in data" :key="index">
+                    <!-- <img :src="item.pic" /> -->
+                    <span class="name" v-html="item.title"></span>
+                    <span class="author">作者:{{ item.channel.title }}</span>
+                    <span class="detail">{{ item.description }}</span>
+                    <div class="tag" v-if="item.badges && item.badges.length > 0">
+                        <el-tooltip :content="tag" placement="top" effect="dark" v-for="(tag, index) in item.badges.slice(0, 5)" :key="index">
+                            <!-- content to trigger tooltip here -->
+                            <span >{{ tag }}</span>
+                        </el-tooltip>
+                        
+                    </div>
+                    <div class="btn" :style="{marginTop: item.badges && item.badges.length > 0 ? '0' : 'auto'}">
+                        <span @click="openUrl(item.id)">查看</span>
+                        <span @click="checkUrl(item.title, item.id)">加入</span>
+                    </div>
+                </div>
+                <div v-if="data.length == 0" class="no_data">暂无数据</div>
+            </div>
+        </div>
+        <span slot="footer" class="dialog-footer">
+            <el-button @click="close">关 闭</el-button>
+        </span>
+    </el-dialog>
+</template>
+
+<script>
+import { v4 as uuidv4 } from "uuid";
+import _ from "lodash";
+
+export default {
+    components: {
+    },
+    props: {
+        dialogVisibleAiCreateVideo: {
+            type: Boolean,
+            default: false
+        },
+        courseName: {
+            type: String,
+            default: ""
+        },
+        courseState: {
+            type: Number,
+        },
+        lineCount: {
+            type: Number,
+        },
+        unitJson: {
+            type: Array,
+        }
+    },
+    // 根据用户给你的参考资料
+    data() {
+        return {
+            userid: this.$route.query.userid,
+            radio: 0,
+            aiJson: {
+                ppt: ``,
+                word: '',
+                video: ''
+            },
+            aiUrl: {
+                ppt: '',
+                word: '',
+                video: ''
+            },
+            detail: "",
+            loading: false,
+            url: "",
+            data: [],
+            uJson: {},
+            navActive: 0
+        }
+    },
+    watch: {
+        dialogVisibleAiCreateVideo(newValue, oldValue) {
+            if (newValue) {
+                this.detail = ""
+                this.data = []
+                this.againEva()
+            }
+        },
+    },
+    methods: {
+        handleClose(done) {
+            this.close()
+            done();
+        },
+        close() {
+            this.$emit('update:dialogVisibleAiCreateVideo', false)
+        },
+        openUrl(url) {
+            window.open('https://www.youtube.com/embed/'+url)
+            // window.open(`//www.bilibili.com/video/${url}`)
+        },
+        checkUrl(name, id) {
+            let json = {
+                name: "链接",
+                title: name.replace(/<[^>]*>?/gm, ''),
+                url: 'https://www.youtube.com/embed/'+id,
+                // url: `//player.bilibili.com/player.html?isOutside=true&bvid=${id}`,
+                type: 8,
+            }
+            this.$emit('createAiVideo', json)
+            this.$message.success('加入成功')
+        },
+        changeRadio() {
+            if (this.radio == 0) {
+                this.detail = this.aiJson.ppt
+            }
+            if (this.radio == 1) {
+                this.detail = this.aiJson.word
+            }
+            if (this.radio == 2) {
+                this.detail = this.aiJson.video
+            }
+        },
+        // async aiGet() {
+        //     let _this = this
+        //     _this.loading = true
+        //     this.ajax
+        //         .get(`https://www.googleapis.com/youtube/v3/search?key=AIzaSyBUvNQ5Wyua4PbStE2vp3t7MIY4htry-4M&part=snippet&q=${this.detail}&maxResults=10&type=video&order=relevance&regionCode=HK`)
+        //         .then((response) => {
+        //             console.log(response);
+        //             _this.data = response.data.items
+        //             _this.loading = false
+
+        //         })
+        //         .catch((error) => {
+        //             _this.loading = false
+        //             console.log(error);
+        //         });
+        // },
+        async aiGet() {
+            let _this = this
+            _this.loading = true
+            this.ajax.post(`https://gpt4.cocorobo.cn/get_network_search`, {
+                engine: "bilibili",
+                keyword: this.detail
+            }).then(response => {
+                console.log(response);
+                _this.data = response.data.FunctionResponse
+                _this.loading = false
+
+            })
+                .catch((error) => {
+                    _this.loading = false
+                    console.log(error);
+                });
+        },
+        // async aiGet2(msg) {
+        //     let _this = this
+        //     _this.loading = true
+        //     this.ajax
+        //         .get(`https://www.googleapis.com/youtube/v3/search?key=AIzaSyBUvNQ5Wyua4PbStE2vp3t7MIY4htry-4M&part=snippet&q=${msg}&maxResults=10&type=video&order=relevance&regionCode=HK`)
+        //         .then((response) => {
+        //             console.log(response);
+        //             _this.data = response.data.items
+        //             _this.loading = false
+
+        //         })
+        //         .catch((error) => {
+        //             _this.loading = false
+        //             console.log(error);
+        //         });
+        // },
+        async aiGet2(msg) {
+            let _this = this
+            return new Promise((resolve, reject) => {
+                this.ajax.post(`https://gpt4.cocorobo.cn/get_network_search`, {
+                    engine: "youtubeNew",
+                    keyword: msg,
+                    // page: 1,
+                    // page_size: 20,
+                    order: this.navActive,
+                    // duration: 0,
+                }).then(response => {
+                    console.log(response);
+                    // _this.data = [..._this.data,...response.data.FunctionResponse]
+                    resolve(response.data.FunctionResponse)
+                })
+                    .catch((error) => {
+                        resolve([])
+                        console.log(error);
+                    });
+            });
+        },
+        navClick(item) {
+            if(this.navActive == item){
+                return
+            }
+            this.navActive = item
+            this.searchA()
+        },
+        async searchA(){
+            let _this = this
+            try {
+                if(!_this.detail){
+                    _this.$message.error("请输入关键字")
+                    return
+                }
+                _this.loading = true
+                let _content = ""
+                if(_this.detail.split(",").length>1){
+                    _content = _this.detail.split(",")
+                }else{
+                    _content = _this.detail.split(",")
+                }
+                _this.data = []
+                let data2 = []
+                for (var a = 0; a < _content.length; a++) {
+                    let _data = await _this.aiGet2(_content[a])
+                    data2[a] = _data
+                }
+                _this.data = _.flatMap(_.zip(...data2), (pair) => pair.filter(value => value !== undefined))
+                // _this.data = _this.data.sort(
+                //     function (a, b) {
+                //         return b.play - a.play;
+                //     }
+                // );
+                _this.againEva2();
+                // _this.loading = false
+            } catch (error){
+                console.log(error);
+                _this.loading = false
+            }
+            
+        },
+        againEva() {
+            let _this = this
+            _this.loading = true
+            let message = `从以下内容中识别出1~2个学科知识点关键词,用于检索知识点相关视频。注意,你仅需要返回关键词,“,”分开。教案:${_this.unitJson[0].chapterInfo[0].taskJson[_this.lineCount].taskDetail3.replaceAll('#', '').replaceAll('*', '').replaceAll('-', '').replaceAll('\n', '')}`
+            let parm = {
+                assistant_id: 'f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b',
+                message: [{ "type": "text", "text": message.replaceAll('\n', " ").replaceAll('*', "") }],
+                session_name: uuidv4(),
+                userId: _this.userid,
+                file_ids: [],
+                model: 'gpt-4o-2024-08-06',
+            }
+            _this.ajax
+                .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", parm)
+                .then(async (response) => {
+                    console.log(response);
+                    let data = response.data.FunctionResponse
+                    if (data.message) {
+                        console.log(data.message);
+
+                        let content = data.message;
+                        _this.detail = _this.courseName+"," + content
+                        let _content = content.split(",")
+                        if(content.split(",").length>1){
+                            _content = content.split(",")
+                        }else{
+                            _content = content.split(",")
+                        }
+                        _this.data = []
+                        let data2 = []
+                        _content.unshift(_this.courseName)
+                        for (var a = 0; a < _content.length; a++) {
+                            let _data = await _this.aiGet2(_content[a])
+                            data2[a] = _data
+                        }
+                        _this.data = _.flatMap(_.zip(...data2), (pair) => pair.filter(value => value !== undefined))
+                        // _this.data = _this.data.sort(
+                        //     function (a, b) {
+                        //         return b.play - a.play;
+                        //     }
+                        // );
+                        _this.againEva2();
+                    }else {
+                        _this.$message.error("哎呀,请求太多了,服务器忙不过来了,请自行搜索关键词")
+                        _this.loading = false
+                    }
+                    // _this.loading = false
+
+                })
+                .catch((error) => {
+                    console.log(error);
+                    _this.$message.error("哎呀,请求太多了,服务器忙不过来了,请自行搜索关键词")
+                    _this.loading = false
+                });
+        },
+        againEva2() {
+            let _this = this
+            _this.loading = true
+            let message = `ATTENTION: Use '##' to SPLIT SECTIONS, not '#'.Output format carefully referenced "Format example".
+针对以下视频数组内容,删除其中不适合k12年级的学生在教室里看到的条目,返回以下视频数组不符合的视频的id,视频数组:${JSON.stringify(_this.data)}
+
+# Format example
+[{id:""},{id:""}]
+`
+            let parm = {
+              model: 'gpt-4o-2024-08-06',
+              temperature: 0,
+              max_tokens: 4096,
+              top_p: 1,
+              frequency_penalty: 0,
+              presence_penalty: 0,
+              messages: [{
+                content: message.replaceAll('\n', " ").replaceAll('*', ""),
+                role: 'user'
+              }],
+              uid: uuidv4(),
+              stream: false,
+              mind_map_question: "",
+            }
+            _this.ajax
+                .post("https://gpt4.cocorobo.cn/chat", parm)
+                .then(async (response) => {
+                    console.log(response);
+                    let data = response.data.FunctionResponse
+                    if (data.choices && data.choices.length && data.choices[0].message) {
+                        console.log(data.choices[0].message.content);
+                        let dArray = []
+                        try {
+                            dArray = JSON.parse(data.choices[0].message.content.replaceAll('```json','').replaceAll('```',''))
+                        } catch (error) {
+                            console.log("error_________________" + error);
+                            try {
+                                let regex = new RegExp("(?<=```json)([\\s\\S]*?)(?=```)");
+                                let match = data.choices[0].message.content.match(regex);
+                                dArray = JSON.parse(match[0]);
+                            } catch (error) {
+                                console.log("error_________________" + error);
+                            }
+                        }
+
+                        let id = []
+                        for(var i = 0; i < dArray.length; i++){
+                            id.push(dArray[i].id)
+                        }
+                        _this.data = _this.data.filter(el => {
+                            return id.indexOf(el.id) === -1
+                        })
+                        _this.$forceUpdate()
+                    }
+                    _this.loading = false
+                })
+                .catch((error) => {
+                    console.log(error);
+                    // _this.$message.error("哎呀,请求太多了,服务器忙不过来了,请自行搜索关键词")
+                    _this.loading = false
+                });
+        },
+    },
+    mounted () {
+        
+    },
+}
+</script>
+
+<style scoped>
+@media screen and (max-width: 1080px) {
+.video_box {
+    width: calc(100% / 3 - 10px) !important;
+  }
+}
+@media screen and (max-width: 760px) {
+.video_box {
+    width: calc(100% / 2 - 10px) !important;
+  }
+}
+.dialog_diy>>>.el-dialog {
+    height: auto;
+    margin: 50px auto 0 !important;
+}
+
+.dialog_diy>>>.el-dialog__header {
+    background: #454545 !important;
+    padding: 15px 20px;
+}
+
+.dialog_diy>>>.el-dialog__body {
+    height: calc(100% - 124px);
+    box-sizing: border-box;
+    padding: 0px;
+}
+
+
+.dialog_diy>>>.el-dialog__title {
+    color: #fff;
+}
+
+.dialog_diy>>>.el-dialog__headerbtn {
+    top: 19px;
+}
+
+.dialog_diy>>>.el-dialog__headerbtn .el-dialog__close {
+    color: #fff;
+}
+
+.dialog_diy>>>.el-dialog__headerbtn .el-dialog__close:hover {
+    color: #fff;
+}
+
+
+.dialog_diy>>>.el-dialog__body,
+.dialog_diy>>>.el-dialog__footer {
+    background: #fafafa;
+}
+
+.binfo_input {
+    width: 100%;
+    margin: 0;
+    padding: 5px 7px;
+    display: block;
+    min-width: 0;
+    outline: none;
+    box-sizing: border-box;
+    background: none;
+    border: none;
+    border-radius: 4px;
+    background: #fff;
+    font-size: 15px;
+    resize: none;
+    font-family: "Microsoft YaHei";
+    min-height: 48px;
+    /* border: 1px solid #3682fc00; */
+    border: 1.5px solid #cad1dc;
+}
+
+.binfo_textarea {
+    border: 1.5px solid #cad1dc;
+    font-size: 15px;
+    resize: none;
+    /* background: #f6f6f6; */
+    font-family: "Microsoft YaHei";
+}
+
+.binfo_input:focus-visible {
+    border: 1.5px solid #3681fc !important;
+}
+
+
+.t_box {
+    display: flex;
+    margin-bottom: 15px;
+}
+
+.t_box>span:nth-child(1) {
+    min-width: 80px;
+    font-size: 16px;
+    color: #000;
+}
+
+.inputC>>>.el-input__inner {
+    padding: '0 35px 0 15px'
+}
+
+.search_img {
+    width: 20px;
+    height: 20px;
+    position: absolute;
+    right: 10px;
+    top: 50%;
+    transform: translateY(-50%);
+}
+
+.search_img>img {
+    width: 100%;
+    height: 100%;
+}
+
+
+.Box {
+    width: 100%;
+    height: 500px;
+    overflow: auto;
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    flex-wrap: wrap;
+    padding: 5px;
+    box-sizing: border-box;
+}
+
+.video_box {
+    width: calc(100% / 4 - 10px);
+    /* overflow: hidden; */
+    margin-right: 10px;
+    display: flex;
+    flex-direction: column;
+    margin-bottom: 15px;
+    cursor: pointer;
+}
+
+.video_box>img {
+    height: 200px;
+    object-fit: cover;
+}
+
+.video_box>.detail {
+    color: #cecece;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 3; /* 显示3行文本 */
+    overflow: hidden;
+    text-overflow: ellipsis; /* 超出部分显示点点点 */
+    margin: 0 0 5px;
+}
+
+.video_box>.name {
+    color: #000;
+    margin: 5px 0;
+    height: 32px;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2; /* 显示3行文本 */
+    overflow: hidden;
+    text-overflow: ellipsis; /* 超出部分显示点点点 */
+}
+
+.video_box>.author{
+    margin: 0 0 5px;
+    width: 100%;
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis; /* 超出部分显示点点点 */
+    white-space: nowrap;
+}
+
+.video_box>.tag{
+    display: flex;
+    flex-wrap: nowrap;
+    margin-top: auto;
+    width: 100%;
+}
+
+.video_box>.tag>span{
+    background: #eef3fb;
+    color: #0061ff;
+    padding: 5px 10px;
+    border-radius: 15px;
+    font-size: 0.9em;
+    margin: 0 5px 5px 0;
+    max-width: 100%;
+    overflow: hidden;
+    box-sizing: border-box;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    text-align: center;
+}
+
+.btn {
+    width: 100%;
+    height: 35px;
+    display: flex;
+    align-items: center;
+    /* margin-top: auto; */
+}
+
+.btn>span:hover {
+    background: #4087f1;
+}
+
+.btn>span {
+    width: 100%;
+    height: 100%;
+    background: #3681fc;
+    color: #fff;
+    border-radius: 5px;
+    margin-top: 10px;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.btn>span+span {
+    margin-left: 10px;
+}
+
+.video_box2 {
+    box-shadow: 0px 0px 4px 2px #d2d2d282;
+    padding: 5px 10px 10px;
+    box-sizing: border-box;
+    border-radius: 5px;
+}
+
+
+.nav_box {
+    display: flex;
+    margin-bottom: 10px;
+    align-content: center;
+}
+
+.nav_box .nav{
+    padding: 8px 10px;
+    color: #060e17;
+    border-radius: 5px;
+    cursor: pointer;
+}
+
+.nav_box .nav.active{
+    background: #eef3fb;
+    font-weight: bold;
+    color: #0061ff;
+}
+
+.nav_box .nav + .nav{
+    margin-left: 20px;
+}
+
+.no_data{
+    height: 500px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 500px;
+}
+</style>

+ 50 - 14
src/components/pages/classroomObservation/components/addNewAnalysisDialog.vue

@@ -4,6 +4,7 @@
       :center="true"
       :visible.sync="dialogVisible"
       width="1200px"
+			style="z-index: 2172;"
       class="addTemplateDialog"
     >
       <!-- <div v-if="showDialog == true" class="a-dialog" v-el-drag-dialog> -->
@@ -399,7 +400,6 @@
                     >
                     </el-option>
                   </el-select>
-                  <!-- <el-input v-model="form.subject" placeholder="请输入所属学科" style="width: 300px;"></el-input> -->
                 </el-form-item>
 
                 <el-form-item
@@ -420,7 +420,26 @@
                     >
                     </el-option>
                   </el-select>
-                  <!-- <el-input v-model="form.subject" placeholder="请输入所属学科" style="width: 300px;"></el-input> -->
+                </el-form-item>
+
+								<el-form-item
+                  label="图表类型"
+                  prop="echartsType"
+                  style="margin-right: 50px;"
+                  class="d_d_b_at_input"
+                >
+                  <el-select
+                    v-model="form.echartsType"
+                    placeholder="请选择图表类型"
+                  >
+                    <el-option
+                      v-for="item in echartsList"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    >
+                    </el-option>
+                  </el-select>
                 </el-form-item>
               </div>
               <el-form-item
@@ -525,8 +544,8 @@ export default {
       dialogVisible: false,
       userId: this.$route.query["userid"],
       input2: "",
-
       tagIndex: 0,
+			addTagIndex:0,
       tagSubject: "",
       boxType: 0, //0 新建  1修改
       dialogTagList: [
@@ -548,13 +567,20 @@ export default {
         { value: "10", label: "政治" },
         { value: "11", label: "其它" }
       ],
+			echartsList:[
+				{value:'0',label:"无"},
+				{value:'1',label:"词云图"},
+				{value:'2',label:"雷达图"},
+				{value:'3',label:"柱状图"},
+			],
       form: {
         name: "",
         detail: "",
         tips: "",
         type: "",
         subject: "",
-        open: false
+        open: false,
+				echartsType:0,
       },
       showModelDialog: "",
       formLoading: false,
@@ -626,6 +652,7 @@ export default {
 	},
   methods: {
     open(type) {
+			this.addTagIndex = type;
       this.tagIndex = type;
       this.input2 = "";
       this.tagSubject = "";
@@ -636,7 +663,8 @@ export default {
         tips: "",
         type: "",
         subject: "",
-        open: false
+        open: false,
+				echartsType:'0'
       };
       this.$emit("update");
     },
@@ -647,7 +675,7 @@ export default {
       this.tagSubject = "";
     },
     addAnalysisItem(title, id) {
-      this.$emit("success", title, id);
+      this.$emit("success", title, id,this.addTagIndex);
     },
     addNew() {
       this.$refs.newAnalysisModuleRef.open();
@@ -664,7 +692,8 @@ export default {
         tips: "",
         type: "",
         subject: "",
-        open: false
+        open: false,
+				echartsType:'0',
       };
       //新建模块
     },
@@ -684,7 +713,8 @@ export default {
                 ntype: this.form.type,
                 nopen: this.form.open ? 2 : 0,
                 nagentid: "",
-                ntips: this.form.tips
+                ntips: this.form.tips,
+								nctype:this.form.echartsType
               }
             ];
 
@@ -703,7 +733,8 @@ export default {
                     tips: "",
                     type: "",
                     subject: "",
-                    open: false
+                    open: false,
+										echartsType:'0',
                   };
                   this.$message.success("创建成功");
                 } else {
@@ -729,7 +760,8 @@ export default {
                 ntype: this.form.type,
                 nopen: this.form.open ? 2 : 0,
                 nagentid: this.form.agentid,
-                ntips: this.form.tips
+                ntips: this.form.tips,
+								nctype:this.form.echartsType
               }
             ];
             this.ajax
@@ -765,7 +797,8 @@ export default {
         tips: "",
         type: "",
         subject: "",
-        open: false
+        open: false,
+				echartsType:'0'
       };
     },
     editAnalysis(type, data) {
@@ -780,7 +813,8 @@ export default {
             ntype: data.type,
             nopen: 2,
             nagentid: data.agentid,
-            ntips: data.tips
+            ntips: data.tips,
+						echartsType:0,
           }
         ];
         this.formLoading = true;
@@ -812,7 +846,8 @@ export default {
             ntype: data.type,
             nopen: 0,
             nagentid: data.agentid,
-            ntips: data.tips
+            ntips: data.tips,
+						nctype:data.echartsType
           }
         ];
         this.formLoading = true;
@@ -846,7 +881,8 @@ export default {
           type: data.type,
           subject: data.subject,
           agentid: data.agentid,
-          open: data.open == 0 ? false : true
+          open: data.open == 0 ? false : true,
+					echartsType:data.echartsType,
         };
         this.showModelDialog = "";
       } else if (type == 4) {

+ 204 - 45
src/components/pages/classroomObservation/components/addNewTeacherVoiceprintDialog.vue

@@ -9,28 +9,71 @@
       <!-- <div v-if="showDialog == true" class="a-dialog" v-el-drag-dialog> -->
       <div class="a-d-top">
         <div class="a-d-topTit"><div>新增声纹</div></div>
-  
+
         <div class="a-d-t-right">
           <span @click.stop="close()">×</span>
         </div>
       </div>
       <div class="a_box">
-				<div class="a_b_form">
-					<div class="a_b_f_item"></div>
-				</div>
-				<div class="a_b_bottom">
-					<div class="a_b_b_top">
-						<span>请使用正常语速朗读以上内容</span>
-					</div>
-					<div class="a_b_b_bottom">
-						<div class="a_b_b_b_btn">
-							<svg width="16" height="22" viewBox="0 0 16 22" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00009 13.8098C10.5962 13.8098 12.6876 11.6655 12.6876 9.00351V5.30633C12.6876 2.64436 10.5962 0.5 8.00009 0.5C5.40393 0.5 3.31259 2.64436 3.31259 5.30633V9.00351C3.31259 11.6655 5.40393 13.8098 8.00009 13.8098ZM4.75489 5.30633C4.75489 3.45774 6.1972 1.97887 8.00009 1.97887C9.80297 1.97887 11.2453 3.45774 11.2453 5.30633V9.00351C11.2453 10.8521 9.80297 12.331 8.00009 12.331C6.1972 12.331 4.75489 10.8521 4.75489 9.00351V5.30633ZM15.5 10.1132C15.5 9.70651 15.1755 9.37377 14.7788 9.37377C14.4183 9.37377 14.0938 9.66954 14.0577 10.0393C13.5529 13.034 11.0288 15.2892 8 15.2892C4.97115 15.2892 2.44712 13.034 1.94231 10.0393C1.90625 9.66954 1.58173 9.37377 1.22115 9.37377C0.824519 9.37377 0.5 9.70651 0.5 10.1132V10.2241C1.07692 13.6995 3.85337 16.3984 7.27885 16.7311V19.9223H4.15379C3.72896 19.9223 3.38456 20.2755 3.38456 20.7111C3.38456 21.1467 3.72896 21.4998 4.15379 21.4998H11.8461C12.2709 21.4998 12.6153 21.1467 12.6153 20.7111C12.6153 20.2755 12.2709 19.9223 11.8461 19.9223H8.72115V16.7311C12.1466 16.3984 14.9231 13.6995 15.4639 10.2611C15.4639 10.2426 15.473 10.2149 15.482 10.1872L15.482 10.1871C15.491 10.1594 15.5 10.1317 15.5 10.1132Z" fill="white"/>
-</svg>
-点击录制
+        <div class="a_b_form">
+          <el-form label-position="top" :model="form" :rules="rules">
+            <el-form-item class="a_b_f_item" label="教师名称" prop="name">
+              <el-input v-model="form.name" :disabled="![0].includes(status)"></el-input>
+            </el-form-item>
+
+            <el-form-item class="a_b_f_item" label="声纹录制">
+              <div class="a_b_f_itemTextArea">
+                <div v-text="textAreaVale"></div>
+              </div>
+            </el-form-item>
+          </el-form>
+        </div>
+        <div class="a_b_bottom">
+          <div class="a_b_b_top">
+            <span>请使用正常语速朗读以上内容</span>
+          </div>
+          <div class="a_b_b_bottom">
+            <div class="a_b_b_b_btn" @click.stop="start()" v-if="status===0">
+              <svg
+                width="16"
+                height="22"
+                viewBox="0 0 16 22"
+                fill="none"
+                xmlns="http://www.w3.org/2000/svg"
+              >
+                <path
+                  fill-rule="evenodd"
+                  clip-rule="evenodd"
+                  d="M8.00009 13.8098C10.5962 13.8098 12.6876 11.6655 12.6876 9.00351V5.30633C12.6876 2.64436 10.5962 0.5 8.00009 0.5C5.40393 0.5 3.31259 2.64436 3.31259 5.30633V9.00351C3.31259 11.6655 5.40393 13.8098 8.00009 13.8098ZM4.75489 5.30633C4.75489 3.45774 6.1972 1.97887 8.00009 1.97887C9.80297 1.97887 11.2453 3.45774 11.2453 5.30633V9.00351C11.2453 10.8521 9.80297 12.331 8.00009 12.331C6.1972 12.331 4.75489 10.8521 4.75489 9.00351V5.30633ZM15.5 10.1132C15.5 9.70651 15.1755 9.37377 14.7788 9.37377C14.4183 9.37377 14.0938 9.66954 14.0577 10.0393C13.5529 13.034 11.0288 15.2892 8 15.2892C4.97115 15.2892 2.44712 13.034 1.94231 10.0393C1.90625 9.66954 1.58173 9.37377 1.22115 9.37377C0.824519 9.37377 0.5 9.70651 0.5 10.1132V10.2241C1.07692 13.6995 3.85337 16.3984 7.27885 16.7311V19.9223H4.15379C3.72896 19.9223 3.38456 20.2755 3.38456 20.7111C3.38456 21.1467 3.72896 21.4998 4.15379 21.4998H11.8461C12.2709 21.4998 12.6153 21.1467 12.6153 20.7111C12.6153 20.2755 12.2709 19.9223 11.8461 19.9223H8.72115V16.7311C12.1466 16.3984 14.9231 13.6995 15.4639 10.2611C15.4639 10.2426 15.473 10.2149 15.482 10.1872L15.482 10.1871C15.491 10.1594 15.5 10.1317 15.5 10.1132Z"
+                  fill="white"
+                />
+              </svg>
+              点击录制
+            </div>
+
+						<div class="a_b_b_b_record">
+							<div class="a_b_b_b_r_left">
+								<img src="../../../../assets/icon/classroomObservation/recordLeft.png" alt="">
+								<div>
+									<div>{{recordData.status==0?"录制中":recordData.status==1?"暂停":"结束"}}</div>
+									<span>{{ recordData.time }}</span>
+								</div>
+							</div>
+							<div class="a_b_b_b_r_right">
+								<div class="a_b_b_b_r_r_start">
+									<span></span>
+								</div>
+								<div class="a_b_b_b_r_r_stop">
+									<span></span>
+									<span></span>
+								</div>
+								<div class="a_b_b_b_r_r_end">
+									<span></span>
+								</div>
+							</div>
 						</div>
-					</div>
-				</div>
+          </div>
+        </div>
       </div>
       <!-- </div> -->
     </el-dialog>
@@ -38,25 +81,46 @@
 </template>
 
 <script>
-
 export default {
   data() {
     return {
       dialogVisible: false,
       userId: this.$route.query["userid"],
-			form: {
-				name: "",
+      status: 1, //0:初始状态   1:录制
+			recordData:{
+				time:0,
+				status:0,//0 录制中  1暂停  2结束
 			},
-			textAreaVale:"夏天来喽,又能吃上西瓜啦!我真的太喜欢在空调房吃西瓜了,这种感觉真的超爽!红彤彤的果肉和黑色的籽,西瓜就是夏天的标志。每次切开一个大大的西瓜,忍不住就想大口大口地吃,尤其在炎热的午后,这时候来一块冰镇西瓜,简直是人间美味,清凉透底!我也喜欢把西瓜切成小块,用小叉子一块一块品尝,仿佛在享受一场夏日盛宴,每一口都充满了甜蜜和清凉,仿佛所有的烦恼都被这清爽的滋味一扫而空。有时候我也会呼朋唤友,让朋友们来家里玩,大家围坐在一起吃着瓜,聊着天,笑声不断,再没有比这更惬意的日子了!这样的时光总让人觉得生活是如此美好。夏天来喽,又能吃上西瓜了,这种简单的快乐,真是让人难以抗拒!",
-		}
+      form: { 
+        name: ""
+      },
+      textAreaVale:
+        "夏天来喽,又能吃上西瓜啦!我真的太喜欢在空调房吃西瓜了,这种感觉真的超爽!红彤彤的果肉和黑色的籽,西瓜就是夏天的标志。每次切开一个大大的西瓜,忍不住就想大口大口地吃,尤其在炎热的午后,这时候来一块冰镇西瓜,简直是人间美味,清凉透底!我也喜欢把西瓜切成小块,用小叉子一块一块品尝,仿佛在享受一场夏日盛宴,每一口都充满了甜蜜和清凉,仿佛所有的烦恼都被这清爽的滋味一扫而空。有时候我也会呼朋唤友,让朋友们来家里玩,大家围坐在一起吃着瓜,聊着天,笑声不断,再没有比这更惬意的日子了!这样的时光总让人觉得生活是如此美好。夏天来喽,又能吃上西瓜了,这种简单的快乐,真是让人难以抗拒!",
+      rules: {
+        name: [
+          { required: true, trigger: "change", message: "请输入新的名称" },
+          {
+            min: 1,
+            max: 20,
+            trigger: "change",
+            message: "长度需在1-20个字符之间"
+          }
+        ]
+      }
+    };
   },
 
-
-  methods:{
-		open(){
-			this.dialogVisible = true;
-		},
-	}
+  methods: {
+    open() {
+      this.dialogVisible = true;
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+		start(){
+			this.status = 1;
+		}
+  }
 };
 </script>
 
@@ -83,7 +147,7 @@ export default {
   box-sizing: border-box;
   /* padding: 5px; */
   line-height: 22px;
-	font-size: 18px;
+  font-size: 18px;
   justify-content: center;
   /* text-align: left; */
 }
@@ -136,34 +200,129 @@ export default {
   display: none;
 }
 
-.a_box{
-	width: 100%;
-	height: 100%;
-	box-sizing: border-box;
-	padding: 20px 0;
+.a_box {
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+  padding: 20px 0;
 }
 
-.a_b_form{
-	width: 100%;
-	height: calc(100% - 70px);
-	background-color: yellow;
+.a_b_form {
+  width: 100%;
+  height: calc(100% - 70px);
 }
 
-.a_b_bottom{
-	width: 100%;
-	height: 70px;
-	background-color: red;
+.a_b_bottom {
+  width: 100%;
+  height: 70px;
 }
 
-.a_b_b_top{
+.a_b_b_top {
+  width: 100%;
+  height: 15px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 14px;
+  color: #5e9afc;
+  margin-top: 0px;
+  cursor: default;
+  box-sizing: border-box;
+  padding-top: 10px;
+}
+
+.a_b_b_bottom {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.a_b_b_b_btn {
+  padding: 10px 20px;
+  background-color: #3681fc;
+  border-radius: 20px;
+  font-size: 16px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+  cursor: pointer;
+}
+
+.a_b_b_b_btn > svg {
+  width: 20px;
+  height: 20px;
+  margin-right: 5px;
+}
+
+.a_b_f_item {
+  margin-bottom: 10px;
+}
+
+.a_b_f_item >>> .el-form-item__label {
+  padding: 0;
+  font-size: 20px;
+  font-weight: bold;
+}
+
+.a_b_f_itemTextArea {
+  width: 100%;
+  height: 390px;
+  border: 1px solid #e7e7e7;
+  border-radius: 4px;
+  box-sizing: border-box;
+  padding: 10px;
+  overflow: auto;
+}
+.a_b_f_itemTextArea > div {
+  background-color: #f0f2f566;
+  border: 1px dashed #f0f2f5;
+  border-radius: 4px;
+  color: #0000008e;
+  box-sizing: border-box;
+  padding: 5px;
+  font-size: 16px;
+	line-height: 30px;
+}
+
+.a_b_b_b_record{
 	width: 100%;
-	height: 15px;
-	background-color: blue;
+	height: 100%;
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+}
+
+.a_b_b_b_r_left{
 	display: flex;
 	align-items: center;
 	justify-content: center;
-	font-size: 14px;
 }
 
+.a_b_b_b_r_left>div{
+	height: 100%;
+	width: auto;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	margin-left: 10px;
+}
+
+.a_b_b_b_r_left>div>div{
+	font-weight: bold;
+	margin-bottom: 5px;
+}
+
+.a_b_b_b_r_left>div>span{
+	color: #3681FC;
+}
+
+.a_b_b_b_r_right{
+	display: flex;
+	align-items: center;
+	justify-content: flex-end;
+}
 
 </style>

+ 3 - 1
src/components/pages/classroomObservation/components/analysis.vue

@@ -5,11 +5,12 @@
         <span :class="['a-h-l-icon', showItem ? 'a-h-l-showIcon' : '']"></span>
         <span class="a-h-l-title" v-if="!editTitle">{{ title }}</span>
         <div class="a_h_l_t_input" v-if="editTitle" @click.stop="() => {}">
-          <el-form ref="form" :model="form" :rules="rules" label-position="top">
+          <el-form ref="form" :model="form" :rules="rules" label-position="top" @submit.native.prevent>
             <el-form-item prop="name">
               <el-input
                 v-model="form.name"
                	@blur="editNameCheckFn()"
+								@keyup.enter.native="editNameCheckFn"
                 ref="editNameInputRef"
                 placeholder="请输入新的名称"
               ></el-input>
@@ -295,6 +296,7 @@ export default {
       // this.$refs.editNameDialogRef.open(this.title)
     },
     editNameCheckFn() {
+			if(!this.editTitle)return;
       this.$refs["form"].validate(valid => {
         if (valid) {
           this.editTitle = false;

+ 37 - 1
src/components/pages/classroomObservation/components/analysisItem.vue

@@ -7,11 +7,12 @@
 				></span>
 				<span class="ai-h-l-text" v-if="!editTitle">{{ data.jsonData.anotherName?data.jsonData.anotherName:data.jsonData.name }}</span>
 				<div class="a_h_l_t_input" v-if="editTitle" @click.stop="() => {}">
-          <el-form ref="form" :model="form" :rules="rules" label-position="top">
+          <el-form ref="form" :model="form" :rules="rules" label-position="top" @submit.native.prevent>
             <el-form-item prop="name">
               <el-input
                 v-model="form.name"
                	@blur="editNameCheckFn()"
+								 @keyup.enter.native="editNameCheckFn()"
                 ref="editNameInputRef"
                 placeholder="请输入新的名称"
               ></el-input>
@@ -116,6 +117,21 @@
 					</el-tooltip>
 				</span>
 
+				<span v-if="loadNum != 1 && openItem && tid && ['1', '2', '3'].includes(data.jsonData.echartsType)" @click="editEcharts()">
+					<el-tooltip
+						class="item"
+						effect="light"
+						content="生成图表"
+						placement="top"
+					>
+						<img
+							:src="
+								require('../../../../assets/icon/classroomObservation/echartIcon.svg')
+							"
+						/>
+					</el-tooltip>
+				</span>
+
 				<!-- <span class="ai-h-r-icon4" @click.stop="delBtn()"></span> -->
 			</div>
 		</div>
@@ -279,6 +295,13 @@ export default {
 
 				let _msg = `使用文件检索的方式完整的去分析文件内容,并请完全按照要求输出。`
 
+				if(!assistant){
+					this.loading = false;
+					this.loadNum = 2;
+					type = 3;
+					return this.$message.error("未找到对应的AI助手");
+				}
+
 				if (assistant.agentid) {
 					type = 0
 				}else if(assistant.tips){
@@ -480,6 +503,7 @@ export default {
       // this.$refs.editNameDialogRef.open(this.title)
     },
     editNameCheckFn() {
+			if(!this.editTitle)return;
       this.$refs["form"].validate(valid => {
         if (valid) {
           this.editTitle = false;
@@ -492,6 +516,18 @@ export default {
         }
       });
     },
+		editEcharts(){
+			console.log("生成图标")
+			if(this.data.jsonData.echartsType == "1"){
+				this.$message.info("词云图")
+			}else if(this.data.jsonData.echartsType == "2"){
+				this.$message.info("雷达图")
+			}else if(this.data.jsonData.echartsType == "3"){
+				this.$message.info("柱状图")
+			}else{
+				return this.$message.error("该模板不是图表模板")
+			}
+		}
 	},
 	mounted() {
 		if (this.data.jsonData.content) {

+ 3 - 1
src/components/pages/classroomObservation/components/analysisSpecialItem.vue

@@ -8,11 +8,12 @@
 				<span class="ai-h-l-text" v-if="!editTitle">{{ data.jsonData.anotherName?data.jsonData.anotherName:data.jsonData.name }}</span>
 
 				<div class="a_h_l_t_input" v-if="editTitle" @click.stop="() => {}">
-          <el-form ref="form" :model="form" :rules="rules" label-position="top">
+          <el-form ref="form" :model="form" :rules="rules" label-position="top" @submit.native.prevent>
             <el-form-item prop="name">
               <el-input
                 v-model="form.name"
                	@blur="editNameCheckFn()"
+								 @keyup.enter.native="editNameCheckFn()"
                 ref="editNameInputRef"
                 placeholder="请输入新的名称"
               ></el-input>
@@ -658,6 +659,7 @@ export default {
       // this.$refs.editNameDialogRef.open(this.title)
     },
     editNameCheckFn() {
+			if(!this.editTitle)return;
       this.$refs["form"].validate(valid => {
         if (valid) {
           this.editTitle = false;

File diff suppressed because it is too large
+ 0 - 46
src/components/pages/classroomObservation/components/analysisTemplateDialog.vue


+ 1 - 1
src/components/pages/classroomObservation/components/chatArea.vue

@@ -152,7 +152,7 @@
             <!-- <div class="ca-b-o-h-l-btn">
               <div class="ca-b-o-h-b-l-text" @click.stop="showTeacherVoiceprintBox = !showTeacherVoiceprintBox">{{choseTeacherVoiceprint?choseTeacherVoiceprint.name+'的':'教师'}}声纹</div>
               <div class="ca_teacherVoiceprintBox" style="cursor: default;" v-click-outside="()=>showTeacherVoiceprintBox = !showTeacherVoiceprintBox" v-if="showTeacherVoiceprintBox">
-                <div class="ca_tvb_itemHead" @click.stop="test()">
+                <div class="ca_tvb_itemHead" @click.stop="addNewTeacherVoiceprintBtn()">
                   <svg
                     width="12"
                     height="12"

+ 215 - 182
src/components/pages/classroomObservation/components/messageArea.vue

@@ -273,7 +273,11 @@
       @success="bindingForm"
     />
     <!-- 保存模板 -->
-    <saveTemplateDialog ref="saveTemplateDialogRef" :dataList="dataList" />
+    <saveTemplateDialog
+      ref="saveTemplateDialogRef"
+      :bmData="bmData"
+      :dataList="dataList"
+    />
     <!-- 分析模板 -->
     <analysisTemplateDialog
       ref="analysisTemplateDialogRef"
@@ -449,6 +453,7 @@ export default {
     useTemplate(json) {
       let _result = [];
       json.forEach(i => {
+				if(i.isOtherData)return _result.push(i);
         let _obj = {
           jsonData: i.jsonData,
           type: i.Type,
@@ -456,10 +461,12 @@ export default {
         };
         _result.push(_obj);
       });
+      // return console.log(_result);
       this.$parent
         .addNewCourseByTemplate(_result)
         .then(res => {
           this.$refs.analysisTemplateDialogRef.close();
+
           this.$refs.analysisTemplateDialogRef.loading = false;
         })
         .catch(e => {
@@ -474,7 +481,7 @@ export default {
       this.$refs.saveTemplateDialogRef.open();
       // this.$message.info("另存为模板");
     },
-    addAnalysisItem(name, id) {
+    addAnalysisItem(name, id, type) {
       return new Promise((resolve, reject) => {
         var OpenCC = require("opencc-js");
         let converter = OpenCC.Converter({
@@ -499,14 +506,14 @@ export default {
           return this.$message.error("未找到对应的AI助手");
         }
         let newIndexData = this.dataList
-          .filter(i => i.Type == assistant.type)
+          .filter(i => i.Type == type)
           .sort((a, b) => new Date(a.createtime) - new Date(b.createtime));
         newIndexData = newIndexData.length
           ? newIndexData[newIndexData.length - 1]
           : null;
         let newIndex = newIndexData
           ? newIndexData.tIndex + 1
-          : assistant.type == 0
+          : type == 0
           ? 2
           : 0;
         let params = {
@@ -516,13 +523,14 @@ export default {
             name: assistant.name,
             anotherName: assistant.name,
             mId: assistant.id,
+            echartsType: assistant.echartsType,
             result: assistant.detail,
             fileList: [],
             dataFileList: [],
             content: ""
           }),
           tid: this.tid,
-          type: assistant.type.toString()
+          type: type
         };
 
         // 这里调用添加
@@ -555,171 +563,183 @@ export default {
     },
     getCurrencyAndBaseMessageData() {
       if (!this.tid) return;
-      let pram = {
-        tid: this.tid,
-        // tid:'02',
-        type: "0"
-      };
-      this.currencyLoading = true;
-      this.dialogTagList.find(i => i.value == 0).loading = true;
-      this.baseMessageLoading = true;
-      this.bmData = {
-        id: "",
-        tId: this.tid,
-        tIndex: 0,
-        jsonData: {
-          activity_methods: "",
-          activity_structure: "",
-          classroom_resources: "",
-          courseName: "",
-          name: "",
-          studentNum: 0,
-          subject: "",
-          textbook: ""
-        }
-      };
-      this.imageList = [];
-      this.dataList = [];
-      this.dialogTagList = [
-        { value: 0, name: "通用课堂分析", loading: false },
-        { value: 1, name: "学科课堂分析", loading: false },
-        { value: 2, name: "扩展分析", loading: false }
-      ];
-      this.ajax
-        .post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
-        .then(res => {
-          let _data = res.data.FunctionResponse.result.length
-            ? JSON.parse(res.data.FunctionResponse.result)
-            : [];
-          if (_data.length == 0) {
-            return this.insertBaseMessage().then(_ => {
-              this.getCurrencyAndBaseMessageData();
-            });
+      return new Promise(resolve => {
+        let pram = {
+          tid: this.tid,
+          // tid:'02',
+          type: "0"
+        };
+        this.currencyLoading = true;
+        this.dialogTagList.find(i => i.value == 0).loading = true;
+        this.baseMessageLoading = true;
+        this.bmData = {
+          id: "",
+          tId: this.tid,
+          tIndex: 0,
+          jsonData: {
+            activity_methods: "",
+            activity_structure: "",
+            classroom_resources: "",
+            courseName: "",
+            name: "",
+            studentNum: 0,
+            subject: "",
+            textbook: ""
           }
-          let _bmData = _data.find(i => i.tIndex == 0);
-          let _dialogTagList = [];
-          // 基础信息
-          _bmData.jsonData = JSON.parse(_bmData.jsonData);
-          _dialogTagList = _bmData.jsonData.dialogTagList || [
-            { value: 0, name: "通用课堂分析", loading: false },
-            { value: 1, name: "学科课堂分析", loading: false },
-            { value: 2, name: "扩展分析", loading: false }
-          ];
-          // 图片
-          let _imageList = _data.find(i => i.tIndex == 1);
-          _imageList.jsonData = JSON.parse(_imageList.jsonData);
+        };
+        this.imageList = [];
+        this.dataList = [];
+        this.dialogTagList = [
+          { value: 0, name: "通用课堂分析", loading: false },
+          { value: 1, name: "学科课堂分析", loading: false },
+          { value: 2, name: "扩展分析", loading: false }
+        ];
+        this.ajax
+          .post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
+          .then(res => {
+            let _data = res.data.FunctionResponse.result.length
+              ? JSON.parse(res.data.FunctionResponse.result)
+              : [];
+            if (_data.length == 0) {
+              return this.insertBaseMessage().then(_ => {
+                this.getCurrencyAndBaseMessageData();
+              });
+            }
+            let _bmData = _data.find(i => i.tIndex == 0);
+            let _dialogTagList = [];
+            // 基础信息
+            _bmData.jsonData = JSON.parse(_bmData.jsonData);
+            _dialogTagList = _bmData.jsonData.dialogTagList || [
+              { value: 0, name: "通用课堂分析", loading: false },
+              { value: 1, name: "学科课堂分析", loading: false },
+              { value: 2, name: "扩展分析", loading: false }
+            ];
+            // 图片
+            let _imageList = _data.find(i => i.tIndex == 1);
+            _imageList.jsonData = JSON.parse(_imageList.jsonData);
 
-          if (!_imageList.jsonData.videoList) {
-            _imageList.jsonData.videoList = [];
-          }
-          if (!_imageList.jsonData.NephogramList) {
-            _imageList.jsonData.NephogramList = [];
-          }
-          //通用分析
-          let currency = [];
-          for (let i = 2; i < _data.length; i++) {
-            let _currency = _data[i];
-            _currency.jsonData = JSON.parse(_currency.jsonData);
-            currency.push(_currency);
-          }
+            if (!_imageList.jsonData.videoList) {
+              _imageList.jsonData.videoList = [];
+            }
+            if (!_imageList.jsonData.NephogramList) {
+              _imageList.jsonData.NephogramList = [];
+            }
+            //通用分析
+            let currency = [];
+            for (let i = 2; i < _data.length; i++) {
+              let _currency = _data[i];
+              _currency.jsonData = JSON.parse(_currency.jsonData);
+              currency.push(_currency);
+            }
 
-          this.dataList.push(...currency);
-          this.bmData = _bmData;
-          this.dialogTagList = _dialogTagList;
-          this.$emit("changeTranscription", {
-            transcriptionData: this.bmData.jsonData.transcriptionData
-              ? this.bmData.jsonData.transcriptionData
-              : "",
-            editorBarData: this.bmData.jsonData.editorBarData
-              ? this.bmData.jsonData.editorBarData
-              : { type: "0", content: "", url: "" }
+            this.dataList.push(...currency);
+            this.bmData = _bmData;
+            this.dialogTagList = _dialogTagList;
+            this.$emit("changeTranscription", {
+              transcriptionData: this.bmData.jsonData.transcriptionData
+                ? this.bmData.jsonData.transcriptionData
+                : "",
+              editorBarData: this.bmData.jsonData.editorBarData
+                ? this.bmData.jsonData.editorBarData
+                : { type: "0", content: "", url: "" }
+            });
+            this.imageList = _imageList;
+            if (this.imageList.jsonData.fileList.length > 0) {
+              this.$emit(
+                "changeChatAreaAudioUrl",
+                this.imageList.jsonData.fileList[0]
+              );
+            } else {
+              this.$emit("changeChatAreaAudioUrl", { name: "", url: "" });
+            }
+            this.$emit("updateTime", this.bmData.createtime);
+            this.baseMessageLoading = false;
+            this.dialogTagList.find(i => i.value == 0).loading = false;
+            this.currencyLoading = false;
+            resolve();
+          })
+          .catch(e => {
+            this.$message.error("获取通用分析失败");
+            console.log(e);
+            resolve();
           });
-          this.imageList = _imageList;
-          if (this.imageList.jsonData.fileList.length > 0) {
-            this.$emit(
-              "changeChatAreaAudioUrl",
-              this.imageList.jsonData.fileList[0]
-            );
-          } else {
-            this.$emit("changeChatAreaAudioUrl", { name: "", url: "" });
-          }
-          this.$emit("updateTime", this.bmData.createtime);
-          this.baseMessageLoading = false;
-          this.dialogTagList.find(i => i.value == 0).loading = false;
-          this.currencyLoading = false;
-        })
-        .catch(e => {
-          this.$message.error("获取通用分析失败");
-          console.log(e);
-        });
+      });
     },
     getScienceData() {
       if (!this.tid) return;
-      let pram = {
-        tid: this.tid,
-        // tid:'02',
-        type: "1"
-      };
-      this.scienceLoading = true;
-      this.dialogTagList.find(i => i.value == 1).loading = true;
-      this.ajax
-        .post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
-        .then(res => {
-          let _data = res.data.FunctionResponse.result.length
-            ? JSON.parse(res.data.FunctionResponse.result)
-            : [];
-          if (_data.length == 0) {
+      return new Promise(resolve => {
+        let pram = {
+          tid: this.tid,
+          // tid:'02',
+          type: "1"
+        };
+        this.scienceLoading = true;
+        this.dialogTagList.find(i => i.value == 1).loading = true;
+        this.ajax
+          .post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
+          .then(res => {
+            let _data = res.data.FunctionResponse.result.length
+              ? JSON.parse(res.data.FunctionResponse.result)
+              : [];
+            if (_data.length == 0) {
+              this.dialogTagList.find(i => i.value == 1).loading = false;
+              return (this.scienceLoading = false);
+            }
+            let science = [];
+            for (let i = 0; i < _data.length; i++) {
+              let _science = _data[i];
+              _science.jsonData = JSON.parse(_science.jsonData);
+              science.push(_science);
+            }
+            this.dataList.push(...science);
             this.dialogTagList.find(i => i.value == 1).loading = false;
-            return (this.scienceLoading = false);
-          }
-          let science = [];
-          for (let i = 0; i < _data.length; i++) {
-            let _science = _data[i];
-            _science.jsonData = JSON.parse(_science.jsonData);
-            science.push(_science);
-          }
-          this.dataList.push(...science);
-          this.dialogTagList.find(i => i.value == 1).loading = false;
-          this.scienceLoading = false;
-        })
-        .catch(e => {
-          this.$message.error("获取科学分析失败");
-          console.log(e);
-        });
+            this.scienceLoading = false;
+            resolve();
+          })
+          .catch(e => {
+            this.$message.error("获取科学分析失败");
+            resolve();
+            console.log(e);
+          });
+      });
     },
     getExtendData() {
       if (!this.tid) return;
-      let pram = {
-        tid: this.tid,
-        // tid:'02',
-        type: "2"
-      };
-      this.extendLoading = true;
-      this.dialogTagList.find(i => i.value == 2).loading = true;
-      this.ajax
-        .post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
-        .then(res => {
-          let _data = res.data.FunctionResponse.result.length
-            ? JSON.parse(res.data.FunctionResponse.result)
-            : [];
-          if (_data.length == 0) {
+      return new Promise(resolve => {
+        let pram = {
+          tid: this.tid,
+          // tid:'02',
+          type: "2"
+        };
+        this.extendLoading = true;
+        this.dialogTagList.find(i => i.value == 2).loading = true;
+        this.ajax
+          .post("https://gpt4.cocorobo.cn/get_classroom_observation_new", pram)
+          .then(res => {
+            let _data = res.data.FunctionResponse.result.length
+              ? JSON.parse(res.data.FunctionResponse.result)
+              : [];
+            if (_data.length == 0) {
+              this.dialogTagList.find(i => i.value == 2).loading = false;
+              return (this.extendLoading = false);
+            }
+            let extent = [];
+            for (let i = 0; i < _data.length; i++) {
+              let _extent = _data[i];
+              _extent.jsonData = JSON.parse(_extent.jsonData);
+              extent.push(_extent);
+            }
+            this.dataList.push(...extent);
             this.dialogTagList.find(i => i.value == 2).loading = false;
-            return (this.extendLoading = false);
-          }
-          let extent = [];
-          for (let i = 0; i < _data.length; i++) {
-            let _extent = _data[i];
-            _extent.jsonData = JSON.parse(_extent.jsonData);
-            extent.push(_extent);
-          }
-          this.dataList.push(...extent);
-          this.dialogTagList.find(i => i.value == 2).loading = false;
-          this.extendLoading = false;
-        })
-        .catch(e => {
-          this.$message.error("获取扩展分析失败");
-          console.log(e);
-        });
+            this.extendLoading = false;
+            resolve();
+          })
+          .catch(e => {
+            this.$message.error("获取扩展分析失败");
+            console.log(e);
+            resolve();
+          });
+      });
     },
     getValueAddedData() {
       if (!this.tid) return;
@@ -761,33 +781,42 @@ export default {
       }
     },
     getData() {
-      this.dataList = [];
-      if (this.tid) {
-        this.getCurrencyAndBaseMessageData();
-        this.getScienceData();
-        this.getExtendData();
-      } else {
-        this.getDefaultData();
-      }
+      return new Promise(resolve => {
+        this.dataList = [];
+        if (this.tid) {
+          Promise.all([
+            this.getCurrencyAndBaseMessageData(),
+            this.getScienceData(),
+            this.getExtendData()
+          ]).then(res => {
+            resolve();
+          });
+        } else {
+          this.getDefaultData()
+        }
+      });
       // this.getValueAddedData();
       // this.getFileId();
     },
     getDefaultData() {
       if (this.tid) return;
-      let params = {
-        uid: this.userId
-      };
-      this.loading = true;
-      this.ajax
-        .get(this.$store.state.api + "selectClassroomDefault", params)
-        .then(res => {
-          let _data = res.data[0][0];
-          if (_data) {
-            _data.tips = JSON.parse(_data.tips);
-            this.dataList = _data.tips;
-          }
-          this.loading = false;
-        });
+      return new Promise(resolve => {
+        let params = {
+          uid: this.userId
+        };
+        this.loading = true;
+        this.ajax
+          .get(this.$store.state.api + "selectClassroomDefault", params)
+          .then(res => {
+            let _data = res.data[0][0];
+            if (_data) {
+              _data.tips = JSON.parse(_data.tips);
+              this.dataList = _data.tips;
+            }
+            this.loading = false;
+						resolve();
+          });
+      });
     },
     saveData(data) {
       return new Promise((resolve, reject) => {
@@ -1078,8 +1107,12 @@ export default {
           this.$message.error("获取模块分析列表失败");
         });
     },
-    changeAnalysisName(data) {
-      this.dialogTagList.find(i => i.value == data.type).name = data.name;
+    changeAnalysisName(data,type = 0) {
+			if(type==0){
+				this.dialogTagList.find(i => i.value == data.type).name = data.name;
+			}else if(type==1){
+				this.dialogTagList = data;
+			}
       this.bmData.jsonData["dialogTagList"] = this.dialogTagList;
       this.saveData(this.bmData).then(res => {
         // this.$message.success("修改名称成功");

+ 17 - 9
src/components/pages/classroomObservation/components/saveTemplateDialog.vue

@@ -61,7 +61,11 @@ export default {
 		dataList:{
 			type:Array,
 			default:()=>{return []}
-		}
+		},
+		bmData:{
+			type:Object,
+			default:()=>{return {}}
+		},
 	},
 	data() {
 		return {
@@ -128,13 +132,7 @@ export default {
 						
 						_data.forEach(i=>{
 							if(converter(i.jsonData.name)==converter('词频词汇分析')){
-								i.jsonData.wordNum = 0;
-								i.jsonData.wordCountNum = 0;
-								i.createtime = "";
-								i.jsonData.content = "";
-								i.id = "",
-								i.tId = "",
-								i.userid = "";
+								return
 							}else{
 								i.jsonData.content = "";
 								i.jsonData.dataFileList = [];
@@ -143,10 +141,20 @@ export default {
 								i.id = "",
 								i.tId = "",
 								i.userid = "";
+								_result.push(i)
 							}
 							
-							_result.push(i)
+							
 						})
+
+						let otherData = {
+							isOtherData:true,
+							dialogTagList:this.bmData.jsonData.dialogTagList,
+						}
+						_result.push(otherData)
+						// console.log(_result)
+						// this.loading = false
+						// return
 						let params = [{
 							title:this.form.name,
 							subject:this.form.subject,

File diff suppressed because it is too large
+ 781 - 724
src/components/pages/classroomObservation/index.vue


+ 115 - 39
src/components/pages/components/exportDataDialog.vue

@@ -106,28 +106,33 @@
                 alt=""
               />
             </div>
-            <div class="zhBlockCon"><el-rate v-model="star"></el-rate></div>
+            <div class="zhBlockCon">
+              <div class="zhBlockCon">{{ star }} / 5.0</div>
+            </div>
+          </div>
+          <div class="zhBlock">
+            <div class="zhBlockTit">
+              <span style="margin-right: 5px">包含学科</span
+              ><img
+                src="../../../assets/icon/exportPdfworks/infocircle.svg"
+                alt=""
+              />
+            </div>
+            <div class="zhBlockCon2">
+              <div>
+               <span v-for="(i,index) in subject" :key="index">{{ i }}</span>
+              </div>
+            </div>
           </div>
-          <!-- <div class="zhBlock">
-                <div class="zhBlockTit">
-                  <span style="margin-right: 5px">包含学科</span
-                  ><img src="../assets/img/infocircle.svg" alt="" />
-                </div>
-                <div class="zhBlockCon2">
-                  <span>语文</span>
-                  <span>数学</span>
-                  <span>英语</span>
-                  <span>化学</span>
-                  <span>美术</span>
-                </div>
-              </div> -->
         </div>
-        <div style="display: flex; height: 370px; margin: 10px 0">
-          <div style="width: 50%">
-            <div ref="chart" style="width: 100%; height: 360px"></div>
+        <div
+          style="display: flex;justify-content: space-between; height: 310px;margin-bottom: 30px"
+        >
+          <div class="zxt" style="width: 49%">
+            <div ref="chart" style="width: 100%; height: 300px"></div>
           </div>
-          <div style="width: 50%">
-            <div ref="ringChart" style="height: 360px; width: 100%"></div>
+          <div class="zxt" style="width: 49%">
+            <div ref="ringChart" style="height: 300px; width: 100%"></div>
           </div>
         </div>
         <!-- 作业提交率 -->
@@ -230,7 +235,7 @@ export default {
 
       // 作业得分折线图开始
       taskList: [], //每个阶段下有几个任务
-      scoFoldLineData: [],
+      scoFoldLineData: [], //课程得分图数据
       // 作业得分折线图结束
 
       // 分数工具柱状图开始
@@ -266,6 +271,8 @@ export default {
       // 处理过的分组
       TeaStuInt2: [1, 3, 5, 4, 10, 13, 15],
 
+      subject:[],
+
       data3: [],
       data4: [],
       data5: [],
@@ -395,9 +402,17 @@ export default {
       for (let i = 0; i < this.tableData.length; i++) {
         this.loading = true;
 
+        this.toolRatio = [
+          { name: "互动类", value: 0 },
+          { name: "思维类", value: 0 },
+          { name: "协作类", value: 0 },
+          { name: "测评类", value: 0 },
+          { name: "评价类", value: 0 },
+          { name: "编程类", value: 0 },
+          { name: "学科类", value: 0 }
+        ];
         this.uid2 = this.tableData[i].userid;
         this.worksDialogCon2 = this.tableData[i];
-        // await this.getCourseDetail();
         await this.getData();
         let a = await this.getPdf2();
         pdfList.push(a);
@@ -413,7 +428,7 @@ export default {
         saveAs(content, _this.courseTit + "-学生报告汇总.zip");
       });
 
-      //   this.$emit("update:worksDialog", false);
+      this.$emit("update:worksDialog", false);
       // this.worksDialog = false;
     },
     // 压缩pdf
@@ -457,6 +472,7 @@ export default {
       });
     },
     async getData() {
+      this.subject=[]
       let params = {
         cid: this.cid,
         uid: this.worksDialogCon2.userid,
@@ -469,6 +485,9 @@ export default {
             this.cState = res.data[0][0].state;
             this.courseTit = res.data[0][0].title;
 
+            let sub = res.data[9][0].subject
+            this.subject = sub.split(',')
+
             this.imgList.forEach(e => {
               if (e.schoolId == this.oid) {
                 this.schoolImg = e;
@@ -506,6 +525,7 @@ export default {
 
             // 处理这个课程下的工具分类
             let data = JSON.parse(res.data[0][0].chapters);
+            
 
             if (this.cState == 1) {
               this.getDataStageMode(data);
@@ -528,6 +548,17 @@ export default {
     },
     // ai模式处理数据
     getDataAiMode(data) {
+      this.toolData = [[], [], [], [], [], [], []];
+      this.taskList = []; //每个阶段下有几个任务
+      this.toolPercentage = [];
+      this.interact = [];
+      this.interactWork = [];
+      this.stuInterAllWork = [];
+      this.stuInterAllLike = [];
+      this.bdStuInterAllWork = [];
+      this.bdStuInterAllLike = [];
+      this.stageList = [];
+      this.stageListPer = [];
       data.forEach((e, eInd) => {
         let toolList = e.chapterInfo[0].taskJson;
         toolList.forEach((i, iInd) => {
@@ -586,7 +617,9 @@ export default {
       this.toolRatio[4].value = this.toolData[4].length;
       this.toolRatio[5].value = this.toolData[5].length;
       this.toolRatio[6].value = this.toolData[6].length;
-
+      this.toolRatio = this.toolRatio.filter(e => {
+        return e.value != 0;
+      });
       // console.log("this.toolRatio[0]", this.toolRatio);
       // 作业提交率折线图
       let repeatWork = this.newArrFn(this.data3);
@@ -628,9 +661,21 @@ export default {
     },
     // 阶段模式处理数据
     getDataStageMode(data) {
+      this.toolData = [[], [], [], [], [], [], []];
+      this.taskList = []; //每个阶段下有几个任务
+      this.toolPercentage = [];
+      this.interact = [];
+      this.interactWork = [];
+      this.stuInterAllWork = [];
+      this.stuInterAllLike = [];
+      this.bdStuInterAllWork = [];
+      this.bdStuInterAllLike = [];
+      this.stageList = [];
+      this.stageListPer = [];
+
       data.forEach((e, eInd) => {
         let toolList = e.chapterInfo[0].taskJson;
-        this.toolPercentage[eInd] = [];
+        this.toolPercentage[eInd] = []; // 每个任务有的工具
         // X轴数据
         this.stageList.push("阶段" + (eInd * 1 + 1));
         // 作业提交率基础数据
@@ -648,6 +693,8 @@ export default {
         this.bdStuInterAllLike[eInd] = []; // 生生互动阶段被动点赞评论分类
 
         // 每个阶段下有多少个任务
+        console.log("toolList", JSON.parse(JSON.stringify(toolList)));
+
         this.taskList[eInd] = toolList;
 
         toolList.forEach(i => {
@@ -691,7 +738,9 @@ export default {
       this.toolRatio[4].value = this.toolData[4].length;
       this.toolRatio[5].value = this.toolData[5].length;
       this.toolRatio[6].value = this.toolData[6].length;
-
+      this.toolRatio = this.toolRatio.filter(e => {
+        return e.value != 0;
+      });
       // 作业提交率折线图
       let repeatWork = this.newArrFn(this.data3);
       this.getFoldLineData(repeatWork);
@@ -814,15 +863,13 @@ export default {
         );
       });
       this.scoFoldLineData = scoList;
-      // console.log("this.scoFoldLineData", this.scoFoldLineData);
 
       let zSco = 0;
       this.scoFoldLineData.forEach(e => {
         zSco += e * 1;
       });
 
-      this.star = (zSco / this.scoFoldLineData.length).toFixed(0) * 1;
-      // console.log("this.star", this.star);
+      this.star = (zSco / this.scoFoldLineData.length).toFixed(1) * 1;
     },
 
     getFoldLineData(repeatWork) {
@@ -923,8 +970,7 @@ export default {
         zSco += e * 1;
       });
 
-      this.star = (zSco / this.scoFoldLineData.length).toFixed(0) * 1;
-      // console.log("this.star", this.star);
+      this.star = (zSco / this.scoFoldLineData.length).toFixed(1) * 1;
     },
     // 师生互动数据
     getTeaStuHdAi(TeaStuHdData) {
@@ -1049,6 +1095,8 @@ export default {
             labelLine: {
               show: false
             },
+            center: ["40%", "50%"], // 控制饼图的位置
+
             data: this.toolRatio
           }
         ]
@@ -1075,7 +1123,10 @@ export default {
         },
         xAxis: {
           type: "category",
-          data: this.stageList.map(item => item)
+          data: this.stageList.map(item => item),
+          axisTick: {
+            alignWithLabel: true // 使刻度线和标签对齐
+        }
         },
         yAxis: {
           type: "value",
@@ -1099,7 +1150,7 @@ export default {
       const chart = echarts.init(this.$refs.cScoEcharts);
       const option = {
         title: {
-          text: this.cState == 1?'阶段成绩':'任务成绩',
+          text: this.cState == 1 ? "阶段成绩" : "任务成绩",
           left: "left",
           textStyle: {
             color: "rgba(140, 140, 140, 1)", // 标题颜色
@@ -1112,7 +1163,10 @@ export default {
         },
         xAxis: {
           type: "category",
-          data: this.stageList.map(item => item)
+          data: this.stageList.map(item => item),
+          axisTick: {
+            alignWithLabel: true // 使刻度线和标签对齐
+        }
         },
         yAxis: {
           type: "value",
@@ -1191,7 +1245,10 @@ export default {
         },
         xAxis: {
           type: "category",
-          data: this.stageList.map(item => item)
+          data: this.stageList.map(item => item),
+          axisTick: {
+            alignWithLabel: true // 使刻度线和标签对齐
+        }
         },
         yAxis: {
           type: "value",
@@ -1228,7 +1285,10 @@ export default {
         },
         xAxis: {
           type: "category",
-          data: this.stageList.map(item => item)
+          data: this.stageList.map(item => item),
+          axisTick: {
+            alignWithLabel: true // 使刻度线和标签对齐
+        }
         },
         yAxis: {
           type: "value",
@@ -1265,7 +1325,10 @@ export default {
         },
         xAxis: {
           type: "category",
-          data: this.stageList.map(item => item)
+          data: this.stageList.map(item => item),
+          axisTick: {
+            alignWithLabel: true // 使刻度线和标签对齐
+        }
         },
         yAxis: {
           type: "value",
@@ -1480,16 +1543,28 @@ export default {
 }
 .zhBlockCon2 {
   display: flex;
-  flex-wrap: wrap;
+  flex-direction: column;
+  justify-content: space-between;
+  /* flex-wrap: wrap; */
+  flex: 1;
   overflow: hidden;
 }
-.zhBlockCon2 > span {
+.zhBlockCon2 > div {
+
+  display: flex;
+  flex-wrap: wrap;
+
+  flex: 1;
+}
+.zhBlockCon2 > div >span{
   font-size: 8px;
   font-weight: 400;
   color: rgba(0, 0, 0, 0.9);
   background-color: rgba(243, 247, 253, 1);
   border-radius: 2px;
-  padding: 1px 4px;
+  padding: 0px 4px;
+  height: 15px;
+  line-height: 15px;
   box-sizing: border-box;
   margin-right: 4px;
   margin-bottom: 2px;
@@ -1497,6 +1572,7 @@ export default {
 .zxt {
   height: 300px;
   width: 100%;
+  border: 1px solid #ccc;
   margin: 10px 0;
   background-color: rgba(255, 255, 255, 1);
   padding: 10px 0;

+ 3 - 1
src/components/pages/components/exportWorksDialog.vue

@@ -458,7 +458,9 @@
                           v-for="(r, tarIndex) in item.data"
                           :key="tarIndex"
                         >
-                          <span> {{ r.target }}</span>
+                        <span v-if="state == 5"> {{ r.target }}</span>
+                        <span v-else> {{ r.target[r.target.length-1] }}</span>
+                          <!-- <span> {{ r.target }}</span> -->
                         </div>
                       </div>
                     </div>

+ 1 - 1
src/components/pages/components/studentWorksDetail.vue

@@ -1400,7 +1400,7 @@
                           <span>{{ checkJson[sIndex].allRight + "%" }}</span>
                         </div>
                       </div> -->
-                      <div v-if="worksDetail[sIndex].eList.length">
+                      <div v-if="worksDetail[sIndex].eList && worksDetail[sIndex].eList.length">
                         <!-- <div class="ech" style="margin-left: 23px">
                           <img src="../../../assets/icon/pj/score.png" alt="" />
                         </div> -->

+ 22 - 4
src/components/pages/components/worksDetail2.vue

@@ -1362,7 +1362,7 @@
                     </div>
                      
                    
-                      <div v-if="worksDetail[sIndex].eList.length">
+                      <div v-if="worksDetail[sIndex].eList && worksDetail[sIndex].eList.length">
                        
                         <div>
                           <div class="score_boxTit"><span>分数详情</span></div>
@@ -1408,10 +1408,18 @@
 
                             <el-rate
                               class="rate_size"
+                              v-if="worksDetail[sIndex].state == 5"
                               style="min-width: 120px"
                               v-model="worksDetail[sIndex].rateList[item.detail]"
                               @change="getStar(sIndex)"
                             ></el-rate>
+                            <el-rate
+                              class="rate_size"
+                              v-else
+                              style="min-width: 120px"
+                              v-model="worksDetail[sIndex].rateList[item.value]"
+                              @change="getStar(sIndex)"
+                            ></el-rate>
                           </div>
                         </div>
                         <div class="worksTarget" v-if="isShow(worksDetail[sIndex].eList)"><span>目标</span></div>
@@ -2713,7 +2721,11 @@ export default {
                 result[l].eList = eList;
                 for (var i = 0; i < eList.length; i++) {
                   _ooption.push({ value: 0, name: eList[i].value });
-                  result[l].rateList[eList[i].detail] = 0;
+                  if (this.DState == 5) {
+                    result[l].rateList[eList[i].detail] = 0;                          
+                  }else{
+                    result[l].rateList[eList[i].value] = 0;                          
+                  }
                 }
                 result[l].rateList.content = "";
                 this.ooption[l] = _ooption;
@@ -2766,7 +2778,11 @@ export default {
                     
                       for (var i = 0; i < eList.length; i++) {
                         _ooption.push({ value: 0, name: eList[i].value });
-                        result[l].rateList[eList[i].detail] = 0;
+                        if (this.DState == 5) {
+                          result[l].rateList[eList[i].detail] = 0;                          
+                        }else{
+                          result[l].rateList[eList[i].value] = 0;                          
+                        }
                       }
                       result[l].rateList.content = "";
                       this.ooption[l] = _ooption;
@@ -3195,7 +3211,7 @@ export default {
     },
     updatePj() {
       for (var i = 0; i < this.worksDetail.length; i++) {
-        if (!this.worksDetail[i].eList.length) {
+        if (this.worksDetail[i].eList && !this.worksDetail[i].eList.length) {
           continue;
         }
         this.updateWorks(
@@ -3243,6 +3259,8 @@ export default {
         rate: rateList,
         uid: this.studentId,
       };
+      // return console.log('params',params);
+      
       const k = i;
       this.ajax
         .get(this.$store.state.api + "updateWorksEva", params)

+ 1 - 1
src/components/pages/components/worksDetail3.vue

@@ -1051,7 +1051,7 @@
                     </div>
                      
                    
-                      <div v-if="worksDetail[sIndex].eList.length">
+                      <div v-if="worksDetail[sIndex].eList && worksDetail[sIndex].eList.length">
                        
                         <div>
                           <div class="score_boxTit"><span>分数详情</span></div>

+ 14 - 3
src/components/pages/works.vue

@@ -565,10 +565,21 @@ export default {
     },
     // 一键导出pdf
     exportPdfSetAllBtn(){
-      this.worksDialog = true;
 
-      this.digNum = 1
-      this.exportW++
+      this.$confirm("是否导出全部学生报告?批量打印需要等待一会哦。", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+      .then(() => {
+        this.worksDialog = true;
+        this.digNum = 1
+        this.exportW++
+      })
+      .catch(_ => {
+        this.$confirm.visible=false
+      })
+     
       
     },
     goTo(path) {

Some files were not shown because too many files changed in this diff