Jelajahi Sumber

Merge branch 'beta' into HK

lsc 10 bulan lalu
induk
melakukan
fc00a5c7b4
32 mengubah file dengan 1632 tambahan dan 1058 penghapusan
  1. 4 0
      dist/index.html
  2. 0 0
      dist/static/css/app.a5b7dd337a30845bd495c8cbd02fe219.css.map
  3. 0 0
      dist/static/css/app.c774f4547ea3f73e85d4a8dc587cc943.css
  4. 1 0
      dist/static/css/app.c774f4547ea3f73e85d4a8dc587cc943.css.map
  5. 1 0
      dist/static/js/app.5cb62b3361321563406f.js
  6. 0 0
      dist/static/js/app.5cb62b3361321563406f.js.map
  7. 1 0
      dist/static/js/app.73a971163826bdf927f2.js
  8. 1 0
      dist/static/js/app.73a971163826bdf927f2.js.map
  9. 0 0
      dist/static/js/manifest.0ad6c5648a38a6d1fa8f.js.map
  10. 1 1
      src/assets/icon/classroomObservation/echartIcon.svg
  11. 3 3
      src/components/pages/addCourse.vue
  12. 29 5
      src/components/pages/aiAddCourse/addCourse.vue
  13. 642 291
      src/components/pages/aiAddCourse/evaList.vue
  14. 1 1
      src/components/pages/classroomObservation/components/addNewAnalysisDialog.vue
  15. 505 465
      src/components/pages/classroomObservation/components/analysisItem.vue
  16. 147 96
      src/components/pages/classroomObservation/components/analysisSpecialItem.vue
  17. 0 3
      src/components/pages/classroomObservation/components/saveTemplateDialog.vue
  18. 31 44
      src/components/pages/classroomObservation/components/sharePdf.vue
  19. 21 2
      src/components/pages/classroomObservation/index.vue
  20. 206 109
      src/components/pages/components/exportDataDialog.vue
  21. 3 3
      src/components/pages/easy/addCourse.vue
  22. 3 3
      src/components/pages/newCourse/addCourse.vue
  23. 4 4
      src/components/pages/student/addCourse.vue
  24. 4 4
      src/components/pages/student/courseProgress.vue
  25. 4 4
      src/components/pages/studio/addCourse.vue
  26. 4 4
      src/components/pages/studio/courseProgress.vue
  27. 3 3
      src/components/pages/synergyCourse/addCourse.vue
  28. 3 3
      src/components/pages/synergyCourse/group/group.vue
  29. 3 3
      src/components/pages/task/addCourse.vue
  30. 3 3
      src/components/pages/trainCourse/addCourse.vue
  31. 3 3
      src/components/pages/trainCourse/easy/addCourse.vue
  32. 1 1
      src/components/pages/works.vue

+ 4 - 0
dist/index.html

@@ -32,7 +32,11 @@
       width: 100%;
       background: #e6eaf0;
       font-family: '黑体';
+<<<<<<< HEAD
     }</style><link href=./static/css/app.a5b7dd337a30845bd495c8cbd02fe219.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.0ad6c5648a38a6d1fa8f.js></script><script type=text/javascript src=./static/js/vendor.a82b79982b082928b294.js></script><script type=text/javascript src=./static/js/app.5cb62b3361321563406f.js></script></body></html><script>function stopSafari() {
+=======
+    }</style><link href=./static/css/app.c774f4547ea3f73e85d4a8dc587cc943.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.00bfcafc8431113801f1.js></script><script type=text/javascript src=./static/js/vendor.a54a39a7efbf3fedeee2.js></script><script type=text/javascript src=./static/js/app.73a971163826bdf927f2.js></script></body></html><script>function stopSafari() {
+>>>>>>> beta
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/css/app.a5b7dd337a30845bd495c8cbd02fe219.css.map


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/css/app.c774f4547ea3f73e85d4a8dc587cc943.css


File diff ditekan karena terlalu besar
+ 1 - 0
dist/static/css/app.c774f4547ea3f73e85d4a8dc587cc943.css.map


File diff ditekan karena terlalu besar
+ 1 - 0
dist/static/js/app.5cb62b3361321563406f.js


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/app.5cb62b3361321563406f.js.map


File diff ditekan karena terlalu besar
+ 1 - 0
dist/static/js/app.73a971163826bdf927f2.js


File diff ditekan karena terlalu besar
+ 1 - 0
dist/static/js/app.73a971163826bdf927f2.js.map


File diff ditekan karena terlalu besar
+ 0 - 0
dist/static/js/manifest.0ad6c5648a38a6d1fa8f.js.map


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

@@ -1 +1 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726640886428" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4312" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M63.5 145v735.3h895.7V145H63.5z m863.7 127.9v127.9H703.3V272.9h223.9zM383.4 496.7h287.9v127.9H383.4V496.7z m-32 127.9H95.5V496.7h255.9v127.9z m351.9-127.9h223.9v127.9H703.3V496.7z m-32-223.8v127.9H383.4V272.9h287.9z m-319.9 0v127.9H95.5V272.9h255.9zM95.5 848.4V720.5h255.9v127.9H95.5z m287.9 0V720.5h287.9v127.9H383.4z m319.9 0V720.5h223.9v127.9H703.3z" p-id="4313"></path></svg>
+<svg t="1726812889551" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1754" width="200" height="200"><path d="M896 896H96a32 32 0 0 1-32-32V224a32 32 0 0 1 64 0v608h768a32 32 0 1 1 0 64z" p-id="1755"></path><path d="M247.008 640a32 32 0 0 1-20.992-56.192l200.992-174.24a32 32 0 0 1 42.272 0.288l172.128 153.44 229.088-246.304a32 32 0 0 1 46.88 43.616l-250.432 269.216a31.936 31.936 0 0 1-44.704 2.08l-174.56-155.52-179.744 155.84a31.872 31.872 0 0 1-20.928 7.776z" p-id="1756"></path></svg>

+ 3 - 3
src/components/pages/addCourse.vue

@@ -7947,11 +7947,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 29 - 5
src/components/pages/aiAddCourse/addCourse.vue

@@ -4851,7 +4851,17 @@
                                   </div>
                                 </div>
                               </div>
-                              <evaList v-if="pjTemplateArray.indexOf(templateid) != -1"></evaList>
+                              <evaList 
+                              :toolsData="toolsData"
+                              :unitJson="unitJson"
+                              :itemTaskIndex="itemTaskIndex"
+                              :toolIndex="toolIndex"
+                              :knowFileids="knowFileids"
+                              :languageSetting="languageSetting" 
+                              :userid="userid" 
+                              @setEvaList="setEvaList"
+                              v-if="pjTemplateArray.indexOf(templateid) != -1 && pjIndex.indexOf(itemTool.tool[0]) != -1"
+                              :ref="'evalist'+itemTaskIndex+toolIndex"></evaList>
                             </div>
                             <button class="c_pub_button_add pub_btn_tool_img" @click="addToolFun(itemTaskIndex)" style="
                                 margin: 0 auto;
@@ -7380,6 +7390,7 @@ export default {
       knowinfoprogress: 0,
       knowFileids: [],
       pjTemplateArray: [ 'cf5722a4-401b-11ef-b873-005056b86cp5' ],
+      pjIndex: [52, 48, 1, 3, 16, 45, 47, 41]
     };
   },
   directives: {
@@ -7758,11 +7769,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;
@@ -19364,6 +19375,7 @@ ${this.courseText && this.aiCallBack[0] == 2 ? '注意,优化原有的<参考
                   _this.unitJson[0].chapterInfo[0].taskJson[index].toolChoose[_this.unitJson[0].chapterInfo[0].taskJson[index].toolChoose.length - 1].testJson = {"testCount":testJson.length,"testTitle":"","testJson":testJson} 
                 }
                 _this.unitJson[0].chapterInfo[0].taskJson[index].toolChoose[_this.unitJson[0].chapterInfo[0].taskJson[index].toolChoose.length - 1].tool = toolsJson[_task.toolChoose[j].tool] ? [toolsJson[_task.toolChoose[j].tool].tool] : [16] 
+
                 _this.$forceUpdate();
                 // _this.unitJson[0].chapterInfo[0].taskJson[index].toolChoose.push(_json)
               }
@@ -19379,10 +19391,18 @@ ${this.courseText && this.aiCallBack[0] == 2 ? '注意,优化原有的<参考
                 },
               )
             }
-            // }
+            // 
+
 
             // _this.unitJson2 = JSON.parse(JSON.stringify(_this.unitJson))
             _this.$forceUpdate();
+            _this.$nextTick(()=>{
+              for (var j = 0; j < _task.toolChoose.length; j++) {
+                if(_this.pjTemplateArray.indexOf(_this.templateid) !=-1 && _this.pjIndex.indexOf(toolsJson[_task.toolChoose[j].tool].tool) != -1){
+                  _this.$refs['evalist'+index+j][0].openAiDialog();
+                }
+              }
+            })
           }
           
           // callback ? callback() : ''
@@ -23375,6 +23395,10 @@ ${msg}
     },
     setIsQuote(string){
       this.isQuote[string] = false
+    },
+    setEvaList(task, tool, elist){
+      this.unitJson[0].chapterInfo[0].taskJson[task].toolChoose[tool].eList = elist
+      this.$forceUpdate()
     }
   },
   beforeDestroy() {

+ 642 - 291
src/components/pages/aiAddCourse/evaList.vue

@@ -1,17 +1,16 @@
 <template>
-    <div>
+    <div v-loading="loading" :style="{ minHeight: loading ? '250px' : 'auto' }" element-loading-text="小可正在努力生成中,请稍等...">
         <div class="elist_title">
             <div style=" display: flex; flex-direction: row;align-items: center; margin: 20px 0; ">
                 <div class="lineTitle clineTitle">评价设置</div>
                 <div style="margin-left:auto;display: flex;">
-                    <div class="r_pub_button_op" style="margin-left:10px;"
-                        @contextmenu.prevent="openAiDialog(1)"
+                    <div class="r_pub_button_op" style="margin-left:10px;" @contextmenu.prevent="openAiDialog(1)"
                         @click="openAiDialog(2)">{{ (eList && eList.length) ? '重新生成评价' : '生成评价' }}</div>
                 </div>
             </div>
         </div>
         <div class="mbCss">
-            <div class="pjCss" :style="{ width: isEvaFold ? 'calc(100% - 55%)' : 'calc(100% - 120px)', }">
+            <div class="pjCss">
                 <div v-if="eList && eList.length" class="elist_input">
                     <div v-for="(eItem, eIndex) in eList" :key="eIndex" class="elist_input_box">
                         <div class="elist_inptu_text">
@@ -19,8 +18,8 @@
                             <input type="input" v-model="eItem.target" placeholder="填写目标"
                                 style="width: calc(100% - 280px);" />
                             <el-switch @change="forceUpdate" class="rateSwitch" style="margin-left: auto;"
-                                v-model="eItem.isai" active-color="#0061FF" active-text="AI评分"
-                                inactive-text="" active-value="1" inactive-value="2">
+                                v-model="eItem.isai" active-color="#0061FF" active-text="AI评分" inactive-text=""
+                                active-value="1" inactive-value="2">
                             </el-switch>
                         </div>
                         <div class="elist_inptu_text">
@@ -32,14 +31,13 @@
                                 )
                                 "></div>
                         </div>
-                        <div class="elist_inptu_text" style="align-items: flex-start;"
-                            v-loading="ruleLoading[itemTaskIndex] && ruleLoading[itemTaskIndex][eIndex]"
-                            element-loading-text="小可正在努力生成中,请稍等...">
+                        <div class="elist_inptu_text" style="align-items: flex-start;">
                             <span>评价细则:</span>
                             <div style="width: calc(100%);">
-                                <div @click="openRule(itemTaskIndex, eIndex)" class="ruleBtn">{{ eItem.isrule ? '收起细则' : '展开细则' }}</div>
+                                <div @click="openRule(eIndex)" class="ruleBtn">{{ eItem.isrule ? '收起细则' : '展开细则' }}</div>
                                 <div style="width: calc(100%);" class='op_task_box' v-if="eItem.isrule">
-                                    <textarea v-autoHeight="68" rows="2" class="binfo_input binfo_textarea" cols v-model="eItem.rule" placeholder="请输入评价细则"></textarea>
+                                    <textarea v-autoHeight="68" rows="2" class="binfo_input binfo_textarea" cols
+                                        v-model="eItem.rule" placeholder="请输入评价细则"></textarea>
                                 </div>
                             </div>
 
@@ -60,473 +58,826 @@
 </template>
 
 <script>
+import { v4 as uuidv4 } from "uuid";
+var OpenCC = require("opencc-js");
+let converter2 = OpenCC.Converter({
+    from: 'cn',
+    to: 'hk'
+})
+
 export default {
+    props: {
+        toolsData:{
+            type: Object,
+            default: () => ({})
+        },
+        languageSetting: {
+            type: Number,
+            default: 0
+        },
+        userid: {
+            type: String,
+            default: ""
+        },
+        knowFileids: {
+            type: Array,
+            default: () => []
+        },
+        unitJson: {
+            type: Array,
+            default: () => []
+        },
+        itemTaskIndex: {
+            type: Number,
+            required: true
+        },
+        toolIndex: {
+            type: Number,
+            required: true
+        },
+    },
     data() {
         return {
-            eList:[],
-            isEvaFold: true
+            eList: [],
+            isEvaFold: true,
+            loading: false
         }
     },
+    watch: {
+        eList: {
+            handler(newVal) {
+                if(newVal.length > 0) {
+                    this.$emit('setEvaList', this.itemTaskIndex, this.toolIndex ,newVal)
+                }
+            },
+            immediate: true,
+            deep: true
+        },
+        // unitJson: {
+        //     handler(newVal) {
+        //         debugger
+        //         let elist = this.unitJson[0].chapterInfo[0].taskJson[this.itemTaskIndex].toolChoose[this.toolIndex].eList
+        //         this.eList = elist ? JSON.parse(JSON.stringify(elist))  : []
+        //     },
+        //     immediate: true,
+        //     deep: true
+        // }
+    },
+    directives: {
+        autoHeight: {
+            update(el, binding) {
+                const { value } = binding;
+                if (value && typeof value === "number") {
+                el.style.height = `${value}px`;
+                } else {
+                el.style.height = "auto";
+                }
+            },
+            componentUpdated(el) {
+                el.style.height = `${el.scrollHeight + 25}px`;
+            },
+        },
+    },
     methods: {
+        forceUpdate() {
+            this.$forceUpdate();
+        },
+        getLang() {
+            let lang = ''
+            if (this.languageSetting == 0) {
+                lang = 'Chinese.'
+            } else if (this.languageSetting == 1) {
+                lang = 'Traditional Chinese.'
+            } else if (this.languageSetting == 2) {
+                lang = 'English.'
+            }
+            return lang
+        },
         openAiDialog() {
-            
+            let _this = this
+            _this.loading = true
+
+            let fileid = _this.knowFileids.length ? [..._this.knowFileids] : []
+            let taskDetail = _this.unitJson[0].chapterInfo[0].taskJson[_this.itemTaskIndex].taskDetail.replaceAll('\n', ' ')
+            let tool = _this.toolsData[_this.unitJson[0].chapterInfo[0].taskJson[_this.itemTaskIndex].toolChoose[_this.toolIndex].tool[0]].name
+            let toolDetail = _this.unitJson[0].chapterInfo[0].taskJson[_this.itemTaskIndex].toolChoose[_this.toolIndex].toolDetail.replaceAll('\n', ' ')
+            let messages = `
+Language: ${this.getLang()}
+
+#上下文#
+你是一个资深的教师,你有丰富的项目式学习、跨学科学习、STEAM导师经验。
+
+<任务描述><工具名称>和<工具描述>是你的参考资料。任务描述中包含了多个学生活动,可能会用到多个工具。工具描述会告诉你学生要用这个工具完成怎样的作业。以下是可能出现的工具以及对应的功能。
+【文档】用于记笔记、写作文、设计实验或者撰写报告等文本类作业。
+【表格】用于记录数据、整理信息等
+【思维导图】用于科学探究的问题分析、头脑风暴等。把各个部分主次关系能直白的展示出来,能够帮助学习和记忆。
+【电子白板】用于个性化表达、自主设计类创意活动,系统支持概念图库,主要用于绘制概念图、梳理关键词/事件/问题之间的关系;或支持学生自由绘制一些方案设计图。
+【作业提交】支持各类文件格式的上传与显示,如png等图片格式、pptx、docx、txt、md等。
+【选择题】用于教师检查学生对知识的掌握和理解,参考指标为题目的正确率。
+【排序】通过设置卡片内容及正确顺序,用于教师使用排序类题目检查学生对知识的掌握和理解,参考指标为题目的正确率。。
+【选择匹配】通过上传题目图片与设置正确回答,用于教师使用选择匹配(连线)检查学生对知识的掌握和理解,参考指标为题目的正确率。
+
+你要学习上传的文件。文件中包含了该学科的“核心素养”和“课程目标”。“学科核心素养”指学生应具备的,能够适应终身发展和社会发展需要的必备品格和关键能力。“课程目标”指课程本身要实现的具体目标和意图。它规定了某一教育阶段的学生通过课程学习以后,在发展品德、智力、体质等方面期望实现的程度,它是确定课程内容、教学目标和教学方法的基础。你要理解学科核心素养和学科目标之间的关系。你生成的评价标准可以被理解为课程目标。
+
+#目标#
+你需要完成以下四个步骤:
+1.你要结合<任务描述:${taskDetail}><工具名称:${tool}>和<工具描述:${toolDetail}>生成适合当前作业的评价标准。评价标准用于评估学生的能力。
+2.你要严格按照上传的文件中的“核心素养”和“课程目标”将评价标准对应到课程目标中,并且用学科核心素养归类。如果没有合适的素养匹配,则输出“暂未检索到,请手动输入!”
+3.你要根据第一步生成的评价标准制定每一条标准的六级评价细则,这个评价细则将用于对学生能力的打分。
+4.你要将前三步生成的内容整理成json格式。
+
+#风格#
+专业的教育教学用语,简练易懂,逻辑性强。
+
+#语气#
+陈述
+
+#受众#
+教师
+
+#输出要求#
+1.评价标准的个数为3个,最多不能超过5个。每一个评价标准不能超过30字。生成的评价标准只能和当前的工具描述相关。选择题、排序、选择匹配工具只生成1个评价标准。输出内容和格式要求参考#评价标准范例#。注意!输出内容不能复制范例内容。注意!不要出现#评价标准错误范例#中的情况。
+2.每1个评价标准只对应1个关联度最高的核心素养。学科核心素养输出参考#核心素养输出范例#。注意!1个评价标准不能对应多个核心素养。
+3.具体的评价细则分为6级——0星,1星,2星,3星,4星,5星。输出格式参考#评价细则范例#。
+4.参考#json格式范例#,将内容整理成json格式。**之间的内容为json格式中的代码。以*[*开头,以*]*结尾。每一条评价标准、核心素养以及评价细则以*{*开头,以*}*结尾。核心素养前有*"core":*。评价标准前有*"std":*。评价细则前有*"rule":*。具体内容放在""之间。格式如下:
+[
+    {"std":"评价标准","core":"核心素养(学科)","rule":"评价细则"},
+    {"std":"评价标准","core":"核心素养(学科)","rule":"评价细则"},
+    {"std":"评价标准","core":"核心素养(学科)","rule":"评价细则"},
+]
+5.只输出json格式的内容,其他的不要输出!
+
+#评价标准范例#
+学生能够准确描述红树林生态功能及动植物之间的关系。 
+学生的调查报告完整详细,说明文逻辑清晰。 
+艺术作品反映了对红树林生态系统的创新理解。
+
+#评价标准错误范例#
+错误范例1:工具描述是“在完成动植物调查后,同学们需要使用文档工具撰写调查报告,详细描述调查过程和结果”,输出“艺术作品反映了对红树林生态系统的创新理解”。原因是:文档工具不能支持学生完成艺术作品。
+错误范例2:工具描述是“在实地考察或虚拟模拟中,同学们需要使用表格工具记录观察到的红树林生态功能和动植物信息”,输出“学生能够通过数据分析解释生态系统变化”。原因是:表格工具不能支持学生完成报告的撰写,所以不能学生通过表格工具解释变化。
+
+#评价细则范例#
+0 星,作业内容与作业要求无关;
+1 星,没有识别问题和需求;
+2 星,问题或需求没有被清晰理解或准确识别;
+3 星,问题或需求的一部分被识别;
+4 星,问题或需求的大部分被识别;
+5 星,问题或需求都被识别。 
+
+#核心素养输出范例#
+评价标准:学生应该能准确指出光合作用发生的具体部位(叶绿体),并解释叶绿体在光合作用中的重要性。
+这一条标准对应了《义务教育科学课程标准(2022年版)》中“科学观念”这一条核心素养。所以输出内容为:科学观念(识别上传文件对应的学科)。
+
+#json格式范例#
+[
+    {"std":"学生应该能清晰地解释光合作用的定义,包括植物利用光能将二氧化碳和水转化为葡萄糖和氧气的过程。","core":"科学观念(识别上传文件对应的学科)","rule":"0星,未能解释光合作用的定义,与主题无关。
+1星,尝试解释光合作用但描述与实际过程不符。
+2星,能够识别光合作用的要素之一,如光能、二氧化碳、水、葡萄糖或氧气,但未形成完整的定义。
+3星,能够部分描述光合作用的过程,例如知道植物利用光能进行转化,但未全面涵盖所有成分。
+4星,能够完整描述光合作用的过程,但细节或某些元素略显不足。
+5星,清晰完整地解释了光合作用的定义,包括如何利用光能将二氧化碳和水转化为葡萄糖和氧气的详细过程。
+"},
+    {"std":"学生应该能正确写出光合作用的化学反应式:6CO2 + 6H2O + 光能 → C6H12O6 + 6O2,并理解每个成分的作用。","core":"科学观念(识别上传文件对应的学科)","rule":"0星:未能写出任何相关的内容,完全没有涉及光合作用的化学反应式。
+1星:光合作用的化学反应式错误,完全没有正确的化学分子式。
+2星:能够部分写出光合作用的化学反应式,但分子式及其配比有较多错误,未能体现光能的作用。
+3星:基本写出大部分的光合作用化学反应式,但有小部分错误,对于光能的作用未能准确阐述。
+4星:能较完整写出光合作用的化学反应式,整体正确,但对每个成分的具体作用理解不够深入。
+5星:准确无误地写出光合作用的化学反应式,并能清晰、详细地解释每个成分的作用及其在反应中的重要性。
+"},
+    {"std":"学生应该能准确指出光合作用发生的具体部位(叶绿体),并解释叶绿体在光合作用中的重要性。","core":"科学观念(识别上传文件对应的学科)","rule":"
+0星,学生无法指出光合作用发生的部位,与要求完全不符;
+1星,学生对光合作用发生的部位有初步认知,但所指部位错误;
+2星,学生能部分识别光合作用相关的部位,但无法确定叶绿体;
+3星,学生能指出叶绿体,但无法解释其重要性;
+4星,学生能指出叶绿体,并能说明叶绿体在光合作用中的一个重要作用;
+5星,学生准确指出叶绿体,并详细解释其在光合作用中的重要性及其功能。
+"},
+]`
+            _this.loading = true
+
+            let params = {
+                assistant_id: '6063369f-289a-11ef-8bf4-12e77c4cb76b',
+                message: [{ "type": "text", "text": this.languageSetting == 1 ? converter2(messages.replaceAll('\n', " ").replaceAll('*', "")) : messages.replaceAll('\n', " ").replaceAll('*', "") }],
+                session_name: uuidv4(),
+                userId: _this.userid,
+                file_ids: fileid.length ? [...fileid] : '',
+                model: 'gpt-4o-2024-08-06',
+                temperature: 0.1,
+            }
+            _this.ajax.post('https://gpt4.cocorobo.cn/ai_agent_park_chat', params).then(function (response) {
+                console.log(response);
+                let data = response.data.FunctionResponse
+                if (data.message) {
+                    console.log(data.message);
+                    let elist = []
+                    try {
+                        elist = JSON.parse(data.message.replaceAll("```json", "").replaceAll("```", ""))
+                        elist = elist.map(el => {
+                                return {
+                                    isai : "1",
+                                    target: el.core,
+                                    value: "",
+                                    detail: el.std,
+                                    rule: el.rule.replace(/([;。])/g, '$1\n')
+                                }
+                            })
+                    } catch (e) {
+                        console.log("error_________________" + e);
+                        try {
+                            let regex = new RegExp("(?<=```json)([\\s\\S]*?)(?=```)");
+                            let match = data.message.match(regex);
+                            elist = JSON.parse(match[0])
+                            elist = elist.map(el => {
+                                return {
+                                    isai : "1",
+                                    target: el.core,
+                                    value: "",
+                                    detail: el.std,
+                                    rule: el.rule.replace(/([;。])/g, '$1\n')
+                                }
+                            })
+
+                        } catch (error) {
+                        }
+                    }
+
+                    console.log(elist);
+                    _this.eList = elist
+                    _this.$forceUpdate()
+                }
+                _this.loading = false
+            }).catch(function (error) {
+                _this.loading = false
+                console.log(error);
+            });
         },
-        addEList(){
+        addEList() {
 
         },
-        deletEList(){
-            
-        }
+        deletEList(index) {
+            this.$confirm('确定删除吗?').then(() => {
+                this.eList.splice(index, 1)
+                if(!this.eList.length){
+                    this.$emit('setEvaList', this.itemTaskIndex, this.toolIndex ,_this.eList)
+                }
+            })
+
+        },
+        openRule(i){
+            if(this.eList[i].isrule){
+                this.eList[i].isrule = false
+            }else {
+                this.eList[i].isrule = true
+            }
+            setTimeout(() => {
+                this.eList[i].rule += "*0*%*";
+                setTimeout(() => {
+                    this.eList[i].rule = this.eList[i].rule.replaceAll("*0*%*", "");
+                }, 0);
+            }, 100);
+            this.$forceUpdate();
+        },
     },
+    mounted() {
+        let elist = this.unitJson[0].chapterInfo[0].taskJson[this.itemTaskIndex].toolChoose[this.toolIndex].eList
+        this.eList = elist ? JSON.parse(JSON.stringify(elist))  : []
+    }
 }
 </script>
 
 <style scoped>
 /* 评价样式 */
 .elist_css {
-  padding-bottom: 75px !important;
+    padding-bottom: 75px !important;
 }
 
 .elist_title {
-  margin-bottom: 10px;
+    margin-bottom: 10px;
 }
 
 .elist_input {
-  width: 100%;
+    width: 100%;
 }
 
 .elist_input_box {
-  display: flex;
-  align-items: center;
-  flex-wrap: wrap;
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
 }
 
 .elist_input_box+.elist_input_box {
-  margin-top: 30px;
+    margin-top: 30px;
 }
 
 .elist_input .elist_input_box input {
-  font: inherit;
-  color: currentColor;
-  width: 100%;
-  /* max-width: calc(100% - 385px); */
-  max-width: calc(100% - 150px);
-  padding: 8px 14px;
-  display: block;
-  min-width: 0;
-  outline: none;
-  border: 1px solid rgba(0, 0, 0, 0.23);
-  border-radius: 4px;
-  box-sizing: border-box;
-  background: #fff;
-  margin: 0 20px 0 0;
+    font: inherit;
+    color: currentColor;
+    width: 100%;
+    /* max-width: calc(100% - 385px); */
+    max-width: calc(100% - 150px);
+    padding: 8px 14px;
+    display: block;
+    min-width: 0;
+    outline: none;
+    border: 1px solid rgba(0, 0, 0, 0.23);
+    border-radius: 4px;
+    box-sizing: border-box;
+    background: #fff;
+    margin: 0 20px 0 0;
 }
 
 .elist_input .elist_input_box span {
-  height: 36px;
-  line-height: 36px;
-  color: rgb(82, 82, 82);
-  min-width: 80px;
+    height: 36px;
+    line-height: 36px;
+    color: rgb(82, 82, 82);
+    min-width: 80px;
 }
 
-.elist_input .elist_input_box .remove {
-  height: 20px;
-  width: 20px;
-  min-height: 20px;
-  min-width: 20px;
+.remove {
+  background-image: url("../../../assets/icon/new/delete_u.png");
+  cursor: pointer;
+  opacity: 0.5;
+  width: 30px;
+  min-width: 30px;
+  height: 30px;
   background-size: 100% 100%;
-  background-position: unset;
-  margin-left: 5px;
+  background-repeat: no-repeat;
+  margin-left: 10px;
+}
+
+.elist_input .elist_input_box .remove {
+    height: 20px;
+    width: 20px;
+    min-height: 20px;
+    min-width: 20px;
+    background-size: 100% 100%;
+    background-position: unset;
+    margin-left: 5px;
 }
 
 .elist_input_box>>>.el-rate {
-  display: flex;
-  height: 36px;
-  align-items: center;
+    display: flex;
+    height: 36px;
+    align-items: center;
 }
 
 .elist_input_box .elist_inptu_text {
-  width: 100%;
-  display: flex;
-  align-items: center;
-  margin-top: 10px;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    margin-top: 10px;
 }
 
 .elist_input_box .elist_inptu_text input {
-  /* width: 500px; */
-  width: 100%;
-  max-width: unset;
+    /* width: 500px; */
+    width: 100%;
+    max-width: unset;
 }
 
 .elist_input_box>>>.el-rate__icon {
-  font-size: 24px;
+    font-size: 24px;
 }
 
 .elist_btn {
-  margin-top: 10px;
+    margin-top: 10px;
 }
 
 .lineTitle {
-  /* margin-top: 15px; */
-  width: 110px;
-  font-size: 16px;
-  display: flex;
-  align-items: center;
-  line-height: 20px;
+    /* margin-top: 15px; */
+    width: 110px;
+    font-size: 16px;
+    display: flex;
+    align-items: center;
+    line-height: 20px;
 }
 
 .lineTitle::before {
-  content: "";
-  display: block;
-  width: 3px;
-  height: 20px;
-  background: #0061ff;
-  border-radius: 3px;
-  margin: 0 5px 0 0;
+    content: "";
+    display: block;
+    width: 3px;
+    height: 20px;
+    background: #0061ff;
+    border-radius: 3px;
+    margin: 0 5px 0 0;
 }
 
 .clineTitle::before {
-  content: "";
-  display: block;
-  min-width: 10px;
-  width: 10px;
-  height: 10px;
-  background: #0061ff;
-  border-radius: 50%;
-  margin: 0 5px 0 0;
+    content: "";
+    display: block;
+    min-width: 10px;
+    width: 10px;
+    height: 10px;
+    background: #0061ff;
+    border-radius: 50%;
+    margin: 0 5px 0 0;
 }
 
 .courseTop {
-  display: flex;
-  flex-direction: row;
-  justify-content: space-between;
-  align-items: center;
-  width: calc(100% - 40px);
-  margin: 0 auto;
-  padding: 10px 0;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    width: calc(100% - 40px);
+    margin: 0 auto;
+    padding: 10px 0;
 }
 
 .stepsNav {
-  display: flex;
-  flex-direction: row;
-  justify-content: flex-start;
-  align-items: center;
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    align-items: center;
 }
 
 .stepsWord {
-  font-size: 18px;
-  color: #fff;
-  font-weight: bold;
-  margin-left: auto;
-  background: rgb(15, 126, 255);
-  border-radius: 5px;
-  padding: 3px 25px;
-  box-sizing: border-box;
+    font-size: 18px;
+    color: #fff;
+    font-weight: bold;
+    margin-left: auto;
+    background: rgb(15, 126, 255);
+    border-radius: 5px;
+    padding: 3px 25px;
+    box-sizing: border-box;
 }
 
 .stepBox {
-  width: calc(100% - 40px);
-  height: calc(100% - 50px);
-  overflow: hidden;
-  border-radius: 5px;
-  margin: 0 auto;
+    width: calc(100% - 40px);
+    height: calc(100% - 50px);
+    overflow: hidden;
+    border-radius: 5px;
+    margin: 0 auto;
 }
 
 .rightBox {
-  width: calc(100%);
-  background: #f0f2f5;
-  /* border-radius: 10px; */
-  overflow: auto;
-  height: calc(100% - 150px);
-  margin: 0 auto;
-  position: relative;
-  box-sizing: border-box;
+    width: calc(100%);
+    background: #f0f2f5;
+    /* border-radius: 10px; */
+    overflow: auto;
+    height: calc(100% - 150px);
+    margin: 0 auto;
+    position: relative;
+    box-sizing: border-box;
 }
 
 .e_add_top {
-  display: flex;
-  justify-content: space-between;
-  background: #fff;
-  position: absolute;
-  right: 20px;
-  height: 50px;
-  align-items: center;
+    display: flex;
+    justify-content: space-between;
+    background: #fff;
+    position: absolute;
+    right: 20px;
+    height: 50px;
+    align-items: center;
 }
 
 .e_add_title2 {
-  display: flex;
-  align-items: center;
+    display: flex;
+    align-items: center;
 }
 
 .e_add_title2 span {
-  width: 40px;
+    width: 40px;
 }
 
 .e_add_title {
-  display: flex;
-  align-items: center;
-  color: #b8b8b8;
-  font-size: 18px;
-  position: relative;
-  height: 40px;
+    display: flex;
+    align-items: center;
+    color: #b8b8b8;
+    font-size: 18px;
+    position: relative;
+    height: 40px;
 }
 
 .e_add_title span {
-  margin-right: 10px;
+    margin-right: 10px;
 }
 
 .e_add_title .el_input {
-  width: 300px;
+    width: 300px;
 }
 
 .e_add_title>>>.el-input__inner {
-  width: 400px;
+    width: 400px;
 }
 
 .e_add_btn {}
 
 .e_add_content {
-  display: flex;
-  width: 100%;
+    display: flex;
+    width: 100%;
 }
 
 .e_add_list {
-  background: #fff;
-  height: 500px;
-  width: 210px;
-  position: relative;
-  margin: 15px 5px 0 0;
-  flex-shrink: 0;
-  display: flex;
-  flex-direction: column;
+    background: #fff;
+    height: 500px;
+    width: 210px;
+    position: relative;
+    margin: 15px 5px 0 0;
+    flex-shrink: 0;
+    display: flex;
+    flex-direction: column;
 }
 
 .e_add_list_title {
-  font-size: 20px;
-  width: 100%;
-  box-sizing: border-box;
-  padding: 15px 40px;
-  text-align: center;
-  border-bottom: 1px solid #eaeaea;
-  position: relative;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  height: 57px;
-  background: #f6f6f6;
+    font-size: 20px;
+    width: 100%;
+    box-sizing: border-box;
+    padding: 15px 40px;
+    text-align: center;
+    border-bottom: 1px solid #eaeaea;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 57px;
+    background: #f6f6f6;
 }
 
 .e_add_list_title span {
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
 }
 
 .e_add_list_title img {
-  position: absolute;
-  right: 15px;
-  width: 25px;
-  cursor: pointer;
-  top: 50%;
-  transform: translateY(-50%);
+    position: absolute;
+    right: 15px;
+    width: 25px;
+    cursor: pointer;
+    top: 50%;
+    transform: translateY(-50%);
 }
 
 .e_add_list_body {
-  height: calc(100% - 187px);
-  overflow: auto;
+    height: calc(100% - 187px);
+    overflow: auto;
 }
 
 .e_add_list_child {
-  width: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  position: relative;
-  box-sizing: border-box;
-  padding: 15px 40px;
-  text-align: center;
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: relative;
+    box-sizing: border-box;
+    padding: 15px 40px;
+    text-align: center;
 }
 
 .e_add_list_child span {
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  cursor: pointer;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    cursor: pointer;
 }
 
 .e_add_list_child img {
-  position: absolute;
-  right: 10px;
-  width: 21px;
-  cursor: pointer;
-  top: 50%;
-  transform: translateY(-50%);
+    position: absolute;
+    right: 10px;
+    width: 21px;
+    cursor: pointer;
+    top: 50%;
+    transform: translateY(-50%);
 }
 
 .e_add_list_child+.e_add_list_child {
-  border-top: 1px solid #eaeaea;
+    border-top: 1px solid #eaeaea;
 }
 
 .e_add_list_child .active {
-  color: #409eff;
+    color: #409eff;
 }
 
 .e_add_list_btn {
-  position: absolute;
-  bottom: 0;
-  height: 50px;
-  background: rgb(120, 120, 254);
-  width: 100%;
-  color: #fff;
-  font-size: 16px;
-  text-align: center;
-  line-height: 50px;
-  cursor: pointer;
+    position: absolute;
+    bottom: 0;
+    height: 50px;
+    background: rgb(120, 120, 254);
+    width: 100%;
+    color: #fff;
+    font-size: 16px;
+    text-align: center;
+    line-height: 50px;
+    cursor: pointer;
 }
 
 .e_add_list_detail {
-  position: absolute;
-  bottom: 0;
-  height: 130px;
-  background: rgb(120, 120, 254);
-  width: 100%;
-  color: #fff;
-  font-size: 16px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
+    position: absolute;
+    bottom: 0;
+    height: 130px;
+    background: rgb(120, 120, 254);
+    width: 100%;
+    color: #fff;
+    font-size: 16px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
 }
 
 .e_add_list_detail textarea {
-  height: 90%;
-  width: 95%;
-  border: none;
-  resize: none;
-  outline: none;
-  padding: 5px;
-  box-sizing: border-box;
+    height: 90%;
+    width: 95%;
+    border: none;
+    resize: none;
+    outline: none;
+    padding: 5px;
+    box-sizing: border-box;
 }
 
 .e_add_list_pbox {
-  width: 100%;
+    width: 100%;
 }
 
 .e_add_list_pbox_title {
-  height: 50px;
-  background: #fff;
-  display: flex;
-  align-items: center;
-  width: 100%;
-  box-sizing: border-box;
-  padding: 0 20px;
-  flex-direction: row;
-  flex-wrap: wrap;
+    height: 50px;
+    background: #fff;
+    display: flex;
+    align-items: center;
+    width: 100%;
+    box-sizing: border-box;
+    padding: 0 20px;
+    flex-direction: row;
+    flex-wrap: wrap;
 }
 
 .mbCss {
-  width: 100%;
-  display: flex;
-  flex-direction: row;
-  flex-wrap: nowrap;
-  align-content: center;
-  align-items: flex-start;
-  justify-content: flex-start;
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    align-content: center;
+    align-items: flex-start;
+    justify-content: flex-start;
 }
 
 .pjCss {
-  /* width: 42%; */
-  width: calc(100% - 55%);
-  display: flex;
-  flex-direction: column;
-  flex-wrap: nowrap;
-  align-items: flex-start;
+    /* width: 42%; */
+    width: calc(100%);
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    align-items: flex-start;
 }
 
 .e_box {
-  /* display: flex; */
-  flex-wrap: wrap;
-  max-height: 500px;
-  align-items: flex-start;
-  overflow: auto;
-  width: 100%;
+    /* display: flex; */
+    flex-wrap: wrap;
+    max-height: 500px;
+    align-items: flex-start;
+    overflow: auto;
+    width: 100%;
 }
 
 .e_card {
-  border: 1px solid #ccc;
-  background: #fff;
-  margin-right: 20px;
-  width: 270px;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  border-radius: 5px;
-  margin-top: 10px;
-  text-align: center;
+    border: 1px solid #ccc;
+    background: #fff;
+    margin-right: 20px;
+    width: 270px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    border-radius: 5px;
+    margin-top: 10px;
+    text-align: center;
 }
 
 .e_card_picture {
-  margin: 10px 0;
+    margin: 10px 0;
 }
 
 .e_card_picture>img {
-  width: 50px;
+    width: 50px;
 }
 
 .e_card_name {
-  width: 100%;
-  padding: 0 10px;
-  box-sizing: border-box;
-  margin-bottom: 10px;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
+    width: 100%;
+    padding: 0 10px;
+    box-sizing: border-box;
+    margin-bottom: 10px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
 }
 
 .e_card_time {
-  width: 100%;
-  padding: 0 10px;
-  box-sizing: border-box;
-  font-size: 15px;
-  color: #c3c3c3;
-  margin-bottom: 10px;
+    width: 100%;
+    padding: 0 10px;
+    box-sizing: border-box;
+    font-size: 15px;
+    color: #c3c3c3;
+    margin-bottom: 10px;
 }
 
 .e_card_btn {
-  height: 40px;
-  display: flex;
-  align-items: center;
-  width: 100%;
-  background: rgb(244, 244, 244);
+    height: 40px;
+    display: flex;
+    align-items: center;
+    width: 100%;
+    background: rgb(244, 244, 244);
 }
 
 .e_card_btn:hover {
-  background: rgb(221 221 221);
+    background: rgb(221 221 221);
 }
 
 .e_card_btn span {
-  flex: 1 1 auto;
-  text-align: center;
-  cursor: pointer;
+    flex: 1 1 auto;
+    text-align: center;
+    cursor: pointer;
 }
 
 .addEva {
-  border: 1px solid #ccc;
+    border: 1px solid #ccc;
+    background: #fff;
+    margin-right: 20px;
+    width: 270px;
+    height: 149px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    border-radius: 5px;
+    margin-top: 10px;
+    text-align: center;
+    cursor: pointer;
+    justify-content: center;
+}
+
+.addEva>img {
+    width: 50px;
+    object-fit: cover;
+}
+
+.ruleBtn {
+  width: fit-content;
+  height: 36px;
+  line-height: 36px;
+  cursor: pointer;
+  color: #0061FF;
+}
+
+.op_task_box,
+.op_tool_box,
+.outline_detail {
+  position: relative;
+}
+
+.op_task_box:hover .op_box,
+.op_tool_box:hover .op_box,
+.outline_detail:hover .op_box {
+  display: flex
+}
+
+.binfo_input {
+  width: 100%;
+  margin: 0;
+  padding: 12px 14px;
+  display: block;
+  min-width: 0;
+  outline: none;
+  box-sizing: border-box;
+  background: none;
+  border: none;
+  border-radius: 4px;
   background: #fff;
-  margin-right: 20px;
-  width: 270px;
-  height: 149px;
+  font-size: 16px;
+  resize: none;
+  font-family: "Microsoft YaHei";
+  min-height: 48px;
+  /* border: 1px solid #3682fc00; */
+  border: 1.5px solid #cad1dc;
+}
+
+.binfo_textarea {
+  border: 1.5px solid #cad1dc;
+  font-size: 16px;
+  resize: none;
+  /* background: #f6f6f6; */
+  font-family: "Microsoft YaHei";
+}
+
+.binfo_input:focus-visible {
+  border: 1.5px solid #3681fc !important;
+}
+.rateSwitch >>> .el-switch__label.is-active {
+  color: #0061FF;
+}
+
+.rateSwitch >>> .el-switch__label--right{
   display: flex;
-  flex-direction: column;
   align-items: center;
-  border-radius: 5px;
-  margin-top: 10px;
-  text-align: center;
-  cursor: pointer;
-  justify-content: center;
 }
-
-.addEva>img {
-  width: 50px;
-  object-fit: cover;
+.rateSwitch >>> .el-switch__label--right::before{
+  content: "";
+  width: 14px;
+  height: 14px;
+  min-width: 14px;
+  min-height: 14px;
+  background-size: 100% 100%;
+  display: block;
+  margin-right: 7px;
+  background-image: url(../../../assets/icon/new/u_op2.png);
 }
+.rateSwitch >>> .el-switch__label--right.is-active::before{
+  background-image: url(../../../assets/icon/new/u_op.png);
+}
+
 </style>

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

@@ -571,7 +571,7 @@ export default {
 				{value:'0',label:"无"},
 				{value:'1',label:"词云图"},
 				{value:'2',label:"雷达图"},
-				{value:'3',label:"柱图"},
+				{value:'3',label:"能量柱图"},
 			],
       form: {
         name: "",

File diff ditekan karena terlalu besar
+ 505 - 465
src/components/pages/classroomObservation/components/analysisItem.vue


+ 147 - 96
src/components/pages/classroomObservation/components/analysisSpecialItem.vue

@@ -126,7 +126,7 @@
           </el-tooltip>
         </span>
 
-        <!-- <span
+        <span
           v-if="loadNum != 1 && openItem && tid"
           @click.stop="editBtn(true)"
         >
@@ -142,22 +142,22 @@
               "
             />
           </el-tooltip>
-        </span> -->
-
-				<span v-if="loadNum != 1 && openItem && tid" @click="editEcharts(true)">
-					<el-tooltip
-						class="item"
-						effect="light"
-						content="生成图表"
-						placement="top"
-					>
-						<img
-							:src="
-								require('../../../../assets/icon/classroomObservation/echartIcon.svg')
-							"
-						/>
-					</el-tooltip>
-				</span>
+        </span>
+
+        <span v-if="loadNum != 1 && openItem && tid" @click="editEcharts(true)">
+          <el-tooltip
+            class="item"
+            effect="light"
+            content="生成图表"
+            placement="top"
+          >
+            <img
+              :src="
+                require('../../../../assets/icon/classroomObservation/echartIcon.svg')
+              "
+            />
+          </el-tooltip>
+        </span>
 
         <!-- <span class="ai-h-r-icon4" @click.stop="delBtn()"></span> -->
       </div>
@@ -209,6 +209,7 @@ let converter2 = OpenCC.Converter({
 });
 import mdView from "./mdView.vue";
 import eChartTemplate from "./eChartTemplate";
+import { v4 as uuidv4 } from "uuid";
 // import editNameDialog from './editNameDialog.vue'
 export default {
   emits: ["delItem", "editItem", "saveItem"],
@@ -318,10 +319,10 @@ export default {
       this.loadNum = 0;
       this.openItem = newValue;
     },
-    editBtn() {
-      // if (!flag) return console.log("不执行获取");
-      // this.loadNum = 1;
-      // this.getData();
+    editBtn(flag = false) {
+      if (!flag) return console.log("不执行获取");
+      this.loadNum = 1;
+      this.getData(1);
 
       // this.ajax
       // 	.post("https://gpt4.cocorobo.cn/ai_agent_park_chat", parm)
@@ -360,12 +361,12 @@ export default {
       // 	});
     },
 
-		editEcharts(flag = false){
-			if (!flag) return console.log("不执行获取");
+    editEcharts(flag = false) {
+      if (!flag) return console.log("不执行获取");
       this.loadNum = 1;
-      this.getData();
-		},
-    getAtAuContent(_uid, _text, _headUrl, _assistantName) {
+      this.getData(0);
+    },
+    getAtAuContent(_uid) {
       let _source = new EventSource(
         `https://gpt4.cocorobo.cn/question/${_uid}`
       ); //http://gpt4.cocorobo.cn:8011/question/   https://gpt4.cocorobo.cn/question/
@@ -420,7 +421,7 @@ export default {
         }
       };
     },
-    getData() {
+    getData(type = 0) {
       if (!this.bmData.editorBarData || this.bmData.editorBarData.type != 0) {
         this.loadNum = 2;
         return this.$message.info("请上传表格形式的转录文稿");
@@ -446,11 +447,11 @@ export default {
         });
         if (_result.length == 0) return this.$message.error("未找到表格数据");
         if (this.data.jsonData.name == "S-T分析:课堂时间分配") {
-          this.getTimeAllocationData(_result);
+          this.getTimeAllocationData(_result, type);
         } else if (this.data.jsonData.name == "S-T分析:师生互动分析") {
-          this.getInteractionAnalysisData(_result);
+          this.getInteractionAnalysisData(_result, type);
         } else if (this.data.jsonData.name == "S-T分析:教学模式分析") {
-          this.getTeachingModeData(_result);
+          this.getTeachingModeData(_result, type);
         } else {
           return this.$message.error("未找到对应的分析");
         }
@@ -462,7 +463,7 @@ export default {
       }
     },
     // 课堂时间分配
-    getTimeAllocationData(_dataList) {
+    getTimeAllocationData(_dataList, type = 0) {
       this.loading = true;
       this.openItem = false;
       let _data = _dataList.reduce(
@@ -479,83 +480,70 @@ export default {
           { value: 0, name: "学生" }
         ]
       );
+
+			let _dataPercentage = _data
+			_data.forEach((i, index) => {
+				_dataPercentage[index].percentage = (i.value / _data.reduce((pre, cur) => pre + cur.value, 0) * 100).toFixed(2)+'%'
+			})
+
+			_dataPercentage.forEach(i=>delete i.value)
+      if (type == 1) {
+        let _msg = `这是某一节课的师生时间占比,请你分析,写出结论,并给出指导建议。请使用3句完整的话,分析并给出建议。 请注意,当老师或学生的时间占比在【40~59%】之间的时候,也认为师生占比约为1:1,各占50%,师生时间占比比较均衡。
+师生时间占比数据:
+老师占比:${_dataPercentage[0].percentage}
+学生占比:${_dataPercentage[1].percentage}
+`;
+        return this.getAiContent(_msg)
+      }
+
       const _option = {
-				// title: {
+        // title: {
         //   text: "课堂时间分配",
         //   left: "center"
         // },
-      	tooltip: {
-					// text: "课堂时间分配",
-					 left: "center",
-      		trigger: "item",
-      		formatter: "{a} <br/>{b}: {d}%"  // {a}为系列名,{b}为数据名,{d}为百分比
-      	},
-      	legend: {
-      		top: "5%",
-					// orient: "vertical",
-      		left: "center",
-      	},
-      	series: [
-      		{
-      			name: "课堂时间分配",
-      			type: "pie",
-      			radius: ["40%", "70%"],
-      			// avoidLabelOverlap: false,
-      			label: {
-							formatter: "{b}: {d}%"
-      				// show: false,
-      				// position: "center",
-      			},
-      			emphasis: {
-      				label: {
-      					show: true,
-      					// fontSize: 40,
-      					// fontWeight: "bold",
-      					formatter: "{b}: {d}%"  // 显示百分比
-      				},
-							itemStyle: {
-                shadowBlur: 10,
-                shadowOffsetX: 0,
-                shadowColor: "rgba(0, 0, 0, 0.5)"
-              }
-      			},
-      			// labelLine: {
-      			// 	show: false,
-      			// },
-      			data: _data
-      		},
-      	],
-      };
-
-      const _option2 = {
-        title: {
-          text: "课堂时间分配",
-          subtext: "Fake Data",
-          left: "center"
-        },
         tooltip: {
-          trigger: "item"
+          // text: "课堂时间分配",
+          left: "center",
+          trigger: "item",
+          formatter: "{a} <br/>{b}: {d}%" // {a}为系列名,{b}为数据名,{d}为百分比
         },
         legend: {
-          orient: "vertical",
-          left: "left"
+          top: "5%",
+          // orient: "vertical",
+          left: "center"
         },
         series: [
           {
             name: "课堂时间分配",
             type: "pie",
-            radius: "50%",
-            data: _data,
+            radius: ["40%", "70%"],
+            // avoidLabelOverlap: false,
+            label: {
+              formatter: "{b}: {d}%"
+              // show: false,
+              // position: "center",
+            },
             emphasis: {
+              label: {
+                show: true,
+                // fontSize: 40,
+                // fontWeight: "bold",
+                formatter: "{b}: {d}%" // 显示百分比
+              },
               itemStyle: {
                 shadowBlur: 10,
                 shadowOffsetX: 0,
                 shadowColor: "rgba(0, 0, 0, 0.5)"
               }
-            }
+            },
+            // labelLine: {
+            // 	show: false,
+            // },
+            data: _data
           }
         ]
       };
+
       let _copyData = JSON.parse(JSON.stringify(this.data));
       _copyData.jsonData.eChartData = _option;
       _copyData.json_data = JSON.stringify(_copyData.jsonData);
@@ -568,7 +556,7 @@ export default {
       this.loading = false;
     },
     // 师生互动分析
-    getInteractionAnalysisData(_dataList) {
+    getInteractionAnalysisData(_dataList, type = 0) {
       this.loading = true;
       this.openItem = false;
       let _pushData = [0, 0];
@@ -584,6 +572,19 @@ export default {
       let _flatArray = _result.flat();
       const _max = Math.max(..._flatArray);
       const _maxValue = Math.ceil(_max / 100) * 100;
+
+      if (type == 1) {
+        let _msg = `
+## 任务 
+请你结合 FIAS 相关的知识,根据以下提供给你的课堂原始数据(包含S和t的数据),请你具体描述整个课堂S行为与T行为的持续性与变化性。比如,课堂一开始老师占比主导,大约5分钟之后,进入到学生为主的小组讨论环节。在整个课堂之中,老师与学生的互动比较频繁,老师会频繁询问学生问题,引导学生思考。之后是授课时间与问答时间。等等。
+## 输出要求 请使用自然语言进行描述,使用不超过5句完整的话进行整体性、概括性的描述,不要包含具体的时长信息。总结性概括之后,使用1句话对整个课堂的教师引导行为进行鼓励和评价,再使用1句话给出相应的优化建议。
+## 你的知识库 定义与目的:S-T图,即学生-教师(Student-Teacher)图,主要用于记录和分析课堂上的学生行为(S)与教师行为(T)的时间分布。这种图形能够帮助教育专家和教师可视化课堂互动的流程,从而判断课堂的教学型态,如练习型、对话型、讲授型或混合型。 绘制方法:S-T图的绘制开始于教学的起始时刻,纵轴表示学生行为(S),横轴表示教师行为(T)。实际课堂观察或录像回放中,按照固定时间间隔(通常每30秒)采样,将对应的行为按时间顺序标记在相应的轴上。通过这种方法,可以清晰看到课堂上教师行为与学生行为的交替模式及其随时间的变化。 应用场景:例如,一个典型的应用是在分析不同类型课堂活动时使用S-T图。在讲授型课堂中,教师行为的时间占比会较高,S-T图显示较长的横轴(T行为)延续;而在练习型或对话型课堂中,学生行为的时间占比增高,显示为较长的纵轴(S行为)。
+## 课堂实录
+${JSON.stringify(_dataList)}
+`;
+        return this.getAiContent(_msg);
+      }
+
       const _option = {
         xAxis: {
           name: "老师", // X轴标题
@@ -638,7 +639,7 @@ export default {
       this.loading = false;
     },
     // 教学模式分析
-    getTeachingModeData(_dataList) {
+    getTeachingModeData(_dataList, type = 0) {
       this.openItem = false;
       this.loading = true;
       let _continuousTime = 0;
@@ -698,6 +699,19 @@ export default {
 
       let _RT = (_teacherTime / _totalTime).toFixed(2);
       let _CH = (_continuousTime / _totalTime).toFixed(2);
+
+      if (type == 1) {
+        let _msg = `## 任务
+根据FIAS(弗兰德斯互动分析系统)理论,计算获得某一节课的RT和CH值。请你结合FIAS相关知识进行分析,使用3句完整的话对整个课堂进行分析,需注意包含这些内容:分析该课堂所属的教学模型,描述课堂的整体表现与特征,肯定老师做出的努力,以及给出相应的建议。 
+## 你的知识 
+根据RT和CH的值,教学模式通常被分为以下几种类型: 练习型:RT ≤ 0.3,表示学生行为占主导,教师行为较少。 讲授型:RT ≥ 0.7,表示教师行为占主导,学生参与较少。 对话型:CH ≥ 0.4,表示师生之间有较多的互动和转换。 混合型:0.3 < RT < 0.7,CH < 0.4,表示教学中既有教师讲授也有学生参与,但两者都不占绝对优势。
+## 数据
+RT:${_RT}
+CH:${_CH}
+`;
+        return this.getAiContent(_msg);
+      }
+
       let _copyData = JSON.parse(JSON.stringify(this.data));
       _copyData.jsonData.RT = _RT;
       _copyData.jsonData.CH = _CH;
@@ -710,6 +724,43 @@ export default {
       this.changeShowIndex(1);
       this.loading = false;
     },
+    getAiContent(_msg) {
+      let parm = {
+        assistant_id: "f8e1ebb2-2e0d-11ef-8bf4-12e77c4cb76b",
+        message: _msg,
+        session_name: uuidv4(),
+        userId: this.userId,
+        file_ids: "",
+        model: "gpt-4o-2024-08-06"
+      };
+
+      this.ajax
+        .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", parm)
+        .then(res => {
+          let _data = res.data.FunctionResponse;
+          let _copyData = JSON.parse(JSON.stringify(this.data));
+          _copyData.jsonData.content = _data.message;
+          // _copyData.jsonData.dataFileList = [];
+          // _copyData.jsonData.fileList = [];
+          _copyData.json_data = JSON.stringify(_copyData.jsonData);
+          if (this.historyResult.length == 0) {
+            this.historyResult.push(_copyData.jsonData);
+          } else {
+            this.historyResult.splice(
+              this.showIndex + 1,
+              0,
+              _copyData.jsonData
+            );
+          }
+          this.changeShowIndex(1);
+          this.loading = false;
+        })
+        .catch(err => {
+          this.loadNum = 2;
+          // this.$message.error("AI无法识别优化");
+          this.loading = false;
+        });
+    },
     delBtn() {
       this.$confirm("确定删除?", "提示", {
         confirmButtonText: "确定",
@@ -1005,19 +1056,19 @@ th {
 }
 
 .a_h_l_t_input {
-	width: 25%;
-	min-width: 220px;
+  width: 25%;
+  min-width: 220px;
   height: 100%;
   display: flex;
   align-items: center;
 }
 
-.a_h_l_t_input>>>.el-form{
-	width: 100%;
-	min-width: 220px;
+.a_h_l_t_input >>> .el-form {
+  width: 100%;
+  min-width: 220px;
 }
 
-.a_h_l_t_input>>>.el-form-item{
-	margin-bottom: 0;
+.a_h_l_t_input >>> .el-form-item {
+  margin-bottom: 0;
 }
 </style>

+ 0 - 3
src/components/pages/classroomObservation/components/saveTemplateDialog.vue

@@ -119,9 +119,6 @@ export default {
 				brief:"",
 				permissions:false,
 			};
-		},
-		search(){
-			
 		},
 		submitBtn(ref) {
 			this.$refs[ref].validate((valid) => {

+ 31 - 44
src/components/pages/classroomObservation/components/sharePdf.vue

@@ -1,31 +1,29 @@
 <template>
   <el-dialog
-    :visible.sync="localDialogVisibleShare"
+    :visible.sync="show"
     :append-to-body="true"
     width="560px"
     :before-close="handleClose"
     class="dialog_diy"
   >
     <div class="share_box">
-     
-   
       <div class="url_box">
         <div class="title">
           分享链接
         </div>
         <div class="url">
-					<el-input
-          class="sc_fu_input"
-          style="color: black"
-          disabled
-          v-model="origin"
-        >
-          <template slot="append"
-            ><div class="sc_fu_copyBtn" @click.stop="copy()">
-              复制链接
-            </div></template
+          <el-input
+            class="sc_fu_input"
+            style="color: black"
+            disabled
+            v-model="origin"
           >
-        </el-input>
+            <template slot="append"
+              ><div class="sc_fu_copyBtn" @click.stop="copy()">
+                复制链接
+              </div></template
+            >
+          </el-input>
           <!-- <el-tooltip :content="origin" placement="top" effect="dark">
             <span>{{ origin }}</span>
           </el-tooltip>
@@ -61,14 +59,10 @@ import Clipboard from "clipboard";
 import QRCode from "qrcodejs2";
 export default {
   props: {
-    dialogVisibleShare: {
-      type: Boolean,
-      default: false
-    },
-		tid:{
-			type:String,
-			default:"",
-		}
+    tid: {
+      type: String,
+      default: ""
+    }
   },
   data() {
     return {
@@ -77,7 +71,7 @@ export default {
       copyText2: "",
       noCount: 0,
       pname: [],
-      localDialogVisibleShare: this.dialogVisibleShare
+      show: false
     };
   },
   methods: {
@@ -85,13 +79,17 @@ export default {
       this.close();
       done();
     },
+    open() {
+      this.show = true;
+      this.setQr();
+    },
     close() {
-    //   this.$emit("update:dialogVisibleShare", false);
-      this.$emit('shareBtn');
-
+      //   this.$emit("update:dialogVisibleShare", false);
+      // this.$emit('shareBtn');
+      this.show = false;
     },
     setQr() {
-      setTimeout(() => {
+      this.$nextTick(() => {
         let url = `https://beta.cloud.cocorobo.cn/aigpt/#/classroom_observation_board?tid=${this.tid}`;
         this.origin = url;
         this.$refs.qrCodeUrl.innerHTML = "";
@@ -103,7 +101,7 @@ export default {
           colorLight: "#ffffff",
           correctLevel: QRCode.CorrectLevel.H
         });
-      }, 500);
+      });
     },
     downQr() {
       // 创建一个虚拟链接,并将 canvas 转换为图片文件
@@ -115,7 +113,7 @@ export default {
       link.click();
     },
     copy() {
-			const input = document.createElement("input");
+      const input = document.createElement("input");
       // 设置 display为none会导致无法复制
       // input.style.display = "none";
       // 所以只能用其他方法隐藏
@@ -147,7 +145,7 @@ export default {
       // });
     },
     copy2() {
-      let url = 'https://beta.cloud.cocorobo.cn/#/classroomObservation';
+      let url = "https://beta.cloud.cocorobo.cn/#/classroomObservation";
       this.copyText2 = `链接提醒:${url}`;
       var clipboard = new Clipboard(".tag-read2");
       clipboard.on("success", e => {
@@ -191,25 +189,14 @@ export default {
     // }
   },
   watch: {
-    dialogVisibleShare(newValue, oldValue) {
-      console.log("newValue", newValue);
-      if (newValue) {
-        this.localDialogVisibleShare=newValue
+    tid() {
+      if (this.show) {
         this.setQr();
-        // this.getData();
-        // console.log(top.origin);
-        // this.origin = top.origin
       }
-    },
-		tid(){
-			if(this.dialogVisibleShare){
-				this.setQr();
-			}
-		}
+    }
   },
   mounted() {
     // console.log("this.info", this.info);
-
     // console.log(top.origin);
     // this.origin = top.origin
   }

+ 21 - 2
src/components/pages/classroomObservation/index.vue

@@ -584,8 +584,9 @@ export default {
             }
 
             if (i2.jsonData.CH && i2.jsonData.RT) {
-              tagHtml += `<div>
-								<img src=''>
+              tagHtml += `<div style="width:100vw;text-align:center;">
+								<img src="${await this.getImageSrcToBase64(require('../../../assets/icon/classroomObservation/rt-ch.png'))}" style="width:200px;height:200px;margin:auto;">
+								<div style="color:#1A7AD3;font-style:italic;font-weight:blob;">RT:${i2.jsonData.RT}CH:${i2.jsonData.CH}</div>
 								</div>`;
             }
 
@@ -679,6 +680,24 @@ export default {
         });
       });
     },
+		getImageSrcToBase64(src){
+			return new Promise((resolve,reject)=>{
+				const image = new Image();
+				image.src = src;
+				image.onload = () =>{
+					const canvas = document.createElement('canvas');
+					canvas.width = image.naturalWidth;
+					canvas.height = image.naturalHeight;
+					canvas.style.width = `${canvas.width / window.devicePixelRatio}px`
+					canvas.style.height = `${canvas.height / window.devicePixelRatio}px`
+
+					const context = canvas.getContext('2d');
+					context.drawImage(image, 0, 0);
+					const base64 = canvas.toDataURL('image/png');
+					resolve(base64);
+				}
+			})
+		},
     // 导出docx
     async generateDocx(name, html) {
       // 将html文件中需要用到的数据挂载到store上

+ 206 - 109
src/components/pages/components/exportDataDialog.vue

@@ -255,8 +255,8 @@ export default {
 
       // 分数工具柱状图开始
       columnData: [
-        { name: "分组工具", data: [] },
-        { name: "其他", data: [] }
+        { name: "个人", data: [] },
+        { name: "合作", data: [] }
       ],
       // 分数工具柱状图结束
 
@@ -286,8 +286,8 @@ export default {
       xk: [28, 31, 39, 66, , 68, 69, 70],
       // 师生互动工具list
       TeaStuInt: [7, 1, 52, 3, 48, 15, 16, 50, 57],
-      // 处理过的分组
-      TeaStuInt2: [1, 3, 5, 4, 10, 13, 15],
+      // 处理过的分组,师生互动数据
+      TeaStuInt2: [1, 3, 5, 4, 10, 11, 13, 15],
 
       subject: [], //课程分类
       AiAnalysisCon: "", //ai数据分析
@@ -334,56 +334,114 @@ export default {
   methods: {
     // ai评价分析
     async getAiAnalysisCon() {
-      let messages = `NOTICE
-      Role:你是一个学生学习行为分析专家,你要根据线上学习平台的数据分析,在学习状态、学习效果、学习动力、学习积极性等方面评估学生,评估后生成学生学习画像和学习建议。你可以自行扩充评估的角度,实现相对全面的评估。
-      Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
-      ATTENTION: Use '##' to SPLIT SECTIONS, not '#'. Output format carefully referenced "Format example".
-      Instruction: Based on the context, follow "Format example", write content.
-
-      #Context
-      ##要求
-      学生进行了线上平台和线下授课相结合的混合式学习,线上平台会记录学生的学习行为,并对数据进行简单的分析
-      只输出分析结果不要输出无关内容
+
+
+      // 师生在线互动次数
+      let tea = 0;
+      this.interactWork.forEach(e=>{
+        tea += e.length
+      })
+
+      let cla = 0
+      this.classSco.forEach(e=>{
+        cla += e *1
+      })
+
+      let cla2 = ''
+      this.classSco.forEach((e,index)=>{
+        cla2 += `${this.cState == 1?'阶段':'任务'}${index + 1}:${e}分,`
+      })
+
+      let repeatWork = this.newArrFn(this.data3);
+      // let repeatWorkCopy = [];
+      // 学生使用工具次数
+      // let repeatWorkCopy2 = [];
+
+      // this.stageList.forEach((e, index) => {
+      //   repeatWorkCopy[index] = [];
+      //   repeatWorkCopy2[index] = 0;
+      // });
+      // // 将作业进行阶段分类
+      // repeatWork.forEach(e => {
+      //   repeatWorkCopy[e.stage].push(e);
+      // });
+
+      // repeatWorkCopy.forEach((e,index)=>{
+      //   repeatWorkCopy2[index] = e.length
+      // })
+
+      // console.log('this.repeatWorkCopy2',this.repeatWorkCopy2);
       
-      ##风格
-      专业的
 
-      ##语气
-      陈述
+      let toolSy= ''
+      this.stageListPer.forEach((e,index)=>{
+        toolSy += `${this.cState == 1?'阶段':'任务'}${index + 1}:${e},`
+      })
 
-      ##受众
-      教师和教育管理者
+      let toolSy2= ''
+      this.classStageListPer.forEach((e,index)=>{
+        toolSy2 += `${this.cState == 1?'阶段':'任务'}${index + 1}:${e},`
+      })
+
+
+      let xieZuo = 0
+      // 协作占比
+      if (repeatWork.filter(item => item.type === 11).length == 0 || repeatWork.length == 0) {
+          xieZuo = 0
+      }else{
+          xieZuo = repeatWork.filter(item => item.type === 11).length / repeatWork.length
+      }
+
+      let duLi = 1 - xieZuo
+      
 
-      ##分析数据
-      学习成绩满分为5分
 
-      登录时长:${this.loginTime}
-      课程学习时长:${this.studyTime}
-      课程学习成绩:${this.star}
+      let int = []
+      this.interactWork.forEach((e,index)=>{
+        int[index] = e.length
+      })
+      let intnum = 0
+      int.forEach(e=>{
+        intnum += e*1
+      })
 
-      学生作业提交率:${this.stageListPer}
-      班级作业平均提交率:${this.classStageListPer}
+      // 任务的分
+      let renwu = ''
+      this.scoFoldLineData.forEach((e,index)=>{
+        renwu += `${this.cState == 1?'阶段':'任务'}${index + 1}:${e}分,`
+      })
 
-      师生互动次数:${this.interactWork}
-      班级师生互动平均次数:${this.classSco}
 
-      学生主动互动次数:${this.stuInterAllLike}
-      班级学生主动互动平均次数:${this.classSco}
 
-      学生主动被动次数:${this.bdStuInterAllLike}
-      班级学生主动被动平均次数:${this.classSco}
+      let messages = `Language: Please use the same language as the user requirement, if the user speaks Chinese, the specific text of your answer should also be in Chinese.
 
-      个人成绩:${this.scoFoldLineData}
-      班级平均成绩:${this.classSco}
+        ##上下文##
+        学生进行了线上平台和线下授课相结合的混合式学习,线上平台会记录学生的学习行为,并对数据进行简单的分析。
 
-      #输出要求#
-      根据分析数据中的数据,对学生在本次课程中的每个${
-        this.cState == 1 ? "阶段" : "任务"
-      }进行学生与班级平均数据进行对比分析
+        ##目标##
+        你是一个学生学习行为分析专家,你要根据线上学习平台的数据分析,在学习状态、学习效果、学习动力、学习积极性等方面评估学生,评估后生成学生学习画像和学习建议。你可以自行扩充评估的角度,实现相对全面的评估。
 
+        ##风格##
+        专业的
 
-      # Format example
-      该课程学习过程中,学生登录时长共1天2小时(班级前25%),学习时长共6小时(班级前25%),使用平台工具22次(班级前25%)。学生进行了科学、数学、美术学科的学习与实践。学生课程得分为4.4/5.0,高于班级平均得分。在课程的每个阶段,学生使用工具次数大多数高于或等于班级平均值,大多数任务能准时提交,有1次未交和2次迟交,师生在线互动次数全部高于或等于班级平均值,生生在线互动次数全部高于或等于班级平均值,协作完成的任务占总任务数量的36.6%,独立完成的任务占63.3%,学生阶段任务得分大多数高于或等于班级平均值。
+        ##语气##
+        陈述
+
+        ##受众##
+        教师和教育管理者
+
+        下面是线上平台的<<数据分析>>
+
+        
+
+        <<该课程学习过程中,学生登录时长共${this.loginTime},学习时长共${this.studyTime},使用平台工具${this.data3.length}次。
+        学生进行了${this.subject.join(',')}的学习与实践。
+        学生课程得分为${this.star}/5.0。
+        在课程的每个阶段,学生作业提交率${toolSy},班级平均值 ${toolSy2},
+        师生在线互动次数${intnum},班级平均值 ${cla},
+        生生在线互动次数${this.bdStuInterAllLike.length + this.stuInterAllLike.length},班级平均值 ${cla},
+        协作完成的任务占总任务数量的${xieZuo},独立完成的任务占${duLi},
+        学生阶段任务得分${renwu},班级平均值${cla2}。>>
       `;
       // this.aiGet2(msg)
       let params = {
@@ -459,10 +517,12 @@ export default {
     async downPdf() {
       this.loading = true;
       this.tableData = this.multipleSelection;
+
       if (!this.tableData.length) {
         this.loading = false;
         return this.$message.info("请选择数据后,再进行导出");
       }
+
       if (this.tableData.length == 1) {
         this.uid2 = this.tableData[0].userid;
         this.worksDialogCon2 = this.tableData[0];
@@ -471,51 +531,52 @@ export default {
           // console.log('res.data[10]',res.data[10]);
           let Asd = this.data10[0].jsonTxt;
           this.AiAnalysisCon = JSON.parse(Asd).comprehensive;
+          this.loading = false;
         } else {
           await this.getAiAnalysisCon();
+          this.loading = false;
         }
         this.loading = false;
 
-        await this.getPdf();
+        setTimeout(() => {
+          this.getPdf();
+        }, 500);
       } else {
         this.circulatePdf();
       }
     },
     // 下载pdf文件
-    async getPdf() {
+    getPdf() {
       let domHeight = this.$refs.reportPdf.offsetHeight;
       // console.log('this.$refs.reportPdf',this.$refs.reportPdf.offsetHeight);
       let maxHeight = 64257;
-      return new Promise((resolve, reject) => {
-        html2canvas(this.$refs.reportPdf, {
-          useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
-          scale: maxHeight / domHeight > 1 ? 1 : maxHeight / domHeight
+      html2canvas(this.$refs.reportPdf, {
+        useCORS: true, // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
+        scale: maxHeight / domHeight > 1 ? 1 : maxHeight / domHeight
+      })
+        .then(canvas => {
+          const contentWidth = canvas.width;
+          const contentHeight = canvas.height;
+
+          var pageData = canvas.toDataURL("image/jpeg", 1.0);
+
+          var pdf = new jspdf("", "pt", [contentWidth, contentHeight]);
+
+          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
+          //当内容未超过pdf一页显示的范围,无需分页
+          // if (leftHeight < pageHeight) {
+          pdf.addImage(pageData, "JPEG", 0, 0, contentWidth, contentHeight);
+
+          pdf.save(
+            this.worksDialogCon2.course +
+              "-学生成长报告-" +
+              this.worksDialogCon2.sName +
+              ".pdf"
+          );
         })
-          .then(canvas => {
-            const contentWidth = canvas.width;
-            const contentHeight = canvas.height;
-
-            var pageData = canvas.toDataURL("image/jpeg", 1.0);
-
-            var pdf = new jspdf("", "pt", [contentWidth, contentHeight]);
-
-            //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
-            //当内容未超过pdf一页显示的范围,无需分页
-            // if (leftHeight < pageHeight) {
-            pdf.addImage(pageData, "JPEG", 0, 0, contentWidth, contentHeight);
-
-            pdf.save(
-              this.worksDialogCon2.course +
-                "-学生成长报告-" +
-                this.worksDialogCon2.sName +
-                ".pdf"
-            );
-            return resolve();
-          })
-          .catch(err => {
-            console.log(err);
-          });
-      });
+        .catch(err => {
+          console.log(err);
+        });
     },
     // 获取所有作业然后一键打包压缩包
     getWorks1() {
@@ -651,14 +712,17 @@ export default {
             });
 
             // 0 课程信息
-            // 1获取登录时长
-            // 3获取学习时长
-            //  4获取学生提交作业
-            //  5获取单个学生作业分数
-            //  6获取教师评价作业
-            //  7获取所有学生提交作业
-            //  8学生点赞评论次数
-            //  9学生被点赞评论次数
+            // 1获取登录时长】
+            // 2获取登录时长
+
+            //  3获取学生提交作业
+            //  4获取单个学生作业分数
+            //  5获取教师评价作业
+            //  6获取所有学生提交作业
+            //  7学生点赞评论次数
+            //  8学生被点赞评论次数
+            //  8学科
+            // 9是否上传过学情分析
             let oneTime = 0;
             res.data[1].forEach(e => {
               oneTime += e.text * 1;
@@ -1346,7 +1410,7 @@ export default {
 
       const option = {
         title: {
-          text: "分组工具占比",
+          text: "完成任务方式占比",
           left: "left",
           textStyle: {
             color: "rgba(140, 140, 140, 1)", // 标题颜色
@@ -1355,12 +1419,22 @@ export default {
           }
         },
         legend: {
-            data: this.columnData.map(item => item.name),  // 设置图例的数据为系列的名称
-            orient: "vertical", // 设置为垂直排列
-            right: 10
+          data: this.columnData.map(item => item.name), // 设置图例的数据为系列的名称
+          orient: "vertical", // 设置为垂直排列
+          right: 10
         },
         tooltip: {
-          trigger: "axis"
+          trigger: "axis",
+          formatter: function(params) {
+            var res = "";
+            for (var i = 0, l = params.length; i < l; i++) {
+              if (i == 0) {
+                res += params[i].name + "<br/>";
+              }
+              res += params[i].seriesName + ": " + params[i].value + "%<br/>";
+            }
+            return res;
+          }
           // axisPointer: {
           //   type: "shadow"
           // },
@@ -1372,9 +1446,10 @@ export default {
         },
         yAxis: {
           type: "value",
-          // axisLabel: {
-          //   formatter: "{value}%"
-          // },
+          axisLabel: {
+            formatter: "{value}%"
+          },
+          max: 100
         },
         series: this.columnData.map(item => ({
           name: item.name,
@@ -1383,7 +1458,7 @@ export default {
           barWidth: "60%",
           label: {
             show: true,
-            formatter: params => Math.round(params.value * 1000) / 10 + "%"
+            formatter: params => Math.round(params.value) + "%"
           },
           data: item.data
         }))
@@ -1623,7 +1698,17 @@ export default {
           }
         },
         tooltip: {
-          trigger: "axis"
+          trigger: "axis",
+          formatter: function(params) {
+            var res = "";
+            for (var i = 0, l = params.length; i < l; i++) {
+              if (i == 0) {
+                res += params[i].name + "<br/>";
+              }
+              res += params[i].seriesName + ": " + params[i].value + "%<br/>";
+            }
+            return res;
+          }
         },
         yAxis: {
           type: "value",
@@ -1664,31 +1749,43 @@ export default {
     },
     // 计算分组工具使用比例
     getColumnData() {
+      console.log("interactWork", this.data3);
+      let repeatWork = this.newArrFn(this.data3);
+
       let columnDataCopy = [];
       let columnDataCopyTwo = [];
-      this.toolPercentage.forEach((e, index) => {
-        columnDataCopy[index] = 0;
-        columnDataCopyTwo[index] = 0;
-        columnDataCopy[index] = e.filter(item => item === 49).length;
-        columnDataCopyTwo[index] = e.filter(item => item != 49).length;
-
-        if (columnDataCopy[index]) {
-          columnDataCopy[index] = (columnDataCopy[index] / e.length).toFixed(
-            2
-          );
+
+      // 作业分类
+      let repeatWorkCopy = [];
+
+      this.stageList.forEach((e, index) => {
+        repeatWorkCopy[index] = [];
+      });
+
+      // 将作业进行阶段分类
+      repeatWork.forEach(e => {
+        repeatWorkCopy[e.stage].push(e);
+      });
+
+      repeatWorkCopy.forEach((e, index) => {
+        if (e && e.length) {
+          columnDataCopy[index] =
+            e.filter(item => item.type === 11).length / e.length;
         } else {
           columnDataCopy[index] = 0;
         }
-        if (columnDataCopyTwo[index]) {
-          columnDataCopyTwo[index] = (columnDataCopyTwo[index] / e.length).toFixed(
-            2
-          );
-        } else {
-          columnDataCopyTwo[index] = 0;
-        }
+        columnDataCopyTwo[index] = 1 - columnDataCopy[index];
+      });
+
+      columnDataCopy = columnDataCopy.map(function(item, index, arr) {
+        return item * 100;
       });
-      this.columnData[0].data = columnDataCopy;
-      this.columnData[1].data = columnDataCopyTwo;
+      columnDataCopyTwo = columnDataCopyTwo.map(function(item, index, arr) {
+        return item * 100;
+      });
+
+      this.columnData[0].data = columnDataCopyTwo;
+      this.columnData[1].data = columnDataCopy;
     },
     // 计算时长
     secondsToDhms(seconds) {

+ 3 - 3
src/components/pages/easy/addCourse.vue

@@ -5127,11 +5127,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 3 - 3
src/components/pages/newCourse/addCourse.vue

@@ -7979,11 +7979,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 4 - 4
src/components/pages/student/addCourse.vue

@@ -5493,11 +5493,11 @@ export default {
           }
         }
       }
-      let params = {
-        uid: array.join(","),
-      };
+      let params = [{
+        uid: _user.join(","),
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 4 - 4
src/components/pages/student/courseProgress.vue

@@ -153,12 +153,12 @@ export default {
             if (this.checkboxList3.indexOf(this.courseUserid) == -1) {
                 this.checkboxList3.push(this.courseUserid)
             }
-            let params = {
+            let params = [{
                 uid: this.checkboxList3.join(","),
-            };
+            }];
             this.ajax
-                .get(
-                    this.$store.state.api + "getAllUserById",
+                .post(
+                    this.$store.state.api + "getAllUserByIdP",
                     params
                 )
                 .then((res) => {

+ 4 - 4
src/components/pages/studio/addCourse.vue

@@ -6536,11 +6536,11 @@ export default {
           }
         }
       }
-      let params = {
-        uid: array.join(","),
-      };
+      let params = [{
+        uid: _user.join(","),
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 4 - 4
src/components/pages/studio/courseProgress.vue

@@ -153,12 +153,12 @@ export default {
             if (this.checkboxList3.indexOf(this.courseUserid) == -1) {
                 this.checkboxList3.push(this.courseUserid)
             }
-            let params = {
+            let params = [{
                 uid: this.checkboxList3.join(","),
-            };
+            }];
             this.ajax
-                .get(
-                    this.$store.state.api + "getAllUserById",
+                .post(
+                    this.$store.state.api + "getAllUserByIdP",
                     params
                 )
                 .then((res) => {

+ 3 - 3
src/components/pages/synergyCourse/addCourse.vue

@@ -3203,11 +3203,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 3 - 3
src/components/pages/synergyCourse/group/group.vue

@@ -507,11 +507,11 @@ export default {
             if (_user.indexOf(this.courseDetail.userid) !== -1) {
                 _user.splice(_user.indexOf(this.courseDetail.userid), 1);
             }
-            let params = {
+            let params = [{
                 uid: _user.join(","),
-            };
+            }];
             this.ajax
-                .get(this.$store.state.api + "getAllUserById", params)
+                .post(this.$store.state.api + "getAllUserByIdP", params)
                 .then((res) => {
                     this.loading = false
                     if (res.data && res.data[0].length) {

+ 3 - 3
src/components/pages/task/addCourse.vue

@@ -8689,11 +8689,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 3 - 3
src/components/pages/trainCourse/addCourse.vue

@@ -4478,11 +4478,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

+ 3 - 3
src/components/pages/trainCourse/easy/addCourse.vue

@@ -5092,11 +5092,11 @@ export default {
       if (_user.indexOf(this.courseUserid) == -1) {
         _user.push(this.courseUserid);
       }
-      let params = {
+      let params = [{
         uid: _user.join(","),
-      };
+      }];
       this.ajax
-        .get(this.$store.state.api + "getAllUserById", params)
+        .post(this.$store.state.api + "getAllUserByIdP", params)
         .then((res) => {
           let teacherJuri = res.data[0];
           this.ManAarray = teacherJuri;

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

@@ -466,7 +466,7 @@
       :append-to-body="true"
     >
       <div slot="title" class="header-title">
-        <div style="color: #fff">导出作业集</div>
+        <div style="color: #fff">{{ this.digNum==2 ?'查看':'导出' }}报告</div>
       </div>
       <exportDataDialog  :key="exportW" :digNum="digNum" :oid="oid" :multipleSelection="multipleSelection" :worksDialogCon="worksDialogCon" :worksDialog.sync="worksDialog" :cid="checkCourse"></exportDataDialog>
     </el-dialog>

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini