Pārlūkot izejas kodu

Merge branch 'beta' of https://git.cocorobo.cn/CocoRoboLabs/pbl-student-table into beta

lsc 4 dienas atpakaļ
vecāks
revīzija
024d50f8e0
32 mainītis faili ar 3546 papildinājumiem un 308 dzēšanām
  1. 1 1
      dist/index.html
  2. 0 0
      dist/static/css/app.d9946d6e19502a2a9afddc0427753271.css
  3. 0 0
      dist/static/css/app.d9946d6e19502a2a9afddc0427753271.css.map
  4. 0 0
      dist/static/css/app.fec9f226c7ef0e394154f6ad67368beb.css.map
  5. 0 0
      dist/static/js/app.201d1e16b1beb54901ae.js
  6. 0 0
      dist/static/js/app.201d1e16b1beb54901ae.js.map
  7. 0 0
      dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map
  8. 0 0
      dist/static/js/vendor.acbd8cb5870df69e0141.js
  9. 0 0
      dist/static/js/vendor.acbd8cb5870df69e0141.js.map
  10. 1 0
      package.json
  11. 1 1
      src/common/tools.js
  12. 99 0
      src/components/EnglishVoice3/component/left.vue
  13. 18 0
      src/components/EnglishVoice3/component/report.vue
  14. 1009 0
      src/components/EnglishVoice3/component/right.vue
  15. 382 0
      src/components/EnglishVoice3/component/testRole new.vue
  16. 206 0
      src/components/EnglishVoice3/component/testRole.vue
  17. 228 0
      src/components/EnglishVoice3/index.vue
  18. 130 44
      src/components/classRoomHelper/component/languageAssistant.vue
  19. 138 44
      src/components/classRoomHelper/component/levitatedSphere.vue
  20. 125 17
      src/components/classRoomHelper/component/searchArea.vue
  21. 728 161
      src/components/components/choseWorksDetailDialog.vue
  22. 1 1
      src/components/components/onlineWrite.vue
  23. 133 3
      src/components/components/studentWorkPreviewDialog.vue
  24. 1 1
      src/components/easy2/commpont/onlineWrite.vue
  25. 81 7
      src/components/easy2/studyStudent.vue
  26. 1 1
      src/components/easy3/commpont/onlineWrite.vue
  27. 83 9
      src/components/easy3/studyStudent.vue
  28. 96 8
      src/components/studyStudent.vue
  29. 1 1
      src/components/studySutdentClass/commpont/onlineWrite.vue
  30. 81 7
      src/components/studySutdentClass/studyStudent.vue
  31. 1 1
      src/components/trainCourse/easy2/commpont/onlineWrite.vue
  32. 1 1
      src/components/trainCourse/easy3/commpont/onlineWrite.vue

+ 1 - 1
dist/index.html

@@ -27,7 +27,7 @@
     html,
     body{
       font-family: '黑体';
-    }</style><link href=./static/css/app.fec9f226c7ef0e394154f6ad67368beb.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.d6d47d008c180699b2a1.js></script><script type=text/javascript src=./static/js/app.bc06dbcf97679f72fe8c.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.d9946d6e19502a2a9afddc0427753271.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.acbd8cb5870df69e0141.js></script><script type=text/javascript src=./static/js/app.201d1e16b1beb54901ae.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/css/app.d9946d6e19502a2a9afddc0427753271.css


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/css/app.d9946d6e19502a2a9afddc0427753271.css.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/css/app.fec9f226c7ef0e394154f6ad67368beb.css.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/js/app.201d1e16b1beb54901ae.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/js/app.201d1e16b1beb54901ae.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/js/vendor.acbd8cb5870df69e0141.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/static/js/vendor.acbd8cb5870df69e0141.js.map


+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "build": "node build/build.js"
   },
   "dependencies": {
+    "@microsoft/fetch-event-source": "^2.0.1",
     "axios": "^0.21.3",
     "big.js": "^6.2.1",
     "dayjs": "^1.11.7",

+ 1 - 1
src/common/tools.js

@@ -32,7 +32,7 @@ export const tools = {
     67: { name: "分子结构" },
     68: { name: "时间轴" },
     69: { name: "英语写作" },
-    69: { name: "英语口语" },
+    70: { name: "英语口语" },
     25: { name: "目标管理" },
     26: { name: "课程设计" },
     71: { name: "AI智能体" },

+ 99 - 0
src/components/EnglishVoice3/component/left.vue

@@ -0,0 +1,99 @@
+<template>
+    <div class="o_box">
+        <div class="o_box_title">
+            <div>标题</div>
+            <div>{{ title }}</div>
+        </div>
+        <div class="o_box_topic">
+            <div class="o_box_child" v-for="(item, index) in checkJson" :key="index" :class="{active:checkType == index}" @click="setType(index)">
+                <el-tooltip :content="item.content.slice(0,130) + (item.content.length > 130 ? '...' : '')" placement="top" effect="dark" popper-class="text_tooltip2">
+                    <!-- content to trigger tooltip here -->
+                    <span>{{ index + 1  }}.{{ item.content }}</span>
+                </el-tooltip>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        title: {
+            type: String,
+        },
+        detail: {
+            type: String,
+        }, 
+        checkJson: {
+            type: Array,
+        }, 
+        checkType: {
+            type: Number,
+        },
+    },
+    methods: {
+        setType(index) {
+            this.$emit('setType', index)
+        }
+    },
+
+
+}
+
+</script>
+
+<style scoped>
+.o_box{
+    width: 100%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px 15px;
+    box-sizing:border-box;
+}
+.o_box_title{
+    width:100%;
+    margin-bottom: 25px;
+}
+.o_box_title > div + div{
+    margin-top: 8px;
+}
+
+.o_box_title > div:nth-child(1){
+ color: #00000066;
+ font-size: 14px;
+ letter-spacing: 6px;
+}
+.o_box_title > div:nth-child(2){
+    color:#3981FA;
+    font-size: 24px;
+    font-style: italic;
+}
+
+.o_box_topic{}
+.o_box_child{
+    height: 42px;
+    display: flex;
+    align-items: center;
+    color: #000;
+    border-radius: 5px;
+    border: 1px solid #3681FC;
+    margin-bottom: 10px;
+    width: 100%;
+    padding: 0 10px;
+    box-sizing: border-box;
+    cursor: pointer;
+}
+.o_box_child.active{
+    background: #3681FC;
+    color: #fff;
+}
+
+.o_box_child > span{
+    width: 100%;
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    word-wrap: break-word;
+}
+</style>

+ 18 - 0
src/components/EnglishVoice3/component/report.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="reportBox"></div>
+</template>
+
+<script>
+export default {};
+</script>
+
+<style scoped>
+.reportBox {
+  background: #fff;
+  width: 800px;
+  height: 300px;
+  position: absolute;
+  bottom: -320px;
+  right: 45px;
+}
+</style>

+ 1009 - 0
src/components/EnglishVoice3/component/right.vue

@@ -0,0 +1,1009 @@
+<template>
+  <div class="o_box" ref="obox">
+    <div class="o_top">
+
+    </div>
+    <div class="o_content">
+      <div class="type_box" :style="{ width: oWidth }" v-if="cjson.type !== 'createRole'">
+        {{ getType(cjson) }}
+      </div>
+      <div class="word_box" v-if="cjson.type == 'word' || cjson.type == 'QA'" ref="wb">
+        <div class="word_bbox" :style="{ maxHeight: oheight }">
+          <img class="word_img" :src="cjson.img" alt="" v-if="cjson.img" @click="previewImg(cjson.img)">
+          <div class="word_content" v-html="cjson.content">
+          </div>
+        </div>
+      </div>
+      <div class="sentence_box" v-if="cjson.type == 'sentence'" ref="wb">
+        <span v-html="cjson.content"></span>
+        <div v-if="cjson.img" class="sentence_div">
+          <img :src="cjson.img" alt="" @click="previewImg(cjson.img)">
+        </div>
+      </div>
+      <div class="word_box" v-if="cjson.type == 'theme'" ref="wb" style="max-height: calc(100% - 95px);">
+        <div class="word_bbox" :style="{ maxHeight: oheight }">
+          <div class="word_content" v-html="cjson.content"></div>
+          <div class="word_content2" v-html="cjson.content2" v-if="cjson.content2"></div>
+        </div>
+      </div>
+      <div class="tips_box" v-if="cjson.type == 'theme' && !isRecord && !LuAudioUrl">提示:准备完成后,点击话筒开始录音</div>
+      <div class="time_box" v-if="cjson.type == 'theme' && isRecord">
+        <span>倒计时</span>
+        <span>{{ Times.min }}:{{ Times.secode }}</span>
+      </div>
+      <testRole v-if="cjson.type == 'createRole'" :checkJson="answerArray"></testRole>
+    </div>
+    <div class="o_bottom" v-loading="isloading">
+      <div class="star_box" v-if="LuAudioUrl && star > 0">
+        <div class="star" v-for="index2 in 5" :key="'star' + index2" :class="{ starA: star >= (index2) }">
+        </div>
+      </div>
+      <div class="audio" v-if="!LuAudioUrl">
+        <img v-if="!isRecord" src="../../../assets/icon/englishVoice/start_aduio.png" alt="" @click="startRecorder">
+        <img v-else src="../../../assets/icon/englishVoice/stop_audio.png" alt="" @click="startRecorder">
+      </div>
+      <div class="audio_word" v-if="!LuAudioUrl">
+        <span v-if="!isRecord">点击话筒开始录音</span>
+        <span v-else>点击话筒结束录音</span>
+      </div>
+      <div v-if="LuAudioUrl" class="audio_b">
+        <mini-audio :audio-source="LuAudioUrl" class="audio_class"></mini-audio>
+      </div>
+      <div v-if="LuAudioUrl" class="audio_rerecord" @click="restart()">
+        <span>录音</span>
+      </div>
+      <div class="audio_index" v-if="!isRecord">
+        <div class="audio_index_last" :class="{ disabled: checkType == 0 }" @click="checkIndex('-1')">
+          <img src="../../../assets/icon/englishVoice/coin.png" alt="">
+        </div>
+        <div class="audio_index_content">
+          <span>{{ checkType + 1 }}</span>
+          <span>/</span>
+          <span>{{ checkJson.length }}</span>
+        </div>
+        <div class="audio_index_next" :class="{ disabled: checkType == (checkJson.length - 1) }"
+          @click="checkIndex('1')">
+          <img src="../../../assets/icon/englishVoice/coin.png" alt="">
+        </div>
+      </div>
+      <div v-else class="audio_ing">
+        <span>正在录音...</span>
+      </div>
+    </div>
+    <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;"
+      src="https://beta.cloud.cocorobo.cn/browser/public/index.html" ref="iiframe" v-show="false"></iframe>
+  </div>
+</template>
+
+<script>
+import Recorder from "js-audio-recorder";
+const lamejs = require("lamejs");
+
+const recorder = new Recorder({
+  sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
+  sampleRate: 48000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
+  numChannels: 1, // 声道,支持 1 或 2, 默认是1
+  // compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
+});
+
+// 绑定事件-打印的是当前录音数据
+recorder.onprogress = function (params) {
+  // console.log('--------------START---------------')
+  // console.log('录音时长(秒)', params.duration);
+  // console.log('录音大小(字节)', params.fileSize);
+  // console.log('录音音量百分比(%)', params.vol);
+  // console.log('当前录音的总数据([DataView, DataView...])', params.data);
+  // console.log('--------------END---------------')
+};
+import testRole from "./testRole.vue";
+export default {
+  components: {
+    testRole,
+  },
+  props: {
+    checkJson: {
+      type: Array,
+    },
+    checkType: {
+      type: Number,
+    },
+    work: {
+      type: Array
+    }
+  },
+  data() {
+    return {
+      cjson: {},
+      LuAudioUrl: "",
+      isRecord: false,
+      isPlayerRecord: false,
+      isloading: false,
+      oheight: 'auto',
+      oWidth: '500px',
+      calcTimer: null,
+      totalSeconds: 0,
+      answerArray: [],
+      id: this.guid(),
+      star: 0
+    }
+  },
+  computed: {
+    // oheight: function() {
+    //   // 获取父元素
+    //   var parentElement = this.$refs['wb'];
+
+    //   // 计算父元素的高度
+    //   var parentHeight = parentElement.offsetHeight;
+    //   return parentHeight + 'px'
+    // }
+    getType() {
+      return function (json) {
+        if (json.type == 'word') {
+          return '单词/词组'
+        } else if (json.type == 'QA') {
+          return '问答题目'
+        } else if (json.type == 'sentence') {
+          return '句子/短文'
+        } else if (json.type == 'theme') {
+          return '主题陈述'
+        }
+      };
+    },
+    Times() {
+      let min = this.totalSeconds ? Math.floor(this.totalSeconds / 60) : 0
+      let secode = this.totalSeconds ? this.totalSeconds % 60 : 0
+      let time = {
+        min: min >= 10 ? min : '0' + min,
+        secode: secode >= 10 ? secode : '0' + secode
+      }
+      return time;
+    },
+  },
+  watch: {
+    checkType: {
+      handler: function (newVal, oldVal) {
+        this.isloading = false
+        this.cjson = JSON.parse(JSON.stringify(this.checkJson[newVal]));
+        this.LuAudioUrl = ''
+        if (typeof this.work[newVal] == 'string') {
+          this.LuAudioUrl = this.work[newVal] ? JSON.parse(JSON.stringify(this.work[newVal])) : ''
+        } else if (typeof this.work[newVal] == 'object' && this.cjson.type != 'createRole') {
+          this.LuAudioUrl = this.work[newVal].audio ? JSON.parse(JSON.stringify(this.work[newVal].audio)) : ''
+        } else if (typeof this.work[newVal] == 'object' && this.cjson.type == 'createRole') {
+          var a = Array.isArray(this.work[newVal])
+          if (a) {
+            this.answerArray = JSON.parse(JSON.stringify(this.work[newVal]))
+          } else {
+            this.answerArray = []
+            this.answerArray.push(
+              {
+                isY: false,
+                content: this.cjson.content3,
+                name: this.cjson.content,
+                img: this.cjson.img
+              }
+            )
+          }
+          this.$emit('setWork', this.answerArray, this.checkType)
+        }
+        if (!this.work[newVal] && this.cjson.type == 'createRole') {
+          var a = Array.isArray(this.work[newVal])
+          if (a) {
+            this.answerArray = JSON.parse(JSON.stringify(this.work[newVal]))
+          } else {
+            this.answerArray = []
+            this.answerArray.push(
+              {
+                isY: false,
+                content: this.cjson.content3,
+                name: this.cjson.content,
+                img: this.cjson.img
+              }
+            )
+          }
+          this.$emit('setWork', this.answerArray, this.checkType)
+        }
+        this.star = this.work[newVal] ? (this.work[newVal].score ? JSON.parse(JSON.stringify(this.work[newVal].score)) : 0) : 0
+        this.oheight = 'auto'
+        this.oWidth = '500px'
+        const images = this.$refs['obox'].querySelectorAll('img');
+        let loadedCount = 0;
+
+        // if(images.length){
+        //   images.forEach((image) => {
+        //     image.addEventListener('load', () => {
+        //       loadedCount++;
+
+        //       if (loadedCount === images.length) {
+        //         this.calculateParentHeight()
+        //       }
+        //     });
+        //   });
+        // }else{
+        if (this.cjson.type != "createRole") {
+          this.calculateParentHeight()
+        }
+        if (this.cjson.type == "createRole") {
+          this.createRole(this.cjson.content2, this.cjson.content)
+        }
+        // }
+
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    previewImg(url) {
+      this.$hevueImgPreview(url);
+    },
+    restart() {
+      let _this = this
+      _this.$confirm("确定重新录音么?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          _this.LuAudioUrl = ""
+          setTimeout(() => {
+            _this.startRecorder()
+          }, 500);
+        })
+        .catch(() => { });
+    },
+    checkIndex(type) {
+      if (type == '1') {
+        if (this.checkType == (this.checkJson.length - 1)) {
+          return;
+        }
+        this.$emit('setType', this.checkType + 1)
+      } else {
+        if (this.checkType == 0) {
+          return;
+        }
+        this.$emit('setType', this.checkType - 1)
+      }
+    },
+    // 开始录音
+    startRecorder() {
+      let _this = this;
+      if (!_this.isRecord) {
+        recorder.destroy(); // 销毁录音
+        _this.isRecord = true;
+        if (this.cjson.type == 'theme') {
+          this.setSecodes()
+        }
+        recorder.start().then(
+          () => { },
+          (error) => {
+            _this.isRecord = false;
+            // _this.$message.error(`${error.name} : ${error.message}`);
+            _this.$message.error(`没有找到可使用的麦克风,或者您没有允许此网页使用麦克风`);
+            // 出错了
+            console.log(`${error.name} : ${error.message}`);
+            if (_this.calcTimer) {
+              clearInterval(_this.calcTimer)
+              _this.calcTimer = null;
+            }
+          }
+        );
+      } else {
+        if (_this.calcTimer) {
+          clearInterval(_this.calcTimer)
+          _this.calcTimer = null;
+        }
+        _this.isRecord = false;
+        recorder.stop(); // 结束录音
+        this.getMp3Data()
+      }
+    },
+
+    // 录音播放
+    playRecorder() {
+      if (!recorder.fileSize) {
+        return;
+      }
+      if (!this.isPlayerRecord) {
+        this.isPlayerRecord = true;
+        recorder.play();
+      } else {
+        this.isPlayerRecord = false;
+        recorder.stopPlay(); // 停止录音播放
+      }
+      recorder.onplayend = () => {
+        this.isPlayerRecord = false;
+        console.log("onplayend");
+      };
+    },
+
+    /**
+     * 文件格式转换 wav-map3
+     * */
+    getMp3Data() {
+      if (!recorder.fileSize) {
+        this.$message.error("请录音后在上传语音");
+        return;
+      }
+
+      const mp3Blob = recorder.getWAVBlob();
+      // const mp3Blob = this.convertToMp3(recorder.getWAV());
+      let audioFile = this.dataURLtoAudio(mp3Blob, "wav");
+      console.log(audioFile);
+      let iiframe = this.$refs['iiframe']
+
+
+
+      // this.isloading = true
+      //   this.beforeUpload1(audioFile, 3);
+      //   return;
+      if (this.cjson.type == 'theme' || this.cjson.type == 'QA') {
+        this.isloading = true
+        let _this = this
+				let _result = ``;
+        iiframe.contentWindow.onRecognizedResult = function (e) {
+          console.log('onRecognizedResult', e);
+          let privText = e.privText
+					_result+=privText;
+
+          // _this.beforeUpload1(audioFile, 3, privText);
+        }
+
+				iiframe.contentWindow.onSessionStopped = function(e){
+					console.log("转译完成")
+					console.log(e);
+					_this.beforeUpload1(audioFile, 3, _result);
+				}
+
+        iiframe.contentWindow.doContinuousPronunciationAssessment('', { files: [audioFile] })
+      } else if (this.cjson.type == 'createRole') {
+        // this.isloading = true
+        // this.beforeUpload1(audioFile, 3);
+        this.isloading = true
+        let _this = this
+				let _result = ``;
+        iiframe.contentWindow.onRecognizedResult = function (e) {
+          console.log('onRecognizedResult', e);
+          let privText = e.privText
+					_result+=privText;
+          // _this.beforeUpload1(audioFile, 3, privText);
+        }
+
+				iiframe.contentWindow.onSessionStopped = function(e){
+					console.log("转译完成")
+					console.log(e);
+					_this.beforeUpload1(audioFile, 3, _result);
+				}
+
+        iiframe.contentWindow.doContinuousPronunciationAssessment('', { files: [audioFile] })
+      } else {
+        this.isloading = true
+        let _this = this
+				let _result = ``;
+				let _star = ``;
+        iiframe.contentWindow.onRecognizedResult = function (e) {
+          console.log('onRecognizedResult', e);
+          let privText = e.privText
+					_result +=privText;
+          _star = JSON.parse(e.privJson).NBest[0].PronunciationAssessment
+					console.log(_star)
+          // console.log('star', star)
+          // e.privText 
+          // JSON.parse(e.privJson).NBest[0].PronunciationAssessment
+
+          // _this.beforeUpload1(audioFile, 3, privText, star);
+        }
+
+				iiframe.contentWindow.onSessionStopped = function(e){
+					console.log("转译完成")
+					console.log(e);
+					_this.beforeUpload1(audioFile, 3, _result, _star);
+				}
+
+
+        iiframe.contentWindow.doContinuousPronunciationAssessment(this.cjson.content, { files: [audioFile] })
+      }
+
+      // recorder.download(mp3Blob, "recorder", "mp3");
+    },
+    convertToMp3(wavDataView) {
+      // 获取wav头信息
+      const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置
+      const { channels, sampleRate } = wav;
+      const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
+      // 获取左右通道数据
+      const result = recorder.getChannelData();
+      const buffer = [];
+      const leftData =
+        result.left &&
+        new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);
+      const rightData =
+        result.right &&
+        new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);
+      const remaining = leftData.length + (rightData ? rightData.length : 0);
+      const maxSamples = 1152;
+      for (let i = 0; i < remaining; i += maxSamples) {
+        const left = leftData.subarray(i, i + maxSamples);
+        let right = null;
+        let mp3buf = null;
+        if (channels === 2) {
+          right = rightData.subarray(i, i + maxSamples);
+          mp3buf = mp3enc.encodeBuffer(left, right);
+        } else {
+          mp3buf = mp3enc.encodeBuffer(left);
+        }
+        if (mp3buf.length > 0) {
+          buffer.push(mp3buf);
+        }
+      }
+
+      const enc = mp3enc.flush();
+      if (enc.length > 0) {
+        buffer.push(enc);
+      }
+      return new Blob(buffer, { type: "audio/wav" });
+    },
+    dataURLtoAudio(blob, filename) {
+      return new File([blob], filename, { type: "audio/wav" });
+    },
+    beforeUpload1(event, type, text, star) {
+      var file;
+      if (type == 3) {
+        file = event;
+      } else {
+        file = event.target.files[0];
+      }
+      var credentials = {
+        accessKeyId: "AKIATLPEDU37QV5CHLMH",
+        secretAccessKey: "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",
+      }; //秘钥形式的登录上传
+      window.AWS.config.update(credentials);
+      window.AWS.config.region = "cn-northwest-1"; //设置区域
+
+      var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
+      var _this = this;
+
+      if (file) {
+        var params = {
+          Key:
+            file.name.split(".")[0] +
+            new Date().getTime() +
+            "." +
+            file.name.split(".")[file.name.split(".").length - 1],
+          ContentType: file.type,
+          Body: file,
+          "Access-Control-Allow-Credentials": "*",
+          ACL: "public-read",
+        }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
+        var options = {
+          partSize: 2048 * 1024 * 1024,
+          queueSize: 2,
+          leavePartsOnError: true,
+        };
+        bucket
+          .upload(params, options)
+          .on("httpUploadProgress", function (evt) {
+            //这里可以写进度条
+            // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
+            // _this.progress = parseInt((evt.loaded * 80) / evt.total);
+          })
+          .send(function (err, data) {
+            if (_this.cjson.type != 'createRole') {
+              _this.isloading = false
+            }
+            // _this.progress = 100;
+            if (err) {
+              var a = _this.$refs.upload1.uploadFiles;
+              a.splice(a.length - 1, a.length);
+              _this.$message.error("上传失败");
+            } else {
+              if (type == 3) {
+                if (_this.cjson.type == 'createRole') {
+                  _this.answerArray.push(
+                    {
+                      isY: true,
+                      content: text,
+                      voice: data.Location,
+                      name: '',
+                      img: ''
+                    }
+                  )
+                  _this.answerCode(text)
+                } else {
+                  _this.LuAudioUrl = data.Location;
+                  _this.$emit('setWork', _this.LuAudioUrl, _this.checkType, text, star)
+                }
+
+
+              }
+              console.log(data.Location);
+            }
+          });
+      }
+    },
+    calculateParentHeight() {
+      this.$nextTick(() => {
+        setTimeout(() => {
+          // 获取父元素
+          var parentElement = this.$refs['wb'];
+
+          // 计算父元素的高度
+          // var parentHeight = parentElement.offsetHeight + 1;
+          var parentWidth = parentElement.offsetWidth;
+          // this.oheight = parentHeight + 'px'
+          this.oWidth = parentWidth + 'px'
+        }, 50);
+      });
+    },
+    setSecodes() {
+      this.totalSeconds = this.checkJson[this.checkType].oTime * 60
+      // this.totalSeconds = 10
+      this.calcTimer = setInterval(() => {
+        if (this.totalSeconds > 0) {
+          this.totalSeconds--;
+        } else {
+          clearInterval(this.calcTimer);
+          this.calcTimer = null
+          this.startRecorder()
+          console.log("倒计时结束"); // 输出日志
+        }
+      }, 1000);
+    },
+    answerCode(msg) {
+      var _this = this;
+      if (msg) {
+        _this.ajax.post('https://gpt4.cocorobo.cn/assistants_completion_response', {
+          uid: _this.id,
+          message: msg,
+        }).then(function (response) {
+          console.log(response);
+          _this.answerArray.push(
+            {
+              isY: false,
+              content: response.data.FunctionResponse,
+              name: _this.answerArray[0].name,
+              img: _this.answerArray[0].img
+            }
+          )
+          console.log(_this.answerArray);
+          _this.$forceUpdate()
+          _this.isloading = false
+          _this.$emit('setWork', _this.answerArray, _this.checkType)
+        }).catch(function (error) {
+          _this.isloading = false
+          console.log(error);
+        });
+      } else {
+        _this.answerArray.push(
+          {
+            isY: false,
+            content: "抱歉,您刚刚没有成功录入内容,请再说一遍!",
+            name: _this.answerArray[0].name,
+            img: _this.answerArray[0].img
+          }
+        )
+        _this.isloading = false
+      }
+    },
+    guid() {
+      var _num,
+        i,
+        _guid = "";
+      for (i = 0; i < 32; i++) {
+        _guid += Math.floor(Math.random() * 16).toString(16); //随机0  - 16 的数字 转变为16进制的字符串
+        _num = Math.floor((i - 7) / 4); //计算 (i-7)除4
+        if (_num > -1 && _num < 4 && i == 7 + 4 * _num) {
+          //会使guid中间加 "-"   形式为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+          _guid += "-";
+        }
+      }
+      return _guid;
+    },
+    createRole(content, name) {
+      var _this = this;
+      _this.ajax.post('https://gpt4.cocorobo.cn/create_free_assistants', {
+        fileName: [],
+        url: [],
+        uid: _this.id,
+        instructions: content,
+        assistantName: name
+      }).then(function (response) {
+        console.log(response);
+      }).catch(function (error) {
+        console.log(error);
+      });
+    }
+  },
+  beforeDestroy() {
+    if (!this.isRecord) {
+    } else {
+      if (this.calcTimer) {
+        clearInterval(this.calcTimer)
+        this.calcTimer = null;
+      }
+      recorder.stop(); // 结束录音
+    }
+  },
+  mounted() {
+
+    this.cjson = JSON.parse(JSON.stringify(this.checkJson[this.checkType]));
+    this.LuAudioUrl = ''
+    if (typeof this.work[this.checkType] == 'string') {
+      this.LuAudioUrl = this.work[this.checkType] ? JSON.parse(JSON.stringify(this.work[this.checkType])) : ''
+    } else if (typeof this.work[this.checkType] == 'object' && this.cjson.type != 'createRole') {
+      this.LuAudioUrl = this.work[this.checkType].audio ? JSON.parse(JSON.stringify(this.work[this.checkType].audio)) : ''
+    } else if (typeof this.work[this.checkType] == 'object' && this.cjson.type == 'createRole') {
+      var a = Array.isArray(this.work[this.checkType])
+      if (a) {
+        this.answerArray = JSON.parse(JSON.stringify(this.work[this.checkType]))
+      } else {
+        this.answerArray = []
+        this.answerArray.push(
+          {
+            isY: false,
+            content: this.cjson.content3,
+            name: this.cjson.content,
+            img: this.cjson.img
+          }
+        )
+      }
+      this.$emit('setWork', this.answerArray, this.checkType)
+    }
+    if (!this.work[this.checkType] && this.cjson.type == 'createRole') {
+      var a = Array.isArray(this.work[this.checkType])
+      if (a) {
+        this.answerArray = JSON.parse(JSON.stringify(this.work[this.checkType]))
+      } else {
+        this.answerArray = []
+        this.answerArray.push(
+          {
+            isY: false,
+            content: this.cjson.content3,
+            name: this.cjson.content,
+            img: this.cjson.img
+          }
+        )
+      }
+      this.$emit('setWork', this.answerArray, this.checkType)
+    }
+    this.star = this.work[this.checkType] ? (this.work[this.checkType].score ? JSON.parse(JSON.stringify(this.work[this.checkType].score)) : 0) : 0
+
+    if (this.cjson.type != "createRole") {
+      this.calculateParentHeight()
+    }
+    if (this.cjson.type == "createRole") {
+      this.createRole(this.cjson.content2, this.cjson.content)
+    }
+  },
+}
+</script>
+
+<style scoped>
+.o_box {
+  width: 100%;
+  height: 100%;
+  background-image: url('../../../assets/icon/env_background.png');
+  background-size: cover;
+}
+
+.o_top {
+  height: 65px;
+  position: absolute;
+}
+
+.o_content {
+  height: calc(100% - 210px);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  overflow: hidden;
+  flex-direction: column;
+}
+
+.o_bottom {
+  height: 210px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.word_box {
+  min-width: 500px;
+  max-width: 70%;
+  background: #fff;
+  border-radius: 10px;
+  position: relative;
+  /* max-height: calc(100% - 40px); */
+  max-height: calc(100% - 70px);
+  /* overflow: auto; */
+}
+
+.tips_box {
+  margin-top: 30px;
+  color: #727272;
+}
+
+.word_box>.word_bbox {
+  width: 100%;
+  position: relative;
+  z-index: 999;
+  max-height: 100%;
+  overflow: auto;
+}
+
+.sentence_box {
+  background: #e0e0e04d;
+  min-width: 500px;
+  max-width: 70%;
+  border-radius: 15px;
+  /* max-height: 100%; */
+  overflow: auto;
+  padding: 15px;
+  font-size: 16px;
+  color: #000;
+  line-height: 20px;
+  word-break: break-word;
+  white-space: pre-line;
+  max-height: calc(100% - 80px);
+}
+
+.word_box::before {
+  content: '';
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  display: block;
+  box-shadow: 0 0 4px 4px #1d39830d;
+  border-radius: 10px;
+  z-index: 2;
+  background: #fff;
+}
+
+.word_box::after {
+  content: '';
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  background: #fff;
+  display: block;
+  box-shadow: 0 0 4px 4px #1d39830d;
+  border-radius: 10px;
+  z-index: 1;
+  top: 15px;
+  left: 15px;
+}
+
+.word_box>.word_bbox>.word_img {
+  width: calc(100% - 30px);
+  max-height: 300px;
+  z-index: 999;
+  position: relative;
+  margin: 15px auto;
+  display: block;
+  border-radius: 10px;
+  cursor: pointer;
+  object-fit: contain;
+}
+
+
+.word_box>.word_bbox>.word_content {
+  position: relative;
+  z-index: 999;
+  text-align: center;
+  font-size: 36px;
+  margin: 15px;
+  font-weight: bold;
+  color: #000;
+  width: calc(100% - 30px);
+  word-break: break-word;
+  white-space: pre-line;
+}
+
+.word_box>.word_bbox>.word_content2 {
+  position: relative;
+  z-index: 999;
+  text-align: left;
+  font-size: 16px;
+  margin: 15px;
+  color: #727272;
+  width: calc(100% - 30px);
+  word-break: break-word;
+  white-space: pre-line;
+  /* margin-top: 10px; */
+}
+
+
+.o_bottom .audio {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.o_bottom .audio>img {
+  width: 75px;
+  height: 75px;
+  cursor: pointer;
+}
+
+.o_bottom .audio_word {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #00000099;
+  font-size: 16px;
+  margin: 10px 0 8px;
+}
+
+.o_bottom .audio_index {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+
+.audio_index_last,
+.audio_index_next {
+  height: 40px;
+  width: 40px;
+  background: #3681fc;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+
+.audio_index_last>img,
+.audio_index_next>img {
+  width: 15px;
+  height: auto;
+}
+
+.audio_index_last.disabled,
+.audio_index_next.disabled {
+  opacity: .6;
+}
+
+.audio_index_last>img {
+  transform: rotate(180deg);
+}
+
+.audio_index_last {
+  margin-right: 20px;
+}
+
+.audio_index_content {
+  color: #000;
+  font-size: 16px;
+}
+
+.audio_index_next {
+  margin-left: 20px;
+}
+
+
+.audio_ing {
+  color: #EE3E3E;
+  margin-top: 25px;
+  font-size: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.audio_b {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 15px;
+}
+
+.audio_rerecord {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 15px;
+}
+
+.audio_rerecord>span {
+  display: flex;
+  border: 1px solid #3981FA;
+  align-items: center;
+  color: #3981FA;
+  padding: 5px 10px;
+  border-radius: 5px;
+  cursor: pointer;
+}
+
+.audio_rerecord>span::before {
+  content: '';
+  width: 15px;
+  height: 15px;
+  background: url('../../../assets/icon/englishVoice/restart.png');
+  display: block;
+  background-size: 100% 100%;
+  margin-right: 5px;
+}
+
+.audio_class {
+  background: #3680fb !important;
+  margin: 0 !important;
+}
+
+.audio_b>>>.vueAudioBetter span:before {
+  color: #fff;
+}
+
+.audio_class>>>.slider .process {
+  background: #000;
+}
+
+.audio_b>>>.vueAudioBetter .iconfont:active {
+  position: unset !important;
+}
+
+.time_box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  margin-top: 25px;
+}
+
+.time_box>span:nth-child(1) {
+  color: #727272;
+  font-size: 16px;
+}
+
+.time_box>span:nth-child(2) {
+  /* margin-top: 10px; */
+  font-size: 32px;
+  color: #3581FC;
+}
+
+.type_box {
+  min-width: 500px;
+  width: 70%;
+  text-align: right;
+  color: #a5a5a5;
+  margin-bottom: 10px;
+}
+
+.sentence_div {
+  width: 100%;
+  overflow: hidden;
+  margin-top: 10px;
+  display: flex;
+  justify-content: flex-end;
+}
+
+.sentence_div>img {
+  width: 60px;
+  height: 60px;
+  object-fit: cover;
+  cursor: pointer;
+  border-radius: 4px
+}
+
+.star_box {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px
+}
+
+.star_box>.star {
+  width: 25px;
+  height: 25px;
+  display: block;
+  background-image: url('../../../assets/icon/englishVoice/star-no.png');
+  background-size: 100% 100%;
+}
+
+.star_box>.star+.star {
+  margin-left: 5px;
+}
+
+.star_box>.starA {
+  background-image: url('../../../assets/icon/englishVoice/star.png');
+}
+</style>

+ 382 - 0
src/components/EnglishVoice3/component/testRole new.vue

@@ -0,0 +1,382 @@
+<template>
+  <div class="d_box" v-loading="isloading">
+    <div class="dialog">
+      <div class="d_img">
+        <img
+          :src="require('../../../assets/icon/englishVoice/icon_portal.png')"
+          alt=""
+        />
+      </div>
+      <div class="d_content_message">
+        <div>Hello,以下是我们这次口语练习的要求:</div>
+        <div class="d_name" v-if="answerArray.time">
+          练习时长:{{
+            answerArray.time == "all" ? "不限时" : answerArray.time + "min"
+          }}
+        </div>
+        <div class="d_name" v-if="answerArray.difficulty">
+          设置难度:{{
+            answerArray.difficulty == 0
+              ? "简单"
+              : answerArray.difficulty == 1
+              ? "一般"
+              : "困难"
+          }}
+        </div>
+        <div
+          class="d_name"
+          v-if="fName && sName"
+          style="
+            display: flex;
+            flex-direction: row;
+            flex-wrap: nowrap;
+            align-items: center;
+            width: 100%;
+          "
+        >
+          <div style="min-width: 60px">对话主题:</div>
+          <div style="width: calc(100% - 80px)">
+            {{ fName - sName }}
+          </div>
+        </div>
+        <div class="gotoTalk">我已了解,开始对话</div>
+        <div class="nowTime">{{ currentTime }}</div>
+      </div>
+    </div>
+    <div class="dialog">
+      <div class="d_img">
+        <img
+          :src="require('../../../assets/icon/englishVoice/icon_portal.png')"
+          alt=""
+        />
+      </div>
+      <div class="d_content">
+        <div class="d_voice">
+          <mini-audio :audio-source="voice" class="audio_class"></mini-audio>
+        </div>
+        <div class="d_log">
+          {{ content }}
+        </div>
+      </div>
+      <div class="nowTime" style="margin: 0 0 0 50px">
+        {{ currentTime }}
+      </div>
+    </div>
+    <div class="dialog dialog_right">
+      <div class="d_img">
+        <img
+          :src="require('../../../assets/icon/englishVoice/icon_portal.png')"
+          alt=""
+        />
+      </div>
+      <div class="d_content">
+        <div class="d_voice">
+          <mini-audio :audio-source="voice" class="audio_class"></mini-audio>
+        </div>
+        <div class="d_log2">
+          {{ content }}
+        </div>
+      </div>
+      <report v-if="lookReport"></report>
+      <div
+        @click="lookReport = true"
+        class="reportButton"
+        :style="{ bottom: lookReport ? '-360px' : '-35px' }"
+      >
+        查看报告
+      </div>
+      <div
+        class="nowTime"
+        style="margin: 0 50px 0 0; bottom: -60px"
+        :style="{ bottom: lookReport ? '-390px' : '-60px' }"
+      >
+        {{ currentTime }}
+      </div>
+    </div>
+    <!-- <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;"
+                src="https://beta.cloud.cocorobo.cn/browser/public/index.html" ref="iiframe"></iframe> -->
+  </div>
+</template>
+    
+<script>
+import report from "./report.vue";
+export default {
+  components: {
+    report,
+  },
+  props: {
+    checkJson: {
+      type: Object,
+    },
+  },
+  data() {
+    return {
+      json: [],
+      answerArray: [],
+      isRecord: false,
+      isPlayerRecord: false,
+      isloading: false,
+      fName: "",
+      sName: "",
+      currentTime: "",
+      lookReport: false,
+      content:
+        "Read the following text aloud.A Car Accident I saw a car accident this morning. A boy wanted to cross the road but he did not look carefully. He just ran out into the road. A car was coming and the driver stopped at once. Luckily, the boy was not hurt. However, there was a bus behind the car. It could not stop and hit the back of the car. Someone called the police and they arrived quickly.",
+    };
+  },
+  methods: {
+    setVoiceJson(val) {
+      let a = JSON.parse(JSON.stringify(val));
+      // this.json = a;
+      this.answerArray = a;
+      // this.answerArray.push(
+      //     {
+      //         isY: false,
+      //         content: a.content3,
+      //         name: a.content,
+      //         img: a.img
+      //     }
+      // )
+    },
+    formatDate(date) {
+      const year = date.getFullYear();
+      const month = (date.getMonth() + 1).toString().padStart(2, "0");
+      const day = date.getDate().toString().padStart(2, "0");
+      const hours = date.getHours().toString().padStart(2, "0");
+      const minutes = date.getMinutes().toString().padStart(2, "0");
+      const seconds = date.getSeconds().toString().padStart(2, "0");
+
+      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+    },
+  },
+  watch: {
+    checkJson: {
+      handler: function (newVal, oldVal) {
+        if (newVal) {
+          this.setVoiceJson(this.checkJson);
+        }
+      },
+      deep: true,
+    },
+  },
+  created() {
+    this.currentTime = this.formatDate(new Date());
+  },
+  mounted() {
+    this.setVoiceJson(this.checkJson);
+  },
+};
+</script>
+    
+<style scoped>
+.d_box {
+  width: 100%;
+  height: 100%;
+  /* background: #000; */
+  padding: 25px 50px;
+  box-sizing: border-box;
+  overflow: auto;
+}
+
+.dialog_answer > img {
+  height: 100%;
+  margin-left: auto;
+  cursor: pointer;
+}
+
+.dialog {
+  display: flex;
+  position: relative;
+}
+
+.dialog + .dialog {
+  margin-top: 40px;
+}
+
+.dialog_right {
+  flex-direction: row-reverse;
+}
+
+.dialog > .d_img {
+  width: 40px;
+  height: 40px;
+  min-width: 40px;
+  overflow: hidden;
+  border-radius: 50%;
+  margin-right: 5px;
+}
+
+.dialog > .d_img > img {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+}
+
+.dialog_right > .d_img {
+  margin-right: 0;
+  margin-left: 5px;
+}
+
+.dialog > .d_content,
+.dialog > .d_content_message {
+  width: 100%;
+}
+.dialog > .d_content_message {
+  display: flex;
+  width: 300px;
+  background: #f6f9ff;
+  flex-direction: column;
+  flex-wrap: nowrap;
+  align-items: flex-start;
+  border-radius: 10px;
+  margin: 0 0 0 10px;
+  position: relative;
+}
+.dialog > .d_content_message > div {
+  padding: 5px;
+}
+.nowTime {
+  position: absolute;
+  bottom: -30px;
+  color: #9c9d9f;
+  font-size: 12px;
+}
+.dialog_right > .d_content,
+.dialog_right > .d_content_message {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+}
+
+.dialog > .d_content > .d_name,
+.dialog > .d_content_message > .d_name {
+  color: #7c7c7c;
+  font-size: 12px;
+  margin-bottom: 5px;
+}
+
+.dialog_right > .d_content > .d_name,
+.dialog_right > .d_content_message > .d_name {
+  text-align: right;
+}
+
+.dialog > .d_content > .d_log,
+.dialog > .d_content_message > .d_log {
+  color: #000;
+  font-size: 16px;
+  background: #fff;
+  width: 100%;
+  max-width: 800px;
+  border: 2px solid #e05d63;
+  border-radius: 40px;
+  line-height: 26px;
+  padding: 20px 35px;
+  box-sizing: border-box;
+  position: relative;
+}
+
+.dialog > .d_content > .d_log::before,
+.dialog > .d_content_message > .d_log::before {
+  content: "";
+  width: calc(100% - 20px);
+  height: calc(100% - 20px);
+  position: absolute;
+  border: 1px dashed #e05d63;
+  box-sizing: border-box;
+  top: 50%;
+  left: 50%;
+  border-radius: 30px;
+  transform: translate(-50%, -50%);
+}
+
+.dialog > .d_content > .d_log2,
+.dialog > .d_content_message > .d_log2 {
+  color: #000;
+  font-size: 14px;
+  background: #fff;
+  width: 100%;
+  max-width: 800px;
+  border: 1px dashed #0f94ce;
+  border-radius: 5px;
+  line-height: 26px;
+  padding: 10px;
+  box-sizing: border-box;
+  position: relative;
+  margin-top: 10px;
+}
+
+.dialog > .d_content > .d_voice,
+.dialog > .d_content_message > .d_voice {
+  width: 100%;
+  max-width: 600px;
+}
+
+.audio_class {
+  background: #3680fb !important;
+  margin: 0 !important;
+  width: 100% !important;
+  box-sizing: border-box !important;
+}
+
+.d_voice >>> .vueAudioBetter span:before {
+  color: #fff;
+}
+
+.audio_class >>> .slider .process {
+  background: #000;
+}
+
+.d_voice >>> .vueAudioBetter .iconfont:active {
+  position: unset !important;
+}
+
+.gotoTalk {
+  margin: 0 5px 10px 5px;
+  background: #3681fc;
+  color: #fff;
+  text-align: center;
+  width: calc(100% - 20px);
+  height: 30px;
+  line-height: 30px;
+  padding: 0 !important;
+  border-radius: 5px;
+  cursor: pointer;
+}
+
+.checkFooter {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+  justify-content: flex-end;
+}
+.checkFooter > div {
+  min-width: 100px;
+  width: 100px;
+  text-align: center;
+  border-radius: 5px;
+  background: #ffffff;
+  color: #3681fc;
+  border: 1px solid #3681fc;
+  height: 35px;
+  line-height: 35px;
+  margin-right: 10px;
+  font-size: 12px;
+  cursor: pointer;
+}
+
+.reportButton {
+  position: absolute;
+  bottom: -35px;
+  right: 50px;
+  background: #16c267;
+  color: #fff;
+  width: 70px;
+  height: 25px;
+  text-align: center;
+  line-height: 25px;
+  cursor: pointer;
+  border-radius: 5px;
+}
+</style>
+    

+ 206 - 0
src/components/EnglishVoice3/component/testRole.vue

@@ -0,0 +1,206 @@
+<template>
+    <div class="d_box" v-loading="isloading">
+        <div class="dialog" v-for="(item, index) in answerArray" :key="index" :class="{ dialog_right: item.isY }">
+            <div class="d_img">
+                <img :src="item.img ? item.img : require('../../../assets/icon/englishVoice/icon_portal.png')" alt="">
+            </div>
+            <div class="d_content">
+                <div class="d_name" v-if="item.name">{{ item.name }}</div>
+                <div class="d_voice" v-if="item.voice">
+                    <mini-audio :audio-source="item.voice" class="audio_class"></mini-audio>
+                </div>
+                <div :class="{d_log: !item.isY, d_log2: item.isY}" v-if="item.content">{{ item.content }}</div>
+            </div>
+        </div>
+        <!-- <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;"
+                src="https://beta.cloud.cocorobo.cn/browser/public/index.html" ref="iiframe"></iframe> -->
+    </div>
+</template>
+    
+<script>
+export default {
+    components: {
+    },
+    props: {
+        checkJson: {
+            type: Object,
+        }
+    },
+    data() {
+        return {
+            json: [],
+            answerArray: [],
+            isRecord: false,
+            isPlayerRecord: false,
+            isloading: false,
+        };
+    },
+    methods: {
+        setVoiceJson(val) {
+            let a = JSON.parse(JSON.stringify(val));
+            // this.json = a;
+            this.answerArray = a
+            // this.answerArray.push(
+            //     {
+            //         isY: false,
+            //         content: a.content3,
+            //         name: a.content,
+            //         img: a.img
+            //     }
+            // )
+
+        },
+    },
+    watch: {
+        checkJson: {
+            handler: function (newVal, oldVal) {
+                if (newVal) {
+                    this.setVoiceJson(this.checkJson);
+                }
+            },
+            deep: true
+        }
+    },
+
+    mounted() {
+        this.setVoiceJson(this.checkJson);
+    }
+};
+</script>
+    
+<style scoped>
+.d_box {
+    width: 100%;
+    height: 100%;
+    /* background: #000; */
+    padding: 25px 50px;
+    box-sizing: border-box;
+    overflow: auto;
+}
+
+.dialog_answer>img {
+    height: 100%;
+    margin-left: auto;
+    cursor: pointer;
+}
+
+
+.dialog {
+    display: flex;
+}
+
+.dialog+.dialog {
+    margin-top: 15px;
+}
+
+.dialog_right {
+    flex-direction: row-reverse;
+}
+
+.dialog>.d_img {
+    width: 40px;
+    height: 40px;
+    min-width: 40px;
+    overflow: hidden;
+    border-radius: 50%;
+    margin-right: 5px;
+}
+
+.dialog>.d_img>img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
+
+.dialog_right>.d_img {
+    margin-right: 0;
+    margin-left: 5px;
+}
+
+.dialog>.d_content {
+    width: 100%;
+}
+.dialog_right>.d_content{
+    display: flex;
+    flex-direction: column;
+    align-items: flex-end;
+}
+
+
+.dialog>.d_content>.d_name {
+    color: #7C7C7C;
+    font-size: 12px;
+    margin-bottom: 5px;
+}
+
+.dialog_right>.d_content>.d_name {
+    text-align: right;
+}
+
+.dialog>.d_content>.d_log {
+    color: #000;
+    font-size: 16px;
+    background: #fff;
+    width: 100%;
+    max-width: 800px;
+    border: 2px solid #e05d63;
+    border-radius: 40px;
+    line-height: 26px;
+    padding: 20px 35px;
+    box-sizing: border-box;
+    position: relative;
+}
+
+.dialog>.d_content>.d_log::before{
+    content: '';
+    width: calc(100% - 20px);
+    height: calc(100% - 20px);
+    position: absolute;
+    border: 1px dashed #e05d63;
+    box-sizing: border-box;
+    top: 50%;
+    left: 50%;
+    border-radius: 30px;
+    transform: translate(-50%, -50%);
+}
+
+.dialog>.d_content>.d_log2 {
+    color: #000;
+    font-size: 14px;
+    background: #fff;
+    width: 100%;
+    max-width: 800px;
+    border: 1px dashed #0f94ce;
+    border-radius: 5px;
+    line-height: 26px;
+    padding: 10px;
+    box-sizing: border-box;
+    position: relative;
+    margin-top:10px;
+}
+
+.dialog>.d_content>.d_voice {
+    width: 100%;
+    max-width: 600px;
+}
+
+.audio_class {
+    background: #3680fb !important;
+    margin: 0 !important;
+    width: 100% !important;
+    box-sizing: border-box !important;
+}
+
+.d_voice>>>.vueAudioBetter span:before {
+    color: #fff;
+}
+
+.audio_class>>>.slider .process {
+    background: #000;
+}
+
+.d_voice>>>.vueAudioBetter .iconfont:active {
+    position: unset !important;
+}
+</style>
+    

+ 228 - 0
src/components/EnglishVoice3/index.vue

@@ -0,0 +1,228 @@
+<template>
+    <div class="ev_box">
+        <div class="ev_box_left">
+            <left :title="title" :detail="detail" :checkJson="checkJson" :checkType="checkType" @setType="setType">
+            </left>
+        </div>
+        <div class="ev_box_right">
+            <right :checkJson="checkJson" :checkType="checkType" @setType="setType" :work="work" @setWork="setWork">
+            </right>
+        </div>
+        <div class="ev_btn">
+            <el-button type="primary" style="padding: 5px 10px;font-size: 14px;height: 30px;" size="mini" :disabled="!(checkType == (checkJson.length - 1))" @click="addEnglishWork">点击提交</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+import right from './component/right.vue'
+import left from './component/left.vue'
+
+export default {
+    components: {
+        right,
+        left
+    },
+    props: {
+
+        englishVoiceJson: {
+            type: Object
+        },
+        userid:{
+            type:String
+        },
+        id:{
+            type:String
+        },
+        courseType:{
+            type:Number
+        },
+        taskCount:{
+            type:Number
+        },
+        toolindex:{
+            type:Number
+        },
+        englishVoiceJsonWork:{
+            type: Array
+        }
+    },
+    data() {
+        return {
+            checkJson: [],
+            checkJson2: {},
+            title: '',
+            detail: '',
+            checkType: 0,
+            work: [],
+            wScore: 0,
+            scoreDetail: "",
+        }
+    },
+    methods: {
+        handleClose(done) {
+            this.close();
+            done();
+        },
+       
+        // confirm() {
+        //     this.close2();
+        // },
+        setJson(val) {
+            this.checkJson = val;
+            this.$forceUpdate()
+        },
+        setVoiceJson(val) {
+            let a = JSON.parse(JSON.stringify(val));
+            this.checkJson2 = JSON.parse(JSON.stringify(a));
+            this.title = a.title;
+            this.detail = a.detail;
+            this.checkJson = a.array
+            this.checkType = 0
+            this.work=[]
+            this.work.length = a.array.length
+            let works = JSON.parse(
+                JSON.stringify(this.englishVoiceJsonWork)
+            );
+            for (var i = 0; i < this.work.length; i++) {
+                if(i > (works.length - 1)){
+                    break
+                }
+                this.work[i] = works[i];
+            }
+        },
+        setType(index) {
+            this.checkType = index
+        },
+        setWork(url, index, text, star) {
+            if(this.checkJson[index].type == 'createRole'){
+                console.log(url);
+                this.work[index] = JSON.parse(JSON.stringify(url))
+                this.$forceUpdate()
+            }else{
+                if(star){
+                    let score = parseInt(star.AccuracyScore / 20)
+                    this.work[index] = {
+                        audio:url,
+                        text:text,
+                        score:score,
+                        star:star
+                    }
+                }else{
+                    this.work[index] = {
+                        audio:url,
+                        text:text
+                    }
+                }
+
+            }
+        },
+        addEnglishWork() {
+            let params = [
+                {
+                    uid: this.userid,
+                    cid: this.id,
+                    stage: this.courseType,
+                    task: this.taskCount,
+                    tool: this.toolindex,
+                    content: JSON.stringify(this.work),
+                    type: 17,
+                    atool: 70,
+                    text: "",
+                },
+            ];
+            this.ajax
+                .post(this.$store.state.api + "addCourseWorks5", params)
+                .then((res) => {
+                    this.$message({
+                        message: "提交成功",
+                        type: "success",
+                    });
+                    // this.$emit('selectSWorks')
+                    // this.$emit('selectStudent')
+                    // this.close2();
+                })
+                .catch((err) => {
+                    this.$message.error("提交失败");
+                    console.error(err);
+                });
+        },
+    },
+
+    mounted() {
+        this.setVoiceJson(this.englishVoiceJson);
+    },
+}
+</script>
+
+<style scoped>
+.dialog_diy>>>.el-dialog {
+    height: 100%;
+    margin: 0vh auto !important;
+}
+
+.dialog_diy>>>.el-dialog__header {
+    background: #454545 !important;
+    padding: 15px 20px;
+}
+
+.dialog_diy>>>.el-dialog__body {
+    height: calc(100% - 54px);
+    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: #e8ebf1;
+    overflow: hidden;
+}
+
+.ev_box {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: space-between;
+    padding: 20px;
+    box-sizing: border-box;
+}
+
+.ev_box_left {
+    width: 280px;
+    margin-right: 15px;
+    border-radius: 10px;
+    background: #fff;
+    overflow: hidden;
+}
+
+.ev_box_right {
+    width: calc(100% - 280px - 15px);
+    border-radius: 10px;
+    background: #fff;
+    overflow: hidden;
+}
+
+.ev_btn {
+    position: absolute;
+    bottom: 0;
+    right: 80px;
+    height: 210px;
+    display: flex;
+    align-items: center;
+}</style>

+ 130 - 44
src/components/classRoomHelper/component/languageAssistant.vue

@@ -173,6 +173,8 @@
 <script>
 import { v4 as uuidv4 } from "uuid";
 import MarkdownIt from "markdown-it";
+import { fetchEventSource } from "@microsoft/fetch-event-source";
+
 export default {
   props: {},
   data() {
@@ -193,6 +195,8 @@ export default {
       openMessage: true,
 			canTalk:true,
 			loading:false,
+      curRequestController:null,
+
     };
   },
   computed: {
@@ -323,52 +327,134 @@ export default {
                     file_ids: [],
                     model: "gpt-4o-2024-11-20"
                   };
-                  this.ajax
-                    // .post("https://claude3.cocorobo.cn/chat", params)
-                    // .post("https://gpt4.cocorobo.cn/chat", params)
-                    .post(
-                      "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
-                      params
-                    )
-                    .then(res => {
-                      if (
-                        converter(res.data.FunctionResponse.result) ==
-                        converter("发送成功")
-                      ) {
-                        this.userText = "";
-												this.showIndex = 0;
+
+                  let _this = this;
+                  this.curRequestController = new AbortController();
+
+                  let _allText = "";
+                  let _mdText = "";
+                  let _talkText = "";
+
+                  fetchEventSource("https://gpt4.cocorobo.cn/ai_agent_park_chat_new_post_stream",{
+                    method: "POST",
+                    headers: {
+                      "Content-Type": "application/json"
+                    },
+                    body: JSON.stringify(params),
+                    signal: _this.curRequestController.signal,
+                    onmessage(_e){
+                      // console.log('_e',_e)
+
+                      _this.showIndex = 0;
+                      let _eData = JSON.parse(_e.data);
+                      if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
+          
+                        let _result = [];
+                        if ("result" in _eData) {
+                          _result = _eData.result;
+                          for (let i = 0; i < _result.length; i++) {
+                            _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
+                          }
+                        }
+                        _mdText = _mdText.replace("_", "");
+                        _this.aiText = _mdText;
+                        _this.scrollBottom();
+                        if (_talkText != "") {
+                          let _resultText = _this.removeMarkdown(_talkText);
+                          _this.talkTextList.push(_resultText);
+                          _talkText = "";
+                          if (!_this.talkLoading) _this.talkText();
+                        }
+                        _this.chatLoading = false;
                       } else {
-                        // this.$message.warning(res.data.FunctionResponse.result);
-                        console.log(res.data.FunctionResponse.result);
-                        this.chatLoading = false;
-                        this.aiStatus = 0;
-                        this.showTextIndex = 0;
-                        this.showIndex = 0;
-                        this.aiText = "对不起,我无法理解您的问题,请重新提问";
-                        // this.timer = setTimeout(() => {
-                        //   this.showTextIndex = 3;
-                        //   this.aiStatus = 2;
-                        //   this.aiText = "";
-                        //   this.userText = "";
-                        // }, 3000);
+                        // _talkIndex+=1;
+                        let _text = _eData.content.replace("'", "").replace("'", "");
+                        if (_allText == "") {
+                          _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
+                          _talkText += _text.replace(/^\n+/, "");
+                        } else {
+                          _allText += _text;
+                          _talkText += _text;
+                        }
+                        `~`;
+                        _mdText = _allText + "_";
+                        _mdText = _mdText.replace(/\\n/g, "\n");
+                        _mdText = _mdText.replace(/\\/g, "");
+                        if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
+                        _this.aiText = _mdText;
+                        _this.showTextIndex = 0;
+                        _this.scrollBottom();
+                        if (/[,。:;?!)]/.test(_talkText)) {
+                          let _resultText = _this.removeMarkdown(_talkText);
+                          _this.talkTextList.push(_resultText);
+                          _talkText = "";
+                          if (!_this.talkLoading) _this.talkText();
+                        }
                       }
-                    })
-                    .catch(e => {
-                      console.log(e);
-                      this.chatLoading = false;
-                      this.aiStatus = 0;
-                      this.showTextIndex = 0;
-                      this.showIndex = 0;
-                      this.aiText = "对不起,我无法理解您的问题,请重新提问";
-                      // this.timer = setTimeout(() => {
-                      //   this.showTextIndex = 3;
-                      //   this.aiStatus = 2;
-                      //   this.aiText = "";
-                      //   this.userText = "";
-                      // }, 3000);
-                    });
-                  // 通过流获取ai对话数据
-                  this.getAtAuContent(_uuid);
+                    },
+                    onclose(){
+                      _this.$forceUpdate();
+                      // _this.stopTalkToken = null;
+                      // // _this.faloading = false;
+                      _this.curRequestController = null;
+
+                      // _this.chatList.find(i => i.uid == _uuid).isalltext = true;
+                      // _this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
+                      // _this.insertChat(_uuid);
+                      console.log("连接关闭")
+                    },
+                    onerror(err){
+
+                      console.log("连接错误",err)
+                    }
+                })
+
+                  // this.ajax
+                  //   // .post("https://claude3.cocorobo.cn/chat", params)
+                  //   // .post("https://gpt4.cocorobo.cn/chat", params)
+                  //   .post(
+                  //     "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
+                  //     params
+                  //   )
+                  //   .then(res => {
+                  //     if (
+                  //       converter(res.data.FunctionResponse.result) ==
+                  //       converter("发送成功")
+                  //     ) {
+                  //       this.userText = "";
+									// 			this.showIndex = 0;
+                  //     } else {
+                  //       // this.$message.warning(res.data.FunctionResponse.result);
+                  //       console.log(res.data.FunctionResponse.result);
+                  //       this.chatLoading = false;
+                  //       this.aiStatus = 0;
+                  //       this.showTextIndex = 0;
+                  //       this.showIndex = 0;
+                  //       this.aiText = "对不起,我无法理解您的问题,请重新提问";
+                  //       // this.timer = setTimeout(() => {
+                  //       //   this.showTextIndex = 3;
+                  //       //   this.aiStatus = 2;
+                  //       //   this.aiText = "";
+                  //       //   this.userText = "";
+                  //       // }, 3000);
+                  //     }
+                  //   })
+                  //   .catch(e => {
+                  //     console.log(e);
+                  //     this.chatLoading = false;
+                  //     this.aiStatus = 0;
+                  //     this.showTextIndex = 0;
+                  //     this.showIndex = 0;
+                  //     this.aiText = "对不起,我无法理解您的问题,请重新提问";
+                  //     // this.timer = setTimeout(() => {
+                  //     //   this.showTextIndex = 3;
+                  //     //   this.aiStatus = 2;
+                  //     //   this.aiText = "";
+                  //     //   this.userText = "";
+                  //     // }, 3000);
+                  //   });
+                  // // 通过流获取ai对话数据
+                  // this.getAtAuContent(_uuid);
                 }
               }, 5000);
             }

+ 138 - 44
src/components/classRoomHelper/component/levitatedSphere.vue

@@ -65,6 +65,8 @@
 <script>
 import { v4 as uuidv4 } from "uuid";
 import MarkdownIt from "markdown-it";
+import { fetchEventSource } from "@microsoft/fetch-event-source";
+
 export default {
   data() {
     return {
@@ -244,52 +246,144 @@ export default {
                   session_name: _uuid + "-qgt",
                   uid: _uuid,
                   file_ids: [],
-									model: "gpt-4o-2024-11-20",
+									model: "gpt-4o-2024-11-20"
                 };
-                this.ajax
-                  // .post("https://claude3.cocorobo.cn/chat", params)
-                  // .post("https://gpt4.cocorobo.cn/chat", params)
-                  .post(
-                    "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
-                    params
-                  )
-                  .then(res => {
-                    if (
-                      converter(res.data.FunctionResponse.result) ==
-                      converter("发送成功")
-                    ) {
-                      this.userText = "";
-											this.showIndex = 0;
-                    } else {
-                      // this.$message.warning(res.data.FunctionResponse.result);
-                      console.log(res.data.FunctionResponse.result);
-                      this.chatLoading = false;
-                      this.aiStatus = 0;
-                      this.showTextIndex = 0;
-                      this.aiText = "对不起,我无法理解您的问题,请重新提问";
-                      this.timer = setTimeout(() => {
-                        this.showTextIndex = 3;
-                        this.aiStatus = 2;
-                        this.aiText = "";
-                        this.userText = "";
-                      }, 3000);
+
+                  const md = new MarkdownIt();
+                  let _this = this;
+                  this.curRequestController = new AbortController();
+
+                  let _allText = "";
+                  let _mdText = "";
+                  let _talkText = "";
+
+                  fetchEventSource("https://gpt4.cocorobo.cn/chat_post_stream",{
+                    method: "POST",
+                    headers: {
+                      "Content-Type": "application/json"
+                    },
+                    body: JSON.stringify(params),
+                    signal: _this.curRequestController.signal,
+                    onmessage(_e){
+                      console.log('_e',_e)
+
+                      this.showIndex = 0;
+                      let _eData = JSON.parse(_e.data);
+                      if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
+                        // this.source.close();
+                        // this.source = null;
+                        let _result = [];
+                        if ("result" in _eData) {
+                          _result = _eData.result;
+                          for (let i = 0; i < _result.length; i++) {
+                            _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
+                          }
+                        }
+                        _mdText = _mdText.replace("_", "");
+                        this.aiText = _mdText;
+                        this.scrollBottom();
+                        if (_talkText != "") {
+                          let _resultText = this.removeMarkdown(_talkText);
+                          this.talkTextList.push(_resultText);
+                          _talkText = "";
+                          if (!this.talkLoading) this.talkText();
+                        }
+                        this.chatLoading = false;
+                      } else {
+                        // _talkIndex+=1;
+                        let _text = _eData.content.replace("'", "").replace("'", "");
+                        if (_allText == "") {
+                          _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
+                          _talkText += _text.replace(/^\n+/, "");
+                        } else {
+                          _allText += _text;
+                          _talkText += _text;
+                        }
+                        `~`;
+                        _mdText = _allText + "_";
+                        _mdText = _mdText.replace(/\\n/g, "\n");
+                        _mdText = _mdText.replace(/\\/g, "");
+                        if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
+                        this.aiText = _mdText;
+                        this.showTextIndex = 0;
+                        this.scrollBottom();
+                        if (/[,。:;?!)]/.test(_talkText)) {
+                          let _resultText = this.removeMarkdown(_talkText);
+                          this.talkTextList.push(_resultText);
+                          _talkText = "";
+                          if (!this.talkLoading) this.talkText();
+                        }
+                      }
+
+                      // let _data = ev.data;
+                      // if(_data=='[DONE]')return;
+                      // _addText+=_data;
+                      // this.aiText = md.render(_addText)
+                      // // _this.chatList.find(i => i.uid == _uuid).aiContent =  md.render(_addText);
+                      // // _this.chatList.find(i => i.uid == _uuid).loading = false;
+                      // _this.scrollBottom();
+                      // console.log(_data)
+                    },
+                    onclose(){
+                      _this.$forceUpdate();
+                      // _this.stopTalkToken = null;
+                      // // _this.faloading = false;
+                      _this.curRequestController = null;
+
+                      // _this.chatList.find(i => i.uid == _uuid).isalltext = true;
+                      // _this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
+                      // _this.insertChat(_uuid);
+                      console.log("连接关闭")
+                    },
+                    onerror(err){
+
+                      console.log("连接错误",err)
                     }
-                  })
-                  .catch(e => {
-                    console.log(e);
-                    this.chatLoading = false;
-                    this.aiStatus = 0;
-                    this.showTextIndex = 0;
-                    this.aiText = "对不起,我无法理解您的问题,请重新提问";
-                    this.timer = setTimeout(() => {
-                      this.showTextIndex = 3;
-                      this.aiStatus = 2;
-                      this.aiText = "";
-                      this.userText = "";
-                    }, 3000);
-                  });
-                // 通过流获取ai对话数据
-                this.getAtAuContent(_uuid);
+                })
+                // this.ajax
+                //   // .post("https://claude3.cocorobo.cn/chat", params)
+                //   // .post("https://gpt4.cocorobo.cn/chat", params)
+                //   .post(
+                //     "https://gpt4.cocorobo.cn/ai_agent_park_chat_new",
+                //     params
+                //   )
+                //   .then(res => {
+                //     if (
+                //       converter(res.data.FunctionResponse.result) ==
+                //       converter("发送成功")
+                //     ) {
+                //       this.userText = "";
+								// 			this.showIndex = 0;
+                //     } else {
+                //       // this.$message.warning(res.data.FunctionResponse.result);
+                //       console.log(res.data.FunctionResponse.result);
+                //       this.chatLoading = false;
+                //       this.aiStatus = 0;
+                //       this.showTextIndex = 0;
+                //       this.aiText = "对不起,我无法理解您的问题,请重新提问";
+                //       this.timer = setTimeout(() => {
+                //         this.showTextIndex = 3;
+                //         this.aiStatus = 2;
+                //         this.aiText = "";
+                //         this.userText = "";
+                //       }, 3000);
+                //     }
+                //   })
+                //   .catch(e => {
+                //     console.log(e);
+                //     this.chatLoading = false;
+                //     this.aiStatus = 0;
+                //     this.showTextIndex = 0;
+                //     this.aiText = "对不起,我无法理解您的问题,请重新提问";
+                //     this.timer = setTimeout(() => {
+                //       this.showTextIndex = 3;
+                //       this.aiStatus = 2;
+                //       this.aiText = "";
+                //       this.userText = "";
+                //     }, 3000);
+                //   });
+                // // 通过流获取ai对话数据
+                // this.getAtAuContent(_uuid);
               }
             }, 5000);
           }

+ 125 - 17
src/components/classRoomHelper/component/searchArea.vue

@@ -1386,6 +1386,8 @@
 import { v4 as uuidv4 } from "uuid";
 import MarkdownIt from "markdown-it";
 import { tools } from "../../../common/tools";
+import { fetchEventSource } from "@microsoft/fetch-event-source";
+
 var OpenCC = require("opencc-js");
 let converter = OpenCC.Converter({
   from: "hk",
@@ -2106,26 +2108,132 @@ export default {
       // };
       this.text = "";
 
-      this.ajax
-        // .post("https://claude3.cocorobo.cn/chat", params)
-        // .post("https://gpt4.cocorobo.cn/chat", params)
-        .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
-        .then(res => {
-          if (
-            converter(res.data.FunctionResponse.result) == converter("发送成功")
-          ) {
+      let _allText = "";
+      let _mdText = "";
+      let _index = 0;
+      let _talkText = "";
+      let _this = this 
+      this.curRequestController = new AbortController();
+
+      fetchEventSource("https://gpt4.cocorobo.cn/ai_agent_park_chat_new_post_stream",{
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json"
+        },
+        body: JSON.stringify(params),
+        signal: _this.curRequestController.signal,
+        onmessage(_e){
+          // console.log('_e_e_e_e_e_e_e_e_e',_e);
+          
+          let _eData = JSON.parse(_e.data);
+          if (_eData.content.replace("'", "").replace("'", "") == "[DONE]") {
+            let _result = [];
+            if ("result" in _eData) {
+              _result = _eData.result;
+              for (let i = 0; i < _result.length; i++) {
+                _mdText = _mdText.replace(_result[i].text, _result[i].fileName);
+              }
+            }
+            _mdText = _mdText.replace("_", "");
+            if (_this.openMegaphone && _this.aiTalkUid == _uuid) {
+              if (_talkText != "") {
+                let _resultText = _this.removeMarkdown(_talkText);
+                _this.aiTalkList.push(_resultText);
+                _talkText = "";
+                if (!_this.aiIsTalk) _this.aiTalk(1);
+              }
+            }
+            _this.chatLoading = false;
+            _this.chatList.find(i => i.uid == _uuid).aiContent = _mdText;
+            _this.chatList.find(i => i.uid == _uuid).isalltext = true;
+            _this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
+            _this.chatList.find(i => i.uid == _uuid).loading = false;
+            _this.nowChatList.push(_this.chatList.find(i => i.uid == _uuid));
+            // this.addAsk(this.chatList.find(i => i.uid == _uid).content);
+            // this.source.close();
+            _this.insertChat(_uuid);
           } else {
-            // this.$message.warning(res.data.FunctionResponse.result);
-            console.log(res.data.FunctionResponse.result);
-            this.chatLoading = false;
+            _index += 1;
+            let _text = _eData.content.replace("'", "").replace("'", "");
+            if (_allText == "") {
+              _allText = _text.replace(/^\n+/, ""); //去掉回复消息中偶尔开头就存在的连续换行符
+              _talkText += _text.replace(/^\n+/, "");
+            } else {
+              _allText += _text;
+              _talkText += _text;
+            }
+            _mdText = _allText + "_";
+            _mdText = _mdText.replace(/\\n/g, "\n");
+            _mdText = _mdText.replace(/\\/g, "");
+            if (_allText.split("```").length % 2 == 0) _mdText += "\n```\n";
+            //转化返回的回复流数据
+            // _mdText = md.render(_mdText);
+            if (_index == 10) {
+              _this.chatList.find(i => i.uid == _uuid).aiContent = _mdText;
+              _this.chatList.find(i => i.uid == _uuid).loading = false;
+              _this.$nextTick(() => {
+                _this.$refs.chatRef.scrollTop = _this.$refs.chatRef.scrollHeight;
+              });
+              _index = 0;
+            }
+            if (_this.openMegaphone && /[,。:;?!)]/.test(_talkText)) {
+              let _resultText = _this.removeMarkdown(_talkText);
+              if (_this.aiTalkUid != _uuid) {
+                _this.aiTalkList = [];
+              }
+              _this.aiTalkList.push(_resultText);
+              _talkText = "";
+              if (_this.aiTalkUid != _uuid) {
+                _this.aiTalkUid = _uuid;
+                _this.aiTalk(0);
+              } else if (!_this.aiIsTalk) {
+                _this.aiTalk(1);
+              }
+            }
+            // 处理流数据
           }
-        })
-        .catch(e => {
-          console.log(e);
-          this.chatLoading = false;
-        });
+        },
+        onclose(){
+          _this.$forceUpdate();
+          // _this.stopTalkToken = null;
+          // _this.faloading = false;
+          _this.curRequestController = null;
+          // _this.chatList.find(i => i.uid == _uuid).isalltext = true;
+          // _this.chatList.find(i => i.uid == _uuid).isShowSynchronization = true;
+          _this.insertChat(_uuid);
+          console.log("连接关闭")
+        },
+        onerror(err){
+
+          console.log("连接错误",err)
+        }
+      })
+
+      // this.ajax
+      //   // .post("https://claude3.cocorobo.cn/chat", params)
+      //   // .post("https://gpt4.cocorobo.cn/chat", params)
+      //   .post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
+      //   .then(res => {
+      //     if (  
+      //       converter(res.data.FunctionResponse.result) == converter("发送成功")
+      //     ) {
+      //       console.log('555');
+
+
+      //     } else {
+      //       // this.$message.warning(res.data.FunctionResponse.result);
+      //       console.log('6666');
+
+      //       console.log(res.data.FunctionResponse.result);
+      //       this.chatLoading = false;
+      //     }
+      //   })
+      //   .catch(e => {
+      //     console.log(e);
+      //     this.chatLoading = false;
+      //   });
       this.saveUid = _uuid;
-      this.getAtAuContent(_uuid);
+      // this.getAtAuContent(_uuid);
     },
     atSend(_text, _atList) {
       let _msg = ``;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 728 - 161
src/components/components/choseWorksDetailDialog.vue


+ 1 - 1
src/components/components/onlineWrite.vue

@@ -93,7 +93,7 @@
           <img src="../../assets/icon/english/delete.png" alt="" />
         </div>
       </div>
-      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
+      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="checkImage">取 消</el-button>
         <el-button type="primary" @click="uploadIsType">确定</el-button>

+ 133 - 3
src/components/components/studentWorkPreviewDialog.vue

@@ -17,7 +17,7 @@
           </div>
           <div
             class="s_b_m_content"
-            v-if="[45, 48, 52, 15, 41, 47,40].includes(tool)"
+            v-if="[45, 48, 52, 15, 41, 47,40,4].includes(tool)"
           >
             <div class="s_b_m_tool45" v-if="[45].includes(tool)">
               <div class="s_b_m_toolItem" v-for="(item, index) in testJson">
@@ -95,7 +95,81 @@
                 <div></div>
               </div>
             </div>
-
+            <div class="s_b_m_tool45" v-if="[4].includes(tool)">
+             
+              <div>
+                <div
+                  class="a_add_title"
+                  style="
+                    display: flex;
+                    flex-direction: row;
+                    align-items: center;
+                    justify-content: center;
+                  "
+                >
+                  <div style="margin-right: 20px; font-size: 20px">标题:</div>
+                  <div style="font-size: 20px">{{ testData.askTitle }}</div>
+                </div>
+                <div class="a_addBox">
+                  <div style="font-size: 16px; color: #c7c7c7; margin-bottom: 10px">
+                    题目内容
+                  </div>
+                  <div
+                    class="a_add_box"
+                    v-for="(item1, index1) in testData.askCount"
+                    :key="index1"
+                  >
+                    <div class="a_add_head">
+                      <div style="display: flex">
+                        <span class="askIndex"> {{ index1 + 1 }}</span>
+                        <div>题目:{{ testData.askJson[index1].askstitle }}</div>
+                      </div>
+                      <img
+                        v-if="testData.askJson[index1].img"
+                        :src="testData.askJson[index1].img"
+                        style="height: 300px; margin-top: 10px; max-width: 100%"
+                      />
+                    </div>
+                    <div class="a_add_body">
+                      <div class="a_add_input">
+                        <el-radio-group
+                          v-model="userAnswer[index1]"
+                          v-if="
+                            testData.askJson[index1].type == '1' ||
+                            !testData.askJson[index1].type
+                          "
+                        >
+                        
+                          <el-radio
+                            v-for="(item2, checkIndex) in testData.askJson[index1]
+                              .checkList"
+                            :key="checkIndex"
+                            :label="checkIndex"
+                            :disabled="isAnswer"
+                            class="redioStyle"
+                            ><span>{{ optionTypeList[checkIndex] }}.</span><span v-html="item2"></span
+                          ></el-radio>
+                        </el-radio-group>
+                        <el-checkbox-group
+                          v-model="userAnswer[index1]"
+                          v-if="testData.askJson[index1].type == '2'"
+                        >
+                          <el-checkbox
+                            v-for="(item2, checkIndex1) in testData.askJson[index1]
+                              .checkList"
+                            :key="checkIndex1"
+                            :label="checkIndex1"
+                            :disabled="isAnswer"
+                            class="redioStyle"
+                            ><span>{{ optionTypeList[checkIndex1] }}.</span> <span v-html="item2"></span>
+                          </el-checkbox>
+                        </el-checkbox-group>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
             <div class="s_b_m_tool48" v-if="[48, 52].includes(tool)">
               <div v-html="userAnswer"></div>
             </div>
@@ -210,6 +284,11 @@ export default {
           value: 45,
           img: require("../../assets/icon/thirdToolList/choose.png")
         },
+        {
+          label: "问卷调查",
+          value: 4,
+          img: require("../../assets/icon/thirdToolList/ask.png")
+        },
         {
           label: "表格",
           value: 48,
@@ -259,7 +338,9 @@ export default {
       studentWork: null,
       testData: null,
       testJson: null,
-      tool: null
+      tool: null,
+			optionTypeList:['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
+
     };
   },
   methods: {
@@ -291,6 +372,11 @@ export default {
           ? this.studentWork.works
           : JSON.parse(this.studentWork.works);
         if ([45].includes(this.tool)) {
+          let _answer = _studentWorks[0].anwer;
+          _result = _answer;
+        } else if ([4].includes(this.tool)) {
+          console.log('_studentWorks',_studentWorks);
+
           let _answer = _studentWorks[0].anwer;
           _result = _answer;
         } else if ([48, 52].includes(this.tool)) {
@@ -644,4 +730,48 @@ export default {
   border: solid 1px #D0D0D2;
   background-color: #F7F6F9;
 }
+.a_add_body {
+  display: flex;
+  align-items: center;
+}
+
+.a_add_input {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  width: 100%;
+}
+
+.a_add_input >>> .el-radio-group,
+.a_add_input >>> .el-checkbox-group {
+  width: 100%;
+}
+
+.a_add_input >>> .el-radio,
+.a_add_input >>> .el-checkbox {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+  padding: 15px 0;
+}
+
+.a_add_input >>> .el-radio:not(:last-child),
+.a_add_input >>> .el-checkbox:not(:last-child) {
+  width: 100%;
+  border-bottom: 1px solid #efefef;
+}
+.redioStyle >>> .el-radio__label {
+  font-size: 18px;
+}
+
+.redioStyle >>> .el-radio__label > span,
+.redioStyle >>> .el-checkbox__label > span {
+  word-break: break-all;
+  white-space: normal;
+}
+
+.redioStyle >>> .el-checkbox__label {
+  font-size: 18px;
+}
 </style>

+ 1 - 1
src/components/easy2/commpont/onlineWrite.vue

@@ -93,7 +93,7 @@
           <img src="../../../assets/icon/english/delete.png" alt="" />
         </div>
       </div>
-      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
+      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="checkImage">取 消</el-button>
         <el-button type="primary" @click="uploadIsType">确定</el-button>

+ 81 - 7
src/components/easy2/studyStudent.vue

@@ -1098,6 +1098,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">问卷调查</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,4)"
+                            style="position: absolute;right: 153px;top: -30px;">
+                              投影
+                            </div>
                             <div
                               class="upload_toolBtn"
                               v-if="tType === '1'"
@@ -1180,6 +1184,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">训练服务器</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,18)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 16">
                             <img
@@ -1204,6 +1212,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AIoT Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,21)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <!-- <div v-if="tooC == 22">
                             <img
@@ -1220,6 +1232,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Python</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,23)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 24">
                             <img
@@ -1228,6 +1244,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,24)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 25">
                             <img
@@ -1244,6 +1264,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">数学画板</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,31)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 28">
                             <img
@@ -1252,6 +1276,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">翻译</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,28)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 37">
                             <img
@@ -1276,6 +1304,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">GeoGebra</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,39)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 32">
                             <img
@@ -1284,6 +1316,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">源码编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,32)"
+                              style="position: absolute;right: 153px;top: -42px;">
+                              投影
+                            </div>
                             <!-- <div class="upload_toolBtn" @click="addImg($event)"
                               style="position: absolute;left: 110px;bottom: 30px;">
                               上传文件
@@ -1378,6 +1414,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">CocoPi</div>
+                            <div class="upload_toolBtn" @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,57)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 58">
                             <img
@@ -1426,6 +1466,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">海龟编程</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,63)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 71">
                             <img
@@ -1434,6 +1478,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI智能体</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,71)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 72">
                             <img
@@ -1458,6 +1506,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">公式编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,66)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 67">
                             <img
@@ -1474,6 +1526,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">时间轴</div>
+                            <!-- <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,68)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div> -->
                           </div>
                           <div v-if="tooC == 69">
                             <img
@@ -1482,6 +1538,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语写作</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,69)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 70">
                             <img
@@ -1490,6 +1550,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语口语</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,70)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                         </div>
                       </div>
@@ -15504,7 +15568,11 @@
       :tType="tType"
       :sIsOpen="sIsOpen"
       :courseDetail="courseDetail"
-      :groupStudent="groupStudent"
+      :groupStudent2="groupStudent"
+      :groupStudentUid2="groupStudentUid"
+      :oid="oid"
+      :org="org"
+      @getCourseDetail="getCourseDetail"
       @selectSLook="selectSLook"
       @selectSWorks="selectSWorks"
       @selectStudent="selectStudent"
@@ -20871,6 +20939,8 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then(res => {
+          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+
           if (type != 2) {
             loading.close();
             if (
@@ -21362,9 +21432,9 @@ export default {
           _this.timer = setInterval(function() {
             // _this.getCourseDetail(2);
             if (_this.tcid) {
-              _this.getCourseGroup(gindex);
+              _this.getCourseGroup();
             } else {
-              _this.selectSWorks(gindex);
+              _this.selectSWorks();
             }
 
             _this.selectStudent();
@@ -21794,9 +21864,10 @@ export default {
           this.IsFollow = res.data[0][0].follow == 1 ? false : true;
           if (!this.IsLookOpen) {
             this.setNavList();
-          } else {
+          } 
+          // else {
             this.getCourseState(1);
-          }
+          // }
           //  || (this.splitScreenData.isOpen && this.splitScreenData.uid != this.splitScreenData.myUid)
 					if ((this.IsFollow && this.tType == 2)) {
             this.setContent2(false);
@@ -21894,8 +21965,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "getCourseState", params)
         .then(res => {
-          if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
+          if (res.data[0].length > 0) {
             this.chapInfoList = JSON.parse(res.data[0][0].state);
+          }
+          if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
+            // this.chapInfoList = JSON.parse(res.data[0][0].state);
             console.log("this.chapInfoList", this.chapInfoList);
             this.setNavList();
             this.$forceUpdate();
@@ -24971,7 +25045,7 @@ export default {
             if(this.taskCount !=behavior.form.taskCount){
               this.taskCount = behavior.form.taskCount;
             }
-            if(this.toolindex != behavior.form.toolType){
+            if((behavior.form.toolType || behavior.form.toolType == 0)  && this.toolindex != behavior.form.toolType){
               this.toolindex = behavior.form.toolType;
             }
 

+ 1 - 1
src/components/easy3/commpont/onlineWrite.vue

@@ -93,7 +93,7 @@
           <img src="../../../assets/icon/english/delete.png" alt="" />
         </div>
       </div>
-      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
+      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="checkImage">取 消</el-button>
         <el-button type="primary" @click="uploadIsType">确定</el-button>

+ 83 - 9
src/components/easy3/studyStudent.vue

@@ -1051,6 +1051,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">问卷调查</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,4)"
+                            style="position: absolute;right: 153px;top: -30px;">
+                              投影
+                            </div>
 														<div class="upload_toolBtn" v-if="tType==='1'" @click="openStatisticalAnalysis(tooC,toolIndex,taskCount)"
                               style="position: absolute;right: 33px;top: -30px;">
                               统计分析
@@ -1113,6 +1117,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">训练服务器</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,18)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 16">
                             <img
@@ -1137,6 +1145,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AIoT Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,21)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <!-- <div v-if="tooC == 22">
                             <img
@@ -1153,6 +1165,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Python</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,23)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 24">
                             <img
@@ -1161,6 +1177,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,24)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 25">
                             <img
@@ -1177,6 +1197,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">数学画板</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,31)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 28">
                             <img
@@ -1185,6 +1209,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">翻译</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,28)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 37">
                             <img
@@ -1209,6 +1237,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">GeoGebra</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,39)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 32">
                             <img
@@ -1217,6 +1249,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">源码编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,32)"
+                              style="position: absolute;right: 153px;top: -42px;">
+                              投影
+                            </div>
                             <!-- <div class="upload_toolBtn" @click="addImg($event)"
                               style="position: absolute;left: 110px;bottom: 30px;">
                               上传文件
@@ -1311,6 +1347,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">CocoPi</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,57)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 58">
                             <img
@@ -1359,6 +1399,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">海龟编程</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,63)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 71">
                             <img
@@ -1367,6 +1411,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI智能体</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,71)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 72">
                             <img
@@ -1391,6 +1439,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">公式编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,66)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 67">
                             <img
@@ -1407,6 +1459,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">时间轴</div>
+                            <!-- <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,68)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div> -->
                           </div>
                           <div v-if="tooC == 69">
                             <img
@@ -1415,6 +1471,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语写作</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,69)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 70">
                             <img
@@ -1423,6 +1483,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语口语</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,70)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                         </div>
                       </div>
@@ -12046,13 +12110,17 @@
       ref="choseWorksDetailDialogRef"
       :worksStudentData="worksStudent"
       :noWorksSData="noWorksS"
-      :chapInfoListData="chapInfoList"
+      :chapInfoListData="chapInfoList" 
       :courseType="courseType"
       :taskCount="taskCount"
       :tType="tType"
       :sIsOpen="sIsOpen"
       :courseDetail="courseDetail"
-      :groupStudent="groupStudent"
+      :groupStudent2="groupStudent"
+      :groupStudentUid2="groupStudentUid"
+      :oid="oid"
+      :org="org"
+      @getCourseDetail="getCourseDetail"
       @selectSLook="selectSLook"
       @selectSWorks="selectSWorks"
       @selectStudent="selectStudent"
@@ -16637,6 +16705,7 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then((res) => {
+          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
           if (type != 2) {
             loading.close();
             if (
@@ -17060,9 +17129,9 @@ export default {
           _this.timer = setInterval(function () {
             // _this.getCourseDetail(2);
             if (_this.tcid) {
-              _this.getCourseGroup(gindex);
+              _this.getCourseGroup();
             } else {
-              _this.selectSWorks(gindex);
+              _this.selectSWorks();
             }
 
             _this.selectStudent();
@@ -17490,9 +17559,11 @@ export default {
           this.IsFollow = res.data[0][0].follow == 1 ? false : true;
           if (!this.IsLookOpen) {
             this.setNavList();
-          } else {
+          } 
+          
             this.getCourseState(1);
-          }
+          
+
 
 					if ((this.IsFollow && this.tType == 2)) {
             this.setContent2(false);
@@ -17590,8 +17661,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "getCourseState", params)
         .then((res) => {
+          if (res.data[0].length > 0) {
+          this.chapInfoList = JSON.parse(res.data[0][0].state);
+          }
           if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
-            this.chapInfoList = JSON.parse(res.data[0][0].state);
+            // this.chapInfoList = JSON.parse(res.data[0][0].state);
             this.setNavList();
             this.$forceUpdate();
           } else if (res.data[0].length > 0 && this.IsLookOpen && type == 2) {
@@ -20598,7 +20672,7 @@ export default {
             if(this.taskCount !=behavior.form.taskCount){
               this.taskCount = behavior.form.taskCount;
             }
-            if(this.toolindex != behavior.form.toolType){
+            if((behavior.form.toolType || behavior.form.toolType == 0) && (this.toolindex != behavior.form.toolType)){
               this.toolindex = behavior.form.toolType;
             }
 
@@ -20607,7 +20681,7 @@ export default {
             // }
             // console.log("分屏阶段和任务",JSON.stringify(oldData),JSON.stringify(newData))
             if(JSON.stringify(oldData)!=JSON.stringify(newData)){
-              // console.log("分屏测试====",JSON.stringify(oldData),JSON.stringify(newData))
+              console.log("分屏测试====",JSON.stringify(oldData),JSON.stringify(newData))
               this.getCourseDetail()
             }
             this.setContent2(false)

+ 96 - 8
src/components/studyStudent.vue

@@ -1012,6 +1012,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">问卷调查</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,4)"
+                            style="position: absolute;right: 153px;top: -30px;">
+                              投影
+                            </div>
 														<div class="upload_toolBtn" v-if="tType==='1'" @click="openStatisticalAnalysis(tooC,toolIndex,taskCount)"
                               style="position: absolute;right: 33px;top: -30px;">
                               统计分析
@@ -1074,6 +1078,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">训练服务器</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,18)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 16">
                             <img
@@ -1098,6 +1106,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AIoT Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,21)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <!-- <div v-if="tooC == 22">
                             <img
@@ -1114,6 +1126,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Python</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,23)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 24">
                             <img
@@ -1122,6 +1138,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,24)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 25">
                             <img
@@ -1138,6 +1158,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">数学画板</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,31)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 28">
                             <img
@@ -1146,6 +1170,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">翻译</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,28)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 37">
                             <img
@@ -1170,6 +1198,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">GeoGebra</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,39)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 32">
                             <img
@@ -1178,6 +1210,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">源码编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,32)"
+                              style="position: absolute;right: 153px;top: -42px;">
+                              投影
+                            </div>
                             <!-- <div class="upload_toolBtn" @click="addImg($event)"
                               style="position: absolute;left: 110px;bottom: 30px;">
                               上传文件
@@ -1272,6 +1308,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">CocoPi</div>
+                            <div class="upload_toolBtn" @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,57)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 58">
                             <img
@@ -1320,6 +1360,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">海龟编程</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,63)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 71">
                             <img
@@ -1328,6 +1372,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI智能体</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,71)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 72">
                             <img
@@ -1352,6 +1400,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">公式编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,66)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 67">
                             <img
@@ -1368,6 +1420,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">时间轴</div>
+                            <!-- <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,68)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div> -->
                           </div>
                           <div v-if="tooC == 69">
                             <img
@@ -1376,6 +1432,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语写作</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,69)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 70">
                             <img
@@ -1384,6 +1444,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语口语</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,70)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                         </div>
                       </div>
@@ -11985,7 +12049,11 @@
       :tType="tType"
       :sIsOpen="sIsOpen"
       :courseDetail="courseDetail"
-      :groupStudent="groupStudent"
+      :groupStudent2="groupStudent"
+      :groupStudentUid2="groupStudentUid"
+      :oid="oid"
+      :org="org"
+      @getCourseDetail="getCourseDetail"
       @selectSLook="selectSLook"
       @selectSWorks="selectSWorks"
       @selectStudent="selectStudent"
@@ -16620,6 +16688,8 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then((res) => {
+          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+
           if (type != 2) {
             loading.close();
             if (
@@ -17042,9 +17112,9 @@ export default {
           _this.timer = setInterval(function () {
             // _this.getCourseDetail(2);
             if (_this.tcid) {
-              _this.getCourseGroup(gindex);
+              _this.getCourseGroup();
             } else {
-              _this.selectSWorks(gindex);
+              _this.selectSWorks();
             }
 
             _this.selectStudent();
@@ -17474,9 +17544,10 @@ export default {
           this.IsFollow = res.data[0][0].follow == 1 ? false : true;
           if (!this.IsLookOpen) {
             this.setNavList();
-          } else {
-            this.getCourseState(1);
           }
+          //  else {
+            this.getCourseState(1);
+          // }
 
           if ((this.IsFollow && this.tType == 2)) {
             this.setContent2(false);
@@ -17574,8 +17645,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "getCourseState", params)
         .then((res) => {
-          if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
+          if (res.data[0].length > 0) {
             this.chapInfoList = JSON.parse(res.data[0][0].state);
+          }
+          if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
+            // this.chapInfoList = JSON.parse(res.data[0][0].state);
             this.setNavList();
             this.$forceUpdate();
           } else if (res.data[0].length > 0 && this.IsLookOpen && type == 2) {
@@ -17896,6 +17970,8 @@ export default {
           type: 2,
         },
       ];
+      console.log('params',params);
+      
       this.ajax
         .post(this.$store.state.api + "addCourseWorks", params)
         .then((res) => {
@@ -20424,6 +20500,7 @@ export default {
       }, 1000);
       this.$message.success("分屏模式已开启");
     },
+    // 获取分屏数据
     getSplitScreenData() {
       // return;
       // if (this.tType != 1) return;
@@ -20498,13 +20575,19 @@ export default {
           console.log("获取分屏数出错:", e);
         });
     },
+    // 操作
     doSplitScreenBehavior() {
       if (
         this.splitScreenData.isOpen &&
         this.splitScreenData.uid != this.splitScreenData.myUid
       ) {
         let behavior = this.splitScreenData.behavior;
+
         if (behavior) {
+          // console.log('behavior',behavior);
+          
+          // this.toolindex = behavior.form.toolType
+          // 初始状态
           if (behavior.code === 99) {
             //初始化
             this.fullDialogVisible = false;
@@ -20515,12 +20598,14 @@ export default {
 							this.$refs.statisticalAnalysisRef.close();
 						}
           }
+          // 文件列表
            if (behavior.code === 0) {
             //开启内容列表弹窗
             this.checkFileFull1(behavior.form.t, behavior.form.f);
             }else{
               this.fullDialogVisible = false;
             }
+            // 打开工具
            if (behavior.code === 1) {
             //关于选择题的作业详细的操作
             // toolIndex:toolIndex,courseType:this.courseType,taskCount:this.taskCount,type:0
@@ -20539,6 +20624,7 @@ export default {
           }else{
             this.$refs.choseWorksDetailDialogRef.close()
           }
+          // 问卷调查
            if(behavior.code === 2){
 						if(this.$refs.statisticalAnalysisRef.show){
 							this.$refs.statisticalAnalysisRef.splitScreenFn({type:behavior.form.type})
@@ -20583,7 +20669,7 @@ export default {
             if(this.taskCount !=behavior.form.taskCount){
               this.taskCount = behavior.form.taskCount;
             }
-            if(this.toolindex != behavior.form.toolType){
+            if((behavior.form.toolType || behavior.form.toolType == 0)  && this.toolindex != behavior.form.toolType){
               this.toolindex = behavior.form.toolType;
             }
 
@@ -20603,6 +20689,7 @@ export default {
         }
       }
     },
+    // 修改分屏数据
     updateSplitScreenData(empty = 0) {
       return new Promise(resolve => {
 				if(this.userid!==this.courseDetail.userid){
@@ -20663,6 +20750,7 @@ export default {
         }
       });
     },
+    // 修改分屏数据
     changeSplitScreenBehavior(newValue) {
       if (
         this.splitScreenData.isOpen &&
@@ -20680,7 +20768,7 @@ export default {
         }else{
           _behavior.form = {
             taskCount:this.taskCount,
-            courseType:this.courseType
+            courseType:this.courseType,
           }
         }
         this.splitScreenData.behavior = _behavior;

+ 1 - 1
src/components/studySutdentClass/commpont/onlineWrite.vue

@@ -93,7 +93,7 @@
           <img src="../../../assets/icon/english/delete.png" alt="" />
         </div>
       </div>
-      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
+      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="checkImage">取 消</el-button>
         <el-button type="primary" @click="uploadIsType">确定</el-button>

+ 81 - 7
src/components/studySutdentClass/studyStudent.vue

@@ -1051,6 +1051,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">问卷调查</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,4)"
+                            style="position: absolute;right: 153px;top: -30px;">
+                              投影
+                            </div>
                             <div
                               class="upload_toolBtn"
                               v-if="tType === '1'"
@@ -1133,6 +1137,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">训练服务器</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,18)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 16">
                             <img
@@ -1157,6 +1165,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AIoT Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,21)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <!-- <div v-if="tooC == 22">
                             <img
@@ -1181,6 +1193,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI Blockly</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,24)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 25">
                             <img
@@ -1197,6 +1213,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">数学画板</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,31)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 28">
                             <img
@@ -1205,6 +1225,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">翻译</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,28)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 37">
                             <img
@@ -1229,6 +1253,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">GeoGebra</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,39)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 32">
                             <img
@@ -1237,6 +1265,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">源码编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,32)"
+                              style="position: absolute;right: 153px;top: -42px;">
+                              投影
+                            </div>
                             <!-- <div class="upload_toolBtn" @click="addImg($event)"
                               style="position: absolute;left: 110px;bottom: 30px;">
                               上传文件
@@ -1331,6 +1363,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">CocoPi</div>
+                            <div class="upload_toolBtn" @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,57)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 58">
                             <img
@@ -1379,6 +1415,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">海龟编程</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,63)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 71">
                             <img
@@ -1387,6 +1427,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">AI智能体</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,71)"
+                              style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 72">
                             <img
@@ -1411,6 +1455,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">公式编辑</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,36)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 67">
                             <img
@@ -1427,6 +1475,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">时间轴</div>
+                            <!-- <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,68)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div> -->
                           </div>
                           <div v-if="tooC == 69">
                             <img
@@ -1435,6 +1487,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语写作</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,69)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                           <div v-if="tooC == 70">
                             <img
@@ -1443,6 +1499,10 @@
                               alt
                             />
                             <div style="margin: 5px 0">英语口语</div>
+                            <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,70)"
+                            style="position: absolute;right: 33px;top: -30px;">
+                              投影
+                            </div>
                           </div>
                         </div>
                       </div>
@@ -11545,6 +11605,10 @@
                   alt
                 />
                 <div style="margin: 5px 0">AI Python</div>
+                <div class="upload_toolBtn"  @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,23)"
+                  style="position: absolute;right: 33px;top: -30px;">
+                  投影
+                </div>
               </div>
               <div class="check">
                 <div
@@ -15056,7 +15120,11 @@
       :tType="tType"
       :sIsOpen="sIsOpen"
       :courseDetail="courseDetail"
-      :groupStudent="groupStudent"
+      :groupStudent2="groupStudent"
+      :groupStudentUid2="groupStudentUid"
+      :oid="oid"
+      :org="org"
+      @getCourseDetail="getCourseDetail"
       @selectSLook="selectSLook"
       @selectSWorks="selectSWorks"
       @selectStudent="selectStudent"
@@ -20292,6 +20360,8 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then((res) => {
+          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+
           if (type != 2) {
             loading.close();
             if (
@@ -20791,9 +20861,9 @@ export default {
           _this.timer = setInterval(function () {
             // _this.getCourseDetail(2);
             if (_this.tcid) {
-              _this.getCourseGroup(gindex);
+              _this.getCourseGroup();
             } else {
-              _this.selectSWorks(gindex);
+              _this.selectSWorks();
             }
 
             _this.selectStudent();
@@ -21222,9 +21292,10 @@ export default {
           this.IsFollow = res.data[0][0].follow == 1 ? false : true;
           if (!this.IsLookOpen) {
             this.setNavList();
-          } else {
+          } 
+          // else {
             this.getCourseState(1);
-          }
+          // }
 
 					if ((this.IsFollow && this.tType == 2) || (this.splitScreenData.isOpen && this.splitScreenData.uid != this.splitScreenData.myUid)) {
             this.setContent2(false);
@@ -21322,8 +21393,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "getCourseState", params)
         .then((res) => {
-          if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
+          if (res.data[0].length > 0) {
             this.chapInfoList = JSON.parse(res.data[0][0].state);
+          }
+          if (res.data[0].length > 0 && this.IsLookOpen && type == 1) {
+            // this.chapInfoList = JSON.parse(res.data[0][0].state);
             this.setNavList();
             this.$forceUpdate();
           } else if (res.data[0].length > 0 && this.IsLookOpen && type == 2) {
@@ -24337,7 +24411,7 @@ export default {
             if(this.taskCount !=behavior.form.taskCount){
               this.taskCount = behavior.form.taskCount;
             }
-            if(this.toolindex != behavior.form.toolType){
+            if((behavior.form.toolType || behavior.form.toolType == 0)  && this.toolindex != behavior.form.toolType){
               this.toolindex = behavior.form.toolType;
             }
 

+ 1 - 1
src/components/trainCourse/easy2/commpont/onlineWrite.vue

@@ -93,7 +93,7 @@
           <img src="../../../../assets/icon/english/delete.png" alt="" />
         </div>
       </div>
-      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
+      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="checkImage">取 消</el-button>
         <el-button type="primary" @click="uploadIsType">确定</el-button>

+ 1 - 1
src/components/trainCourse/easy3/commpont/onlineWrite.vue

@@ -93,7 +93,7 @@
           <img src="../../../../assets/icon/english/delete.png" alt="" />
         </div>
       </div>
-      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
+      <div style="text-align: center">如已进行填写,确认后清空内容噢。</div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="checkImage">取 消</el-button>
         <el-button type="primary" @click="uploadIsType">确定</el-button>

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels