ソースを参照

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

Luckydo01 1 年間 前
コミット
767830f4d1
46 ファイル変更2838 行追加20036 行削除
  1. 1 1
      dist/index.html
  2. 0 0
      dist/static/css/app.5084b426060481646e5988ec5efdba39.css
  3. 0 0
      dist/static/css/app.5084b426060481646e5988ec5efdba39.css.map
  4. 0 0
      dist/static/js/app.06b30b2ce84ecc895b51.js
  5. 0 0
      dist/static/js/app.06b30b2ce84ecc895b51.js.map
  6. 0 0
      dist/static/js/manifest.571c38d63f24b1ae9e16.js.map
  7. 0 0
      dist/static/js/vendor.d5f0d79dbb0d92c052d4.js
  8. 0 0
      dist/static/js/vendor.d5f0d79dbb0d92c052d4.js.map
  9. 0 18827
      package-lock.json
  10. 1 0
      package.json
  11. BIN
      src/assets/icon/ppt/model1-1.png
  12. BIN
      src/assets/icon/ppt/model1-2.png
  13. BIN
      src/assets/icon/ppt/model2-1.png
  14. BIN
      src/assets/icon/ppt/model2-2.png
  15. BIN
      src/assets/icon/ppt/model3-1.png
  16. BIN
      src/assets/icon/ppt/model3-2.png
  17. BIN
      src/assets/icon/ppt/model4-1.png
  18. BIN
      src/assets/icon/ppt/model4-2.png
  19. BIN
      src/assets/icon/ppt/model5-1.png
  20. BIN
      src/assets/icon/ppt/model5-2.png
  21. 43 39
      src/components/pages/aiAddCourse/addCourse.vue
  22. 1 2
      src/components/pages/aiAddCourse/addCourse3.vue
  23. 151 50
      src/components/pages/aiAddCourse/aiCreateDialog.vue
  24. 1 1
      src/components/pages/aiAddCourse/aiCreateVideoDialog.vue
  25. 14 2
      src/components/pages/classroomObservation/components/analysis.vue
  26. 10 9
      src/components/pages/classroomObservation/components/analysisItem.vue
  27. 66 7
      src/components/pages/classroomObservation/components/analysisTemplateDialog.vue
  28. 12 5
      src/components/pages/classroomObservation/components/baseMessage.vue
  29. 291 16
      src/components/pages/classroomObservation/components/chatArea.vue
  30. 127 95
      src/components/pages/classroomObservation/components/messageArea.vue
  31. 23 7
      src/components/pages/classroomObservation/components/saveTemplateDialog.vue
  32. 215 77
      src/components/pages/classroomObservation/index.vue
  33. 49 1
      src/components/pages/components/studentReport.vue
  34. 6 1
      src/components/pages/easy/addCourse.vue
  35. 6 1
      src/components/pages/newCourse/addCourse.vue
  36. 6 1
      src/components/pages/student/addCourse.vue
  37. 6 1
      src/components/pages/synergyCourse/addCourse.vue
  38. 6 1
      src/components/pages/task/addCourse.vue
  39. 24 3
      src/components/pages/test/check/index.vue
  40. 1 1
      src/components/pages/test/examine/conpoments/personPage.vue
  41. 1032 563
      src/components/pages/test/examine/conpoments/targetPage.vue
  42. 4 3
      src/components/pages/test/examine/index.vue
  43. 665 312
      src/components/pages/testPerson/examine/index.vue
  44. 26 8
      src/components/pages/testPerson/test/test.vue
  45. 6 1
      src/components/pages/trainCourse/addCourse.vue
  46. 45 1
      src/components/pages/works.vue

+ 1 - 1
dist/index.html

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

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/css/app.5084b426060481646e5988ec5efdba39.css


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/css/app.5084b426060481646e5988ec5efdba39.css.map


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/app.06b30b2ce84ecc895b51.js


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/app.06b30b2ce84ecc895b51.js.map


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/manifest.571c38d63f24b1ae9e16.js.map


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/vendor.d5f0d79dbb0d92c052d4.js


ファイルの差分が大きいため隠しています
+ 0 - 0
dist/static/js/vendor.d5f0d79dbb0d92c052d4.js.map


ファイルの差分が大きいため隠しています
+ 0 - 18827
package-lock.json


+ 1 - 0
package.json

@@ -36,6 +36,7 @@
     "lamejs": "^1.2.1",
     "language-hk-loader": "^1.0.1",
     "markdown-it": "^14.1.0",
+    "opencc-js": "^1.0.5",
     "pdfjs-dist": "^2.5.207",
     "pptxgenjs": "^3.12.0",
     "qrcodejs2": "^0.0.2",

BIN
src/assets/icon/ppt/model1-1.png


BIN
src/assets/icon/ppt/model1-2.png


BIN
src/assets/icon/ppt/model2-1.png


BIN
src/assets/icon/ppt/model2-2.png


BIN
src/assets/icon/ppt/model3-1.png


BIN
src/assets/icon/ppt/model3-2.png


BIN
src/assets/icon/ppt/model4-1.png


BIN
src/assets/icon/ppt/model4-2.png


BIN
src/assets/icon/ppt/model5-1.png


BIN
src/assets/icon/ppt/model5-2.png


+ 43 - 39
src/components/pages/aiAddCourse/addCourse.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="pb_content" style="background: #f0f2f5" v-loading="loading">
+  <div class="pb_content" style="background: #f0f2f5" v-loading="loading" element-loading-text="小可正在努力生成中,请稍等...">
     <div class="pb_content_body" style="position: relative; margin: 0">
       <div class="right" :style="{width:istemplate == 1 ? 'calc(100% - 300px)' : '100%'}">
         <div class="courseTop">
@@ -358,7 +358,7 @@
                 </div>
               </div>
             </div>
-            <div class="whiteBg" style="background: #fff; margin: 0 0 10px;padding: 0 0 15px;" v-loading="textLoading">
+            <div class="whiteBg" style="background: #fff; margin: 0 0 10px;padding: 0 0 15px;" v-loading="textLoading" element-loading-text="小可正在努力生成中,请稍等...">
               <div class="whiteBg" style="border-radius: 0; margin-top: 15px">
                 <div class="c_info_title">
                   课程简要描述
@@ -407,7 +407,7 @@
                     <div class="add_info_box" style="margin: 0 0 0 auto">
                       <button class="c_pub_button_add pub_btn_add_img" @click="addImg($event)">
                         上传补充资料
-                        <input type="file" accept=".docx,.doc,.ppt,.pptx,.md,.txt" style="display: none" v-if="inputShow" @change="
+                        <input type="file" accept=".docx,.doc,.ppt,.pptx,.md,.txt,.pdf" style="display: none" v-if="inputShow" @change="
                           beforeUploadInfo2(
                             $event,
                             13
@@ -667,7 +667,7 @@
                       <input type="text" placeholder="输入任务名称" class="binfo_input" style="border-radius: 4px"
                         v-model="item.task" />
                     </div>
-                    <div class="outline_detail" v-loading="taskDetailLoading.indexOf('task-' + index) !== -1">
+                    <div class="outline_detail" v-loading="taskDetailLoading.indexOf('task-' + index) !== -1" element-loading-text="小可正在努力生成中,请稍等...">
                       <textarea v-autoHeight="100" rows="4" class="binfo_input binfo_textarea" cols
                         placeholder="请输入任务描述" v-model="item.taskDetail2"></textarea>
                       <div class="op_box">
@@ -689,7 +689,7 @@
                   概念群
                 </div>
                 <div class="task_outline">
-                  <div class="outline_detail" v-loading="cpoteLoading.cpote1">
+                  <div class="outline_detail" v-loading="cpoteLoading.cpote1" element-loading-text="小可正在努力生成中,请稍等...">
                     <textarea v-autoHeight="100" rows="4" class="binfo_input binfo_textarea" cols placeholder="请输入概念群"
                       v-model="cpote.cpote1" v-if="cpote.cpote1s"></textarea>
                     <div class="markBox vditor-reset" v-html="MarkdownT(cpote.cpote1)" v-else></div>
@@ -714,7 +714,7 @@
                   问题链
                 </div>
                 <div class="task_outline">
-                  <div class="outline_detail" v-loading="cpoteLoading.cpote2">
+                  <div class="outline_detail" v-loading="cpoteLoading.cpote2" element-loading-text="小可正在努力生成中,请稍等...">
                     <textarea v-autoHeight="100" rows="4" class="binfo_input binfo_textarea" cols placeholder="请输入问题链"
                       v-model="cpote.cpote2" v-if="cpote.cpote2s"></textarea>
                     <div class="markBox vditor-reset" v-html="MarkdownT(cpote.cpote2)" v-else></div>
@@ -739,7 +739,7 @@
                   目标层
                 </div>
                 <div class="task_outline">
-                  <div class="outline_detail" v-loading="cpoteLoading.cpote3">
+                  <div class="outline_detail" v-loading="cpoteLoading.cpote3" element-loading-text="小可正在努力生成中,请稍等...">
                     <textarea v-autoHeight="100" rows="4" class="binfo_input binfo_textarea" cols placeholder="请输入目标层"
                       v-model="cpote.cpote3" v-if="cpote.cpote3s"></textarea>
                     <div class="markBox vditor-reset" v-html="MarkdownT(cpote.cpote3)" v-else></div>
@@ -764,7 +764,7 @@
                   任务簇
                 </div>
                 <div class="task_outline">
-                  <div class="outline_detail" v-loading="cpoteLoading.cpote4">
+                  <div class="outline_detail" v-loading="cpoteLoading.cpote4" element-loading-text="小可正在努力生成中,请稍等...">
                     <textarea v-autoHeight="100" rows="4" class="binfo_input binfo_textarea" cols placeholder="请输入任务簇"
                       v-model="cpote.cpote4" v-if="cpote.cpote4s"></textarea>
                       <div class="markBox vditor-reset" v-html="MarkdownT(cpote.cpote4)" v-else></div>
@@ -801,7 +801,7 @@
                       <input type="text" placeholder="输入任务名称" class="binfo_input" style="border-radius: 4px"
                         v-model="item.task" />
                     </div>
-                    <div class="outline_detail" v-loading="taskDetailLoading5.indexOf('task-' + index) !== -1">
+                    <div class="outline_detail" v-loading="taskDetailLoading5.indexOf('task-' + index) !== -1" element-loading-text="小可正在努力生成中,请稍等...">
                       <textarea v-autoHeight="100" rows="4" class="binfo_input binfo_textarea" cols placeholder="请输入教案"
                         v-model="item.taskDetail3" v-if="item.isTask3"></textarea>
                       <div class="markBox vditor-reset" v-html="MarkdownT(item.taskDetail3)" v-else></div>
@@ -1659,7 +1659,7 @@
                               easyArray.indexOf(unitJson[unitIndex].easy) ==
                               -1
                             " style="margin-top: 20px" class="op_task_box"
-                              v-loading="taskDetailLoading2.indexOf('task-' + itemTaskIndex) !== -1">
+                              v-loading="taskDetailLoading2.indexOf('task-' + itemTaskIndex) !== -1" element-loading-text="小可正在努力生成中,请稍等...">
                               <!-- <editor-bar class="addEditor" style="margin: 0" placeholder="请输入任务描述" v-model="unitJson[unitIndex].chapterInfo[0].taskJson[
                                   itemTaskIndex
                                 ].taskDetail
@@ -3332,7 +3332,7 @@
                               </div>
                               <!-- v-show="!itemTool.isFold3" -->
                               <div class="op_tool_box"
-                                v-loading="taskDetailLoading3.indexOf('task-' + itemTaskIndex + toolIndex) !== -1">
+                                v-loading="taskDetailLoading3.indexOf('task-' + itemTaskIndex + toolIndex) !== -1" element-loading-text="小可正在努力生成中,请稍等...">
                                 <textarea rows="2" v-autoHeight="70" type="text" placeholder="添加工具描述"
                                   class="binfo_input" style="
                                     margin: 0 0 20px 0;
@@ -3632,7 +3632,7 @@
                           </div>
                         </div>
                         <div class="elist_css" v-if="!(unitJson[unitJson.length - 1].easy == 4)"
-                          v-loading="taskDetailLoading4.indexOf('task-' + itemTaskIndex) !== -1">
+                          v-loading="taskDetailLoading4.indexOf('task-' + itemTaskIndex) !== -1" element-loading-text="小可正在努力生成中,请稍等...">
                           <div class="elist_title">
                             <div style="
                                 display: flex;
@@ -5282,6 +5282,12 @@ import { v4 as uuidv4 } from "uuid";
 import MarkdownIt from "markdown-it";
 import aiCreateDialog from './aiCreateDialog.vue'
 import aiCreateVideoDialog from './aiCreateVideoDialog.vue'
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
+
 
 export default {
   components: {
@@ -5543,7 +5549,7 @@ export default {
       imageloading2: false,
       searchImageValue: "",
       ppage: 1,
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
       oldIndex: 0,
       dragType: "",
       oldUnitIndex: 0,
@@ -7610,7 +7616,7 @@ export default {
 
       var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
       var _this = this;
-      var xianObj = ['DOCX','DOC','PPT','PPTX','MD','TXT']
+      var xianObj = ['DOCX','DOC','PPT','PPTX','MD','TXT','PDF']
       if (
         xianObj.indexOf(
             file.name
@@ -7618,7 +7624,7 @@ export default {
             [file.name.split(".").length - 1].toLocaleUpperCase()
           ) == -1
         ) {
-        this.$message.error("请上传.doc,.docx,.ppt,.pptx,.md,.txt文件!");
+        this.$message.error("请上传.doc,.docx,.ppt,.pptx,.md,.txt,.pdf文件!");
         this.inputShow = true;
         // var a = _this.$refs.upload1.uploadFiles;
         // a.splice(a.length - 1, a.length);
@@ -11038,7 +11044,7 @@ export default {
           .then((res) => {
             let _unitJson = JSON.parse(res.data[0][0].chapters);
             let fileInfo = []
-            var xianObj = ['DOCX','DOC','PPT','PPTX','MD','TXT']
+            var xianObj = ['DOCX','DOC','PPT','PPTX','MD','TXT','PDF']
 
             for(var i = 0; i < _unitJson.length; i++){
               let tasks = _unitJson[i].chapterInfo[0].taskJson
@@ -13205,8 +13211,7 @@ Instruction: Based on the context, follow "Format example", write content.
 
 # Context
 ## 要求 
-${msg} 以及##参考资料,
-然后根据Format example的要求返回要以数组的格式
+${msg} 以及##参考资料
 
 ## 参考资料
 课程名字:${this.courseName}
@@ -13245,7 +13250,7 @@ Instruction: Based on the context, follow "Format example", write content.
 
 # Context
 ## 要求
-${msg} 以及#教学任务教案 内容要求参考#格式要求, 然后根据Format example的要求返回要以数组的格式
+${msg} 以及#教学任务教案 内容要求参考#格式要求
 
 ## 教学任务教案
 ${_text}
@@ -13253,15 +13258,14 @@ ${_text}
 ${this.templateid == "4480d65a-1e48-11ef-bee5-005056b86db5" ? '#目标层\n'+this.cpote.cpote3.replaceAll('#','').replaceAll('*','').replaceAll('-','').replaceAll('\n','')+'\n\n#任务簇\n'+this.cpote.cpote4.replaceAll('#','').replaceAll('*','').replaceAll('-','').replaceAll('\n','') : ''}
 
 ## 格式要求
-任务名:
-任务描述:该描述是教师给与学生的指示(用于指导学生如何进行每个教学活动),对应到学生活动,你应该用友好,但是又清晰明确的口吻来撰写。
+任务数量:${this.teacherText.length}个
+任务描述:用老师的身份以友好,但是又清晰明确的口吻来撰写该描述,该描述教师给与学生的指示(用于指导学生如何进行每个教学活动),对应到学生活动
 评价标准:至少3条评价标准,这个评价是教师用来评价学生表现的,需要包含评价维度,以及该维度中教师期待学生的表现,句式为学生应该能....
-平台工具:
-工具名:从工具列表中选择0~2个工具用于学生阶段性成果提交,工具列表:[电子白板,文档,思维导图,表格,作业提交,问答,选择题],仅在这几个工具里选择
-工具指引:以友好,明确的口吻告诉学生该如何使用该工具
+工具名:从工具列表中选择0~2个工具用于学生阶段性成果提交:工具列表:电子白板,文档,思维导图,表格,作业提交,问答,选择题,只在这几个工具里选
+工具描述:用同学的方式以友好亲切,明确的口吻告诉学生该如何使用该工具
 
 # Format example
-[{"detail":"面向学生的任务描述","elist":[{"value":"评价名字1","detail":"评价维度1","score":5},{"value":"评价名字2","detail":"评价维度2","score":5},{"value":"评价名字3","detail":"评价维度3","score":5}],"toolChoose":[{"tool":"电子白板","detail":"工具描述"},{"tool":"思维大图","detail":"工具描述"}]},{"detail":"面向学生的任务描述","elist":[{"value":"评价名字1","detail":"评价维度1","score":5},{"value":"评价名字2","detail":"评价维度2","score":5},{"value":"评价名字3","detail":"评价维度3","score":5}],"toolChoose":[]},{"detail":"面向学生的任务描述","elist":[{"value":"评价名字1","detail":"评价维度1","score":5},{"value":"评价名字2","detail":"评价维度2","score":5},{"value":"评价名字3","detail":"评价维度3","score":5}],"toolChoose":[{"tool":"文档","detail":"工具描述"}]}]`
+[{"detail":"面向学生的任务描述","elist":[{"value":"评价名字1","detail":"评价维度1","score":5},{"value":"评价名字2","detail":"评价维度2","score":5},{"value":"评价名字3","detail":"评价维度3","score":5}],"toolChoose":[{"tool":"工具名","detail":"工具描述"},{"tool":"工具名","detail":"工具描述"}]},{"detail":"面向学生的任务描述","elist":[{"value":"评价名字1","detail":"评价维度1","score":5},{"value":"评价名字2","detail":"评价维度2","score":5},{"value":"评价名字3","detail":"评价维度3","score":5}],"toolChoose":[]},{"detail":"面向学生的任务描述","elist":[{"value":"评价名字1","detail":"评价维度1","score":5},{"value":"评价名字2","detail":"评价维度2","score":5},{"value":"评价名字3","detail":"评价维度3","score":5}],"toolChoose":[{"tool":"工具名","detail":"工具描述"}]}]`
         this.loading = true
         this.aiGet3(message, this.aiCallBack)
       } else if (this.aitype == "aiDetail1") {
@@ -13297,7 +13301,7 @@ Instruction: Based on the context, follow "Format example", write content.
 
 # Context
 ## 要求
-${msg} 以及${this.templateid != "4480d65a-1e48-11ef-bee5-005056b86db5" ? '##任务大纲' : '##目标层,##任务簇'}, 然后根据Format example的要求返回要以数组的格式
+${msg} 以及${this.templateid != "4480d65a-1e48-11ef-bee5-005056b86db5" ? '##任务大纲' : '##目标层,##任务簇'}
 
 ${this.templateid != "4480d65a-1e48-11ef-bee5-005056b86db5" ? '## 任务大纲\n'+_text : ''}
 
@@ -13451,7 +13455,7 @@ ${message} 以及##参考资料 以文本格式输出项目概况,驱动性问
         // if (data.choices && data.choices.length && data.choices[0].message) {
         //   _this.courseText = data.choices[0].message.content
         // }
-        if (response.data.FunctionResponse.result == "发送成功") {
+        if (converter(response.data.FunctionResponse.result) == converter("发送成功")) {
         } else {
           this.$message.warning(response.data.FunctionResponse.result);
         }
@@ -13880,18 +13884,18 @@ ${message} 以及##参考资料 以文本格式输出项目概况,驱动性问
               if (_task.toolChoose.length) {
                 for (var j = 0; j < _task.toolChoose.length; j++) {
                   let _json = {
-                      tool: toolsJson[_task.toolChoose[j].tool] ? [toolsJson[_task.toolChoose[j].tool].tool] : [],
+                      tool: toolsJson[_task.toolChoose[j].tool] ? [toolsJson[_task.toolChoose[j].tool].tool] : [16],
                       toolDetail: _task.toolChoose[j].detail,
-                      toolType: toolsJson[_task.toolChoose[j].tool] ? toolsJson[_task.toolChoose[j].tool].type : 0,
+                      toolType: toolsJson[_task.toolChoose[j].tool] ? toolsJson[_task.toolChoose[j].tool].type : 2,
                       askCount: 1,
                       askTitle: "",
                       askJson: [{ askstitle: "", askItem: 1, checkList: [] }],
                     }
                   
-                  if(_task.toolChoose[j].tool == '问答'){
+                  if(converter(_task.toolChoose[j].tool) == converter('问答')){
                     let answerQ = await _this.aiCreateQuestion(15, i)
                     _json.answerQ = answerQ.answerQ 
-                  }else if(_task.toolChoose[j].tool == '选择题'){
+                  }else if(converter(_task.toolChoose[j].tool) == converter('选择题')){
                     let testJson = await _this.aiCreateQuestion(45, i)
                     _json.testJson = {"testCount":testJson.length,"testTitle":"","testJson":testJson} 
                   }
@@ -13975,7 +13979,7 @@ ${mclass.length ? '面向年级:' + mclass.join(",") : ''}
 ## 教案
 ${this.teacherText[task].detail.replaceAll('#','').replaceAll('*','').replaceAll('-','').replaceAll('\n','')}
 
-# formate example
+# Format example
 {answerQ:"问题"}
 `
         }else if(type == 45){
@@ -13987,7 +13991,7 @@ Instruction: Based on the context, follow "Format example", write content.
 
 # Context
 ## 任务
-根据本任务的#教案,在考虑到面向学生年级(<面向年级>)以及相对应的学科(<课程学科>)的基础上生成5道单选题。题目的意义是测试学生对本教学任务知识点的掌握情况,你的题目应当是有意义的。然后根据Format example的要求返回要以数组的格式
+根据本任务的#教案,在考虑到面向学生年级(<面向年级>)以及相对应的学科(<课程学科>)的基础上生成5道单选题。题目的意义是测试学生对本教学任务知识点的掌握情况,你的题目应当是有意义的。
 
 ## 限制
 - 生成题目禁止重复。
@@ -14004,7 +14008,7 @@ ${mclass.length ? '面向年级:' + mclass.join(",") : ''}
 ## 教案
 ${this.teacherText[task].detail.replaceAll('#','').replaceAll('*','').replaceAll('-','').replaceAll('\n','')}
 
-# formate example
+# Format example
 [{"teststitle":"题目内容","testItem":4,"checkList":["选项1","选项2","选项3","选项4"],"timuList":[],"answer":0,"type":"1"},{"teststitle":"题目内容","testItem":"选项数量(数字)","checkList":["选项1","选项2","选项3","选项4"],"timuList":[],"answer":"答案(数字)","type":"1"}]
 `
         }
@@ -14389,7 +14393,7 @@ ${msg} 及#教学任务描述 以文本格式输出任务设计和评价标准
         //   _this.$forceUpdate()
         // }
 
-        if (response.data.FunctionResponse.result == "发送成功") {
+        if (converter(response.data.FunctionResponse.result) == converter("发送成功")) {
         } else {
           this.$message.warning(response.data.FunctionResponse.result);
         }
@@ -14527,7 +14531,7 @@ ${msg}
         //   _this.$forceUpdate()
         // }
         // _this.taskDetailLoading2.splice(_this.taskDetailLoading.indexOf(_tindex), 1)
-        if (response.data.FunctionResponse.result == "发送成功") {
+        if (converter(response.data.FunctionResponse.result) == converter("发送成功")) {
         } else {
           this.$message.warning(response.data.FunctionResponse.result);
         }
@@ -14665,7 +14669,7 @@ ${msg} 输出格式和内容要求参考#格式与要求
         //   _this.$forceUpdate()
         // }
         // _this.taskDetailLoading3.splice(_this.taskDetailLoading3.indexOf(_tindex), 1)
-        if (response.data.FunctionResponse.result == "发送成功") {
+        if (converter(response.data.FunctionResponse.result) == converter("发送成功")) {
         } else {
           this.$message.warning(response.data.FunctionResponse.result);
         }
@@ -14949,7 +14953,7 @@ ${_text2}`
         //   _this.$forceUpdate()
         // }
         // _this.taskDetailLoading2.splice(_this.taskDetailLoading.indexOf(_tindex), 1)
-        if (response.data.FunctionResponse.result == "发送成功") {
+        if (converter(response.data.FunctionResponse.result) == converter("发送成功")) {
         } else {
           this.$message.warning(response.data.FunctionResponse.result);
         }
@@ -15109,7 +15113,7 @@ ${this.aitype == 'aiCpote4' ? '## 目标层\n'+this.cpote['cpote3'] : ''}`
         //   _this.$forceUpdate()
         // }
         // _this.taskDetailLoading2.splice(_this.taskDetailLoading.indexOf(_tindex), 1)
-        if (response.data.FunctionResponse.result == "发送成功") {
+        if (converter(response.data.FunctionResponse.result) == converter("发送成功")) {
         } else {
           this.$message.warning(response.data.FunctionResponse.result);
         }

+ 1 - 2
src/components/pages/aiAddCourse/addCourse3.vue

@@ -12641,10 +12641,9 @@ ${msg} 以及补充参考资料和教学任务教案和输出格式和内容要
 ${_text}
 
 ## 格式与要求
-任务名:
+任务数量:${this.teacherText.length}个
 任务描述:该描述是教师给与学生的指示(用于指导学生如何进行每个教学活动),对应到学生活动,你应该用友好,但是又清晰明确的口吻来撰写。
 评价标准:至少3条评价标准,这个评价是教师用来评价学生表现的,需要包含评价维度,以及该维度中教师期待学生的表现,句式为学生应该能....
-平台工具:
 工具名:从工具列表中选择0~2个工具用于学生阶段性成果提交:工具列表:[电子白板,文档,思维导图,表格,作业提交]
 工具指引:以友好,明确的口吻告诉学生该如何使用该工具
 

+ 151 - 50
src/components/pages/aiAddCourse/aiCreateDialog.vue

@@ -1,7 +1,7 @@
 <template>
     <el-dialog title="AI生成PPT" :visible.sync="dialogVisibleAiCreate" :append-to-body="true" width="700px"
         :before-close="handleClose" class="dialog_diy">
-        <div style="height: 500px; padding: 15px" v-loading="loading">
+        <div style="height: 500px; padding: 15px" v-loading="loading" element-loading-text="小可正在努力生成中,请稍等...">
             <!-- <div class="t_box">
                 <span>选择:</span>
                 <el-radio-group v-model="radio" @change="changeRadio">
@@ -11,8 +11,17 @@
                 </el-radio-group>
             </div> -->
             <div class="t_box" v-if="steps == 1" style="height: 100%">
-                <textarea style="height: 100%" rows="10" class="binfo_input binfo_textarea" cols placeholder="请生成大纲"
-                    v-model="outline"></textarea>
+                <textarea style="height: 100%;width:calc(100% - 260px)" rows="10" class="binfo_input binfo_textarea" cols
+                    placeholder="请生成大纲" v-model="outline"></textarea>
+                <div class="template_box">
+                    <span class="title">选择模板</span>
+                    <div class="template_list">
+                        <div class="template_item" :class="{ active: index == templateIndex }"
+                            v-for="(item, index) in templateList" :key="index" @click="changeTemplate(index)">
+                            <img :src="item.img" alt="" />
+                        </div>
+                    </div>
+                </div>
             </div>
             <div style="height: 100%" v-else>
                 <wOffice v-if="url" :url="url"></wOffice>
@@ -22,7 +31,7 @@
             <el-button @click="aiGet(2)" type="primary" :disabled="loading">重新生成大纲</el-button>
             <el-button @click="aiGet(1)" type="primary" :disabled="loading">{{
                 url ? "重新生成PPT" : "生成PPT"
-                }}</el-button>
+            }}</el-button>
             <el-button @click="steps = 1" type="primary" v-if="steps == 2">上一步</el-button>
             <el-button @click="steps = 2" type="primary" v-else-if="steps == 1 && url">下一步</el-button>
             <el-button @click="confirm" type="primary">确 定</el-button>
@@ -35,6 +44,7 @@
 import Pptxgen from "pptxgenjs";
 import wOffice from "../components/wOffice.vue";
 import { v4 as uuidv4 } from "uuid";
+import { color } from "highcharts";
 
 export default {
     components: {
@@ -59,7 +69,7 @@ export default {
         },
         CourseTypeJson: {
             type: Object,
-            default: ()=>({}),
+            default: () => ({}),
         }
     },
     // 根据用户给你的参考资料
@@ -93,6 +103,19 @@ export default {
             uJson: {},
             outline: "",
             steps: 1,
+            templateList: [
+                // { img: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model1-11719468995661.png', img2: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model1-21719469026755.png',color:'17094F' },
+                // { img: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model2-11719469051869.png', img2: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model2-21719469040181.png',color:'052B37' },
+                // { img: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model3-11719469071576.png', img2: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model3-21719469092087.png',color:'1D5869' },
+                // { img: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model4-11719469106190.png', img2: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model-4-21719469125318.png',color:'372213' },
+                // { img: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model5-11719295908696.png', img2: 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/model5-21719295930345.png',color:'674D40' },
+                { img: require('../../../assets/icon/ppt/model1-1.png'), img2: require('../../../assets/icon/ppt/model1-2.png'),color:'17094F' },
+                { img: require('../../../assets/icon/ppt/model2-1.png'), img2: require('../../../assets/icon/ppt/model2-2.png'),color:'052B37' },
+                { img: require('../../../assets/icon/ppt/model3-1.png'), img2: require('../../../assets/icon/ppt/model3-2.png'),color:'1D5869' },
+                { img: require('../../../assets/icon/ppt/model4-1.png'), img2: require('../../../assets/icon/ppt/model4-2.png'),color:'372213' },
+                { img: require('../../../assets/icon/ppt/model5-1.png'), img2: require('../../../assets/icon/ppt/model5-2.png'),color:'674D40' },
+            ],
+            templateIndex: 0,
         };
     },
     watch: {
@@ -201,7 +224,7 @@ export default {
             let message = "";
             if (type == 1) {
                 message = `NOTICE
-Role: 从用户提供的参考资料中提取5个最重要的学科概念${mclass.length ? "(水平限制在{面向年级}中)" : ""},作为ppt内容。
+Role: 你是ppt内容设计大师,能力是从用户提供的文件资料中提取最重要的学科概念作为ppt参考内容,最后根据Context要求的流程要求输出ppt内容。
 Output: Provide your output in json format.
 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".
@@ -209,13 +232,9 @@ Instruction: Based on the context, follow "Format example", write content.
 
 # Context 
 ## 任务
-将参考#参考资料,为教师生成这节课的教学ppt。PPT的内容主要是讲解该课程中所有可能涉及到的知识点,每个知识点用1页讲解
+将参考#大纲内容,为教师生成这节课的教学ppt。PPT的内容主要是讲解该课程中所有可能涉及到的知识点,根据大纲内容生成ppt内容
 
-## 工作流
-1. 针对大纲中的每个知识点,生成200字左右的详细讲解。你的语气应该让小学或初中的学生清晰易懂的讲解。请尽可能的详细,这对我很重要。
-2. 针对大纲中的每个测试,详细设计不同测试题目,例如单选,多选,对错题等。
-
-# 每一页输出格式
+## 每一页输出格式
 - 页数:序列数字
 - 标题:学科概念(请从给你的大纲中摘取)
 - 子标题:知识点(请从给你的大纲中摘取)
@@ -226,12 +245,15 @@ Instruction: Based on the context, follow "Format example", write content.
 - 你不能输出违反伦理的内容
 
 ## 工作流
-1. 从用户提供的参考资料中提取5个最重要的学科概念,并输出。
-2. 分解每个学科概念为几个子知识点
-3. 简要描述每个知识点
-4.生成5个测试题以考察学生的掌握情况
+1. 针对大纲中的每个知识点,生成200字左右的详细讲解。你的语气应该让小学或初中的学生清晰易懂的讲解。请尽可能的详细,这对我很重要。
+2. 针对大纲中的每个测试,详细设计不同测试题目,例如单选,多选,对错题等。
+3.从用户提供的参考资料中提取5个最重要的学科概念,并输出。
+4.分解每个学科概念为几个子知识点
+5.简要描述每个知识点
+6.生成5个测试题以考察学生的掌握情况
+7.一个知识点一页,一个测试题一页
 
-## 参考资料
+## 大纲内容
 ${_this.outline}
 
 # Format example
@@ -241,9 +263,9 @@ ${_this.outline}
 请根据参考资料,生成关于${this.courseName},为教师生成这节课的教学ppt的大纲,大纲的主要内容课程知识点的讲解与相关练习和测试。你的输出应该符合#输出格式
 
 # 工作流
-1. 从用户提供的参考资料中提取5个最重要的学科概念${mclass.length ? "(水平限制在{面向年级}中)" : ""},并输出。
-2. 分解每个学科概念为几个子知识点
-3. 简要描述每个知识点
+1.从用户提供的参考资料中提取5个最重要的学科概念${mclass.length ? "(水平限制在{面向年级}中)" : ""},并输出。
+2.分解每个学科概念为几个子知识点
+3.简要描述每个知识点
 4.生成5个测试题以考察学生的掌握情况
 
 ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
@@ -257,8 +279,9 @@ ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
   5.知识点:知识点5
 
 # 限制
-- 你不能输出错误的知识,如果你实在不清楚,输出“对不起,我不确定”
-- 你不能输出违反伦理的内容
+1.如果有参考资料请根据参考资料,如果没有无需根据参考资料进行,随意发挥。
+2.你不能输出错误的知识。
+3.你不能输出违反伦理的内容。
 `;
             }
 
@@ -365,50 +388,69 @@ ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
         createPpt(array) {
             // 1. 创建PPT
             const pres = new Pptxgen();
+            const _slideTou = pres.addSlide();
+            _slideTou.background = { path: this.templateList[this.templateIndex].img }
+            _slideTou.addText(this.courseName, {
+                x: "10%", // 横坐标
+                y: 3,
+                width: "90%",
+                color: this.templateList[this.templateIndex].color,
+                fontSize: 38, // 字号
+                align: "center",
+            });
             for (var i = 0; i < array.length; i++) {
                 // 2. 创建一个PPT页面,每调用一次 pres.addSlide() 都可以生成一张新的页面
                 // 建议把每个页面的构造抽成一个个函数,然后通过函数调用生成新页面,代码不会很乱
                 const _slide = pres.addSlide();
+                _slide.background = { path: this.templateList[this.templateIndex].img2 }
 
                 // 3. 调用addTetx(),在PPT页面中插入文字“Hello World from PptxGenJS...”
                 // 括号里面是对文字的配置,文字横坐标x为1.5,纵坐标y为1.5,字体颜色 363636……
                 // 关于坐标长度与px的转换 x 1 = 127~128px 左右
-                const page = i+1 > 10 ? i+1 : "0"+(i+1);
-                _slide.addText(page, {
-                    x: 0.2, // 横坐标
-                    y: 0.5,
-                    color: "363636",
-                    fontSize: 20, // 字号
-                    align: "left",
-                });
-                const tempResult1 = array[i].title;
+                const page = i + 1 > 10 ? i + 1 : "0" + (i + 1);
+                const tempResult1 = page + " " + array[i].title;
                 _slide.addText(tempResult1, {
-                    x: 0.6, // 横坐标
-                    y: 0.5,
-                    color: "363636",
+                    x: "10%", // 横坐标
+                    y: 1.1,
+                    width: "90%",
+                    color: this.templateList[this.templateIndex].color,
                     fontSize: 28, // 字号
-                    bold: true,
-                    align: "left",
+                    align: "center",
                 });
                 const tempResult2 = array[i].task;
                 _slide.addText(tempResult2, {
-                    x: 0.6, // 横坐标
-                    y: 1.5,
-                    color: "363636",
-                    fontSize: 18, // 字号
-                    align: "left",
+                    x: "10%", // 横坐标
+                    y: 1.8,
+                    width: "90%",
+                    color: "222222",
+                    fontSize: 20, // 字号
+                    align: "center",
                 });
-                const tempResult3 = array[i].points;
+                let tempResult3 = '';
+                if (typeof array[i].points == 'object') {
+                    tempResult3 = array[i].points.join('\n')
+                } else {
+                    tempResult3 = array[i].points
+                }
                 _slide.addText(tempResult3, {
-                    x: 0.6, // 横坐标
-                    y: 3,
+                    x: "20%", // 横坐标
+                    y: 3.2,
                     w: "60%",
-                    color: "363636",
+                    color: "444444",
                     fontSize: 18, // 字号
-                    align: "left",
+                    align: "center",
                 });
             }
-
+            const _slideWei = pres.addSlide();
+            _slideWei.background = { path: this.templateList[this.templateIndex].img }
+            _slideWei.addText("谢谢观看,下课!", {
+                x: "10%", // 横坐标
+                y: 3,
+                width: "90%",
+                color: this.templateList[this.templateIndex].color,
+                fontSize: 38, // 字号
+                align: "center",
+            });
             // 获取PPTX文件的ArrayBuffer
 
             // 保存为 Blob 并处理
@@ -416,7 +458,7 @@ ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
                 // 现在你有了一个 Blob 对象
                 console.log(blob);
 
-                const file = new File([blob], this.courseName+".pptx", {
+                const file = new File([blob], this.courseName + ".pptx", {
                     type: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                 });
                 console.log(pres);
@@ -474,6 +516,9 @@ ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
                     });
             }
         },
+        changeTemplate(index) {
+            this.templateIndex = index;
+        }
     },
 };
 </script>
@@ -544,13 +589,35 @@ ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
     font-family: "Microsoft YaHei";
 }
 
-.binfo_input:focus-visible {
-    border: 1.5px solid #3681fc !important;
+.binfo_textarea:focus-visible {
+  border: 1.5px solid #3681fc !important;
+}
+
+.binfo_textarea::-webkit-scrollbar {
+  /*滚动条整体样式*/
+  width: 6px;
+  /*高宽分别对应横竖滚动条的尺寸*/
+  height: 6px;
+}
+
+/*定义滚动条轨道 内阴影+圆角*/
+.binfo_textarea::-webkit-scrollbar {
+  border-radius: 10px;
+  background-color: #eee;
+}
+
+/*定义滑块 内阴影+圆角*/
+.binfo_textarea::-webkit-scrollbar-thumb {
+  border-radius: 10px;
+  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+  background-color: rgba(0, 0, 0, 0.1);
 }
 
 .t_box {
     display: flex;
     margin-bottom: 15px;
+    display: flex;
+    justify-content: space-between;
 }
 
 .t_box>span:nth-child(1) {
@@ -558,4 +625,38 @@ ${mclass.length ? "#参考资料\n面向年级:" + mclass.join(",") : ""}
     font-size: 16px;
     color: #000;
 }
+
+.template_box{
+    width: 250px;
+}
+.template_box > .title{
+    font-size: 18px;
+    margin-bottom: 10px;
+    display: block;
+}
+.template_list{
+    overflow: auto;
+    width: 100%;
+    height: calc(100% - 31px);
+}
+.template_item{
+    cursor: pointer;
+    width: 100%;
+    height: 165px;
+    overflow: hidden;
+    border-radius: 5px;
+    box-sizing: border-box;
+    border: 5px solid #e5e5e5ee;
+}
+.template_item + .template_item{
+    margin-top: 10px;
+}
+.template_item.active{
+    border: 5px solid #0061ff;
+}
+.template_item > img{
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
 </style>

+ 1 - 1
src/components/pages/aiAddCourse/aiCreateVideoDialog.vue

@@ -1,7 +1,7 @@
 <template>
     <el-dialog title="AI生成视频" :visible.sync="dialogVisibleAiCreateVideo" :append-to-body="true" width="700px"
         :before-close="handleClose" class="dialog_diy">
-        <div style="height: 500px;padding:15px" v-loading="loading">
+        <div style="height: 500px;padding:15px" v-loading="loading" element-loading-text="小可正在努力生成中,请稍等...">
             <div style="position: relative; width: 100%;height: 40px;margin-bottom: 10px;">
                 <el-input class="inputC" style="height: 100%;" placeholder="搜索视频关键字" v-model="detail"
                 @keyup.enter.native="aiGet()"></el-input>

+ 14 - 2
src/components/pages/classroomObservation/components/analysis.vue

@@ -16,7 +16,7 @@
 			<template v-for="(item, index) in analysisItemList">
 				<analysisItem
 				ref="analysisItemRef"
-				v-if="(item.jsonData.name!='词频词汇分析') && !['S-T分析:课堂时间分配','S-T分析:师生互动分析','S-T分析:教学模式分析'].includes(item.jsonData.name) "
+				v-if="(converter(item.jsonData.name)!=converter('词频词汇分析')) && ![converter('S-T分析:课堂时间分配'),converter('S-T分析:师生互动分析'),converter('S-T分析:教学模式分析')].includes(converter(item.jsonData.name)) "
 				:dialogTagDataList="dialogTagDataList"
 				:key="item.id"
 				:data="item"
@@ -29,7 +29,7 @@
 				@saveItem="saveItem"
 			/>
 			<analysisSpecialItem
-				v-if="['S-T分析:课堂时间分配','S-T分析:师生互动分析','S-T分析:教学模式分析'].includes(item.jsonData.name)"
+				v-if="[converter('S-T分析:课堂时间分配'),converter('S-T分析:师生互动分析'),converter('S-T分析:教学模式分析')].includes(converter(item.jsonData.name))"
 				:dialogTagDataList="dialogTagDataList"
 				ref="analysisItemRef"
 				:bmData="bmData"
@@ -54,6 +54,11 @@
 <script>
 import analysisItem from "./analysisItem";
 import analysisSpecialItem from './analysisSpecialItem'
+var OpenCC = require("opencc-js");
+let converter2 = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 export default {
 	emits: ["delItem", "editItem","saveItem"],
 	props: {
@@ -100,6 +105,13 @@ export default {
 		analysisItem,
 		analysisSpecialItem
 	},
+	computed: {
+		converter() {
+			return function (word) {
+				return converter2(word);
+			};
+		},
+	},
 	data() {
 		return {
 			showDialog: false,

+ 10 - 9
src/components/pages/classroomObservation/components/analysisItem.vue

@@ -269,14 +269,15 @@ export default {
 					.post("https://gpt4.cocorobo.cn/ai_agent_park_chat", parm)
 					.then((res) => {
 						let _data = res.data.FunctionResponse;
-						if (
-							!_data.message ||
-							_data.message.indexOf("由于我无法直接访问您上传的文件内容") > -1
-						) {
-							this.loading = false;
-							this.loadNum = 2;
-							return this.$message.error("AI无法识别优化");
-						}
+						// if (
+						// 	!_data.message ||
+						// 	_data.message.indexOf("由于我无法直接访问您上传的文件内容") > -1
+						// ) {
+						// 	this.loading = false;
+						// 	this.loadNum = 2;
+						// 	// this.$message.error("AI无法识别优化");
+						// 	return 
+						// }
 						let _copyData = JSON.parse(JSON.stringify(this.data));
 						// _copyData.jsonData.result = "";
 						_copyData.jsonData.content = _data.message;
@@ -297,7 +298,7 @@ export default {
 					})
 					.catch((err) => {
 						this.loadNum = 2;
-						this.$message.error("AI无法识别优化");
+						// this.$message.error("AI无法识别优化");
 						this.loading = false;
 					});
 			});

+ 66 - 7
src/components/pages/classroomObservation/components/analysisTemplateDialog.vue

@@ -186,16 +186,19 @@
 											style="background-color: #f0f2f5; color: black"
 											@click="editAnalysis(item)"
 											v-if="userId == item.userid"
+											class="bb_edit"
 										>
 											编辑
 										</div>
 										<div
 											style="border: solid 1px #3681fc; color: #3681fc"
+											class="bb_preview"
 											@click="previewAnalysis(item)"
 										>
 											预览
 										</div>
 										<div
+											class="bb_use"
 											style="background-color: #3681fc; color: white"
 											@click="useAnalysis(item)"
 										>
@@ -367,7 +370,7 @@ export default {
 				{ value: "9", label: "地理" },
 				{ value: "10", label: "政治" },
 			],
-			defaultData:{"id":"45413212-2956-11ef-bee5-005056b86db5","name":"科学通用模板","detail":"针对性分析科学课堂,包含通用分析模块以及科学学科分析模块,并采用5E和5EX课程设计模型对课堂进行改编。","open":"1","userid":"qgt","type":"4","use":0,"update_at":"2024-06-13T07:21:48.000Z","create_at":"2024-06-13T07:21:48.000Z"},
+			defaultData:null,
 			templateData: [],
 			collectData: [],
 			analysisDetail: null,
@@ -397,14 +400,16 @@ export default {
 			this.tagBox = 0;
 			this.getData();
 			this.getCollectData(false);
+			this.getDefaultTemplate();
 			this.dialogVisible = true;
 		},
 		close() {
-			if (this.loading) return;
+			// if (this.loading) return;
 			this.dialogVisible = false;
 			this.text = "";
 			this.tagIndex = 1;
 			this.tagSubject = 0;
+			this.defaultData = null;
 			this.tagBox = 0;
 		},
 		changeTagSubject(subject) {
@@ -507,7 +512,7 @@ export default {
 		},
 		// 使用
 		useAnalysis(item) {
-			this.$confirm("使用模板会替换原有的模板!是否使用该模板?", "提示", {
+			this.$confirm("确定使用该模板来创建新的课堂吗?", "提示", {
 				confirmButtonText: "确定",
 				cancelButtonText: "取消",
 				type: "warning",
@@ -527,18 +532,21 @@ export default {
 						.then((res) => {
 							let _data = res.data[0][0];
 							if (_data) {
+								this.loading = true;
 								_data.tips = JSON.parse(_data.tips);
-								console.log(_data);
+								this.$emit("useTemplate", _data.tips);
 							} else {
+								this.loading = false;
 								this.$message.error("获取模板详细为空");
 							}
 						})
 						.catch((e) => {
 							console.log(e);
+							this.loading = false;
 							this.$message.error("获取模板详细失败");
 						})
 						.finally((_) => {
-							this.loading = false;
+							// this.loading = false;
 						});
 				})
 				.catch(() => {
@@ -704,7 +712,7 @@ export default {
 			);
 			_data.splice(_dIndex, 1);
 			this.analysisDetail.tips = JSON.parse(JSON.stringify(_data));
-			this.$message.success("删除成功");
+			// this.$message.success("删除成功");
 		},
 		// 添加弹窗
 		addAnalysisItem(type) {
@@ -743,10 +751,48 @@ export default {
 			this.tagBox = 0;
 			this.analysisDetail = null;
 		},
+		getDefaultTemplate(){
+			let params = {
+				uid:this.userId
+			}
+			this.ajax.get(this.$store.state.api+"selectClassroomDefault",params).then(res=>{
+				let _data = res.data[0][0];
+				this.defaultData = _data;
+			}).catch(e=>{
+				this.$message.error("获取默认模板失败");
+				console.log(e);
+			})
+		},
 		//设置默认
 		setDefault(_data){
 			if(this.defaultData.id==_data.id)return;
-			this.$message.info("设置默认");
+			this.$confirm("确定设置该模板为默认模板?", "提示", {
+				confirmButtonText: "确定",
+				cancelButtonText: "取消",
+				type: "warning",
+			})
+				.then(() => {
+					let params = [{
+				uid:this.userId,
+				tid:_data.id
+			}]
+			this.ajax.post(this.$store.state.api+"updateClassroomDefault",params).then(res=>{
+				console.log("👇设置默认模板")
+				if(res.data ==1){
+					this.$message.success('设置默认模板成功');
+				}else{
+					this.$message.error('设置默认模板失败');
+				}
+				this.getDefaultTemplate();
+			}).catch(e=>{
+				this.$message.error('设置默认模板失败');
+				console.log(e);
+				this.getDefaultTemplate();
+			})
+				}).catch(e=>{
+					console.log(e)
+				})
+			// this.$message.info("设置默认");
 		}
 	},
 };
@@ -1069,6 +1115,7 @@ export default {
 	align-items: center;
 	border-radius: 6px;
 	cursor: pointer;
+	transition: .3s;
 }
 
 .analysisDetail {
@@ -1160,4 +1207,16 @@ export default {
 	padding: 12px;
 	box-sizing: border-box;
 }
+
+.bb_preview:hover{
+	background-color: #E0EAFB;
+}
+
+.bb_edit:hover{
+	background-color: #e4e6e9 !important;
+}
+
+.bb_use:hover{
+	background-color: #3171da !important;
+}
 </style>

+ 12 - 5
src/components/pages/classroomObservation/components/baseMessage.vue

@@ -70,7 +70,7 @@
 							style="width: 100%"
 							v-model="data.subject"
 							@change="changeData()"
-							placeholder="请选择年级"
+							placeholder="请选择科目"
 						>
 							<el-option
 								v-for="(item, index) in subjectList"
@@ -133,7 +133,7 @@
 							<div
 								class="m-m-fi-imageItem"
 								@click.stop="addImage()"
-								style="max-width:60%;"
+								style="max-width:32%;"
 								v-if="
 									imageList.fileList1 &&
 									imageList.fileList1.length +
@@ -339,6 +339,12 @@ export default {
 				{ value: "小学四年级", label: "小学四年级" },
 				{ value: "小学五年级", label: "小学五年级" },
 				{ value: "小学六年级", label: "小学六年级" },
+				{ value: "初中一年级", label: "初中一年级" },
+				{ value: "初中二年级", label: "初中二年级" },
+				{ value: "初中三年级", label: "初中三年级" },
+				{ value: "高中一年级", label: "高中一年级" },
+				{ value: "高中二年级", label: "高中二年级" },
+				{ value: "高中三年级", label: "高中三年级" },
 			],
 			subjectList: [
 				{ value: "语文", label: "语文" },
@@ -556,8 +562,8 @@ Instruction: Based on the context, follow "Format example", write content.
 ]
 
 ## 课堂实录 
-${this.data.editorBarData.content}
-`;
+${this.data.editorBarData?this.data.editorBarData.content:""}
+`;			
 				const _uuid = uuidv4();
 				let params = {
 					model: "gpt-3.5-turbo",
@@ -613,6 +619,7 @@ ${this.data.editorBarData.content}
 					.catch((e) => {
 						console.log(e);
 						this.$message.error("生成词云图失败");
+						this.uploadNephogramLoading = false;
 					})
 					.finally((_) => {
 						this.uploadNephogramLoading = false;
@@ -802,7 +809,7 @@ ${this.data.editorBarData.content}
 	margin-bottom: 20px;
 	display: flex;
 	justify-content: flex-start;
-	flex-wrap: wrap;
+	/* flex-wrap: wrap; */
 }
 
 .m-m-fi-imageList {

+ 291 - 16
src/components/pages/classroomObservation/components/chatArea.vue

@@ -618,7 +618,7 @@ export default {
 			input.type = "file";
 			// input.accept = ".wav";
 			// input.accept = "audio/*, .txt, .pdf, .xlsx";
-			input.accept = ".wav,.txt,.pdf,.xlsx,.doc,.docx";
+			input.accept = ".wav,.txt,.pdf,.xlsx,.doc,.docx,.csv";
 			input.click();
 			input.onchange = () => {
 				this.uploadFileLoading = true;
@@ -626,7 +626,7 @@ export default {
 				if (!/\.(wav|txt|pdf|xlsx|doc|docx)$/i.test(file.name)) {
 					this.uploadFileLoading = false;
 					return this.$message.info(
-						"请上传.wav,.txt,.pdf,.xlsx,.doc,.docx格式的文件"
+						"请上传.wav,.txt,.pdf,.xlsx,.doc,.docx,.csv格式的文件"
 					);
 				}
 				this.uploadFile(file, { changeText: true, flag: true });
@@ -1052,6 +1052,11 @@ export default {
 		},
 		// 发送消息
 		send(_text = this.textareaValue) {
+			var OpenCC = require("opencc-js");
+			let converter = OpenCC.Converter({
+					from:'cn',
+					to:'hk'
+			})
 			this.textareaValue = "";
 			// 判断输入的文本是否为空
 			if (!_text.trim()) return;
@@ -1121,7 +1126,7 @@ export default {
 					this.ajax
 						.post("https://gpt4.cocorobo.cn/ai_agent_park_chat_new", params)
 						.then((res) => {
-							if (res.data.FunctionResponse.result == "发送成功") {
+							if (converter(res.data.FunctionResponse.result) == converter("发送成功")) {
 							} else {
 								this.$message.warning(res.data.FunctionResponse.result);
 							}
@@ -1183,11 +1188,12 @@ export default {
 				// 	uid: _uuid,
 				// 	model: "Claude 3 Sonnet", // Claude 3 Sonnet或者Claude 3 Haiku
 				// });
+				
 				this.ajax
 					.post("https://gpt4.cocorobo.cn/chat", params)
 					// .post("https://claude3.cocorobo.cn/chat", params)
 					.then((res) => {
-						if (res.data.FunctionResponse.result == "发送成功") {
+						if (converter(res.data.FunctionResponse.result) == converter("发送成功")) {
 						} else {
 							this.$message.warning(res.data.FunctionResponse.result);
 						}
@@ -1314,6 +1320,255 @@ export default {
 		noShowRoleList() {
 			this.showRoleList = false;
 		},
+		getBehaviorCoding(list){
+			let start = 0;
+			let end = 0;
+			let _pList = [];
+			let _step = 9999999999999999999;
+			let promiseList  = []
+			for(let i = 0;i<=list.length-1;i++){
+				_pList.push(list[i])
+				if(i==0)continue;
+				if(i%_step==0){
+					end = i;
+					promiseList.push(this.getBehaviorCodingPromise(start,end,_pList).then(_res=>{
+						let {startIndex,endIndex,data} =_res;
+						data.forEach((item2,index2)=>{
+							list[startIndex+index2].aiBehavior = item2;
+						})
+						// let 
+					}))
+					_pList = [];
+					start = i;
+					continue;
+				}
+				if(i==(list.length-1)){
+					end = i;
+					promiseList.push(this.getBehaviorCodingPromise(start,end,_pList).then(_res=>{
+						let {startIndex,endIndex,data} =_res;
+						console.log("promise👉",_res)
+						data.forEach((item2,index2)=>{
+							list[startIndex+index2].aiBehavior = item2;
+						})
+					}))
+					_pList = [];
+					start = i;
+					break;
+				}
+			}
+			Promise.all(promiseList).then(_=>{
+				console.log('👇')
+				console.log(list)
+			})
+
+
+			
+			
+			// list.forEach((item,index)=>{
+			// 	if(index==0){
+			// 		start = 0;
+			// 		end = 0;
+			// 		_pList = [];
+			// 	}
+
+			// }) 
+
+		},
+		getBehaviorCodingPromise(start,end,list){
+			return new Promise((resolve,reject)=>{
+				let _uuid = uuidv4();
+				let _workText = '';
+				let _list = [];
+				list.forEach(i=>{
+					_list.push({
+						index:i.index,
+						message:i.message,
+						time:i.time,
+						role:i.role,
+						behavior:"",
+					})
+				})
+				// list.forEach(i=>{
+				// 	_workText+=`${i.message} ${i.time} ${i.role}\n`
+				// }) 
+				let _msg = `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
+				
+请你基于以下{用户给定的文本},执行以下任务,按要求输出对应内容。
+
+## 角色
+
+你是专业的课堂行为分析员,熟悉课堂行为编码的标准和分类,能够准确识别和标注课堂中的各种行为。
+
+## 任务
+
+根据用户给定的文本和文本上下文背景,为用户提供的每一行文本,打上相应的行为编码的标签。输出行为编码的名称,以及你的判断理由。严格按照指定的格式输出编码名称,请仅仅只是输出编码名称,无需任何其它的解释性文字。
+
+## 工作流程
+
+1. 仔细阅读并分析用户提供的文本。
+2. 仔细阅读用户指定的某一行文本,结合上下文,参考知识库中的编码特征描述,为该行文本打上相应的行为编码标签。
+3. 严格按照指定的格式输出编码名称,请仅仅只是输出编码名称,无需任何其它的解释性文字。
+
+
+## 知识库
+
+### 简单版本的编码特征描述
+
+每个编码类型的名字、评价标准、语言学特征,以及相应的课堂实例。
+
+| 行为编码       | 评价标准                                               | 语言学特征                                                   | 课堂实例                                                     |
+| -------------- | ------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| 老师讲课       | 老师进行知识传授、活动安排、总结等。                   | 使用陈述句,语气平稳,内容多为知识传授、活动安排、总结等。   | 1.' '好了,接下来我们进行一个小实验,请大家按照步骤操作'。' <br> 2.' '那孩子们仔细看老师的手指,十个手指中有一些指向陆地,有一些指向海洋'。' <br> 3.' '现在我随机把这个球传给我们班上的任意1位同学,请你数数几个陆地几个海洋'。' |
+| 老师提问或点名 | 老师提问学生或点名学生回答问题。                       | 使用疑问句或指令性语言,语气较为引导,内容多为提问或点名。   | 1.' '请你说'。' <br> 2.' '请你帮我数一数有多少个陆地,多少个海洋'。' <br> 3.' '那这个时候我们可以怎么办?这些困难又会给我们带来什么样的启发呢?'' |
+| 老师板书或操作 | 老师在黑板上书写或进行实验操作。                       | 使用描述性语言和指令性语言,语气较为平稳,内容多为书写或操作指令。 | 1.' '请大家看黑板,这里是我们今天要学习的重点'。' <br> 2.' '接下来我们进行一个小实验,请大家按照步骤操作'。' <br> 3.' '我现在在黑板上写下这个公式,大家要记住'。' |
+| 老师评价或反馈 | 老师对学生的回答或表现进行评价或反馈。                 | 使用评价性语言和反馈性语言,语气较为鼓励,内容多为评价或反馈。 | 1.' '所以你是个观察仔细的同学,请坐'。' <br> 2.' '你是一个善于思考的孩子'。' <br> 3.' '非常好的方法'。' |
+| 老师其它       | 老师进行与课堂内容相关的其他活动。                     | 使用描述性语言和指令性语言,语气较为活泼,内容多为活动描述或操作指令。 | 1.' '这实在是太有趣了,原来失重使太空与地球之间的生活形成了如此大的差别'。' <br> 2.' '请大家自由编创,同学们可以想一想'。' <br> 3.' '我们将白玫瑰横向剪开,再纵向剪开,观察茎的内部结构'。' |
+| 学生发言       | 学生在课堂上进行简短的发言或回答老师的问题。           | 使用简短的陈述句或疑问句,语气较为随意,内容多为回答问题或简短发言。 | 1.' '我觉得是一号'。' <br> 2.' '因为一号比那个二号大好'。' <br> 3.' '因为呢海洋看上去面积更大'。' |
+| 学生讨论       | 学生进行小组讨论或合作活动。                           | 使用讨论性语言和合作性语言,语气较为互动,内容多为讨论或合作。 | 1.' '请小评委们对照评价标准,小组内先讨论一下,可以站起来找同学说说你的想法'。' <br> 2.' '大家请看视频,先选取一朵白玫瑰,将水染色,把白玫瑰插入水中,等待一天'。' <br> 3.' '我们严格执行调查计划,通过百度、豆包等渠道搜集相关资料'。' |
+| 学生小组活动   | 学生进行小组讨论或合作活动。                           | 使用讨论性语言和合作性语言,语气较为互动,内容多为讨论或合作。 | 1.' '请小评委们对照评价标准,小组内先讨论一下,可以站起来找同学说说你的想法'。' <br> 2.' '大家请看视频,先选取一朵白玫瑰,将水染色,把白玫瑰插入水中,等待一天'。' <br> 3.' '我们严格执行调查计划,通过百度、豆包等渠道搜集相关资料'。' |
+| 学生自主学习   | 学生进行自主学习或独立完成任务。                       | 使用描述性语言和指令性语言,语气较为平稳,内容多为学习任务或指令。 | 1.' '请大家独立完成这道题目'。' <br> 2.' '现在大家可以开始阅读课本的第十页'。' <br> 3.' '请同学们在接下来的十分钟内完成这份练习'。' |
+| 学生汇报分享   | 学生进行小组汇报、分享学习成果、展示活动成果等。       | 使用陈述句和描述性语言,语气较为正式,内容多为汇报、分享学习成果。 | 1.' '我们小组用了拼接法来比较海陆的面积'。' <br> 2.' '我们利用粘豆子的方法来比较海陆面积'。' <br> 3.' '我们采取数格子的方法比较海陆面积'。' |
+| 学生其他       | 学生进行与课堂内容相关的其他活动,如表演、实验操作等。 | 使用描述性语言和指令性语言,语气较为活泼,内容多为活动描述或操作指令。 | 1.' '这实在是太有趣了,原来失重使太空与地球之间的生活形成了如此大的差别'。' <br> 2.' '请大家自由编创,同学们可以想一想'。' <br> 3.' '我们将白玫瑰横向剪开,再纵向剪开,观察茎的内部结构'。' |
+
+
+### 行为编码详细的特征描述
+
+#### 【老师讲课】的特征
+
+老师的发言内容具有结构清晰、互动性强、鼓励参与、引导性强、教育性和启发性、反馈及时、语言简洁明了和注重细节等特征。这些特征有助于提高学生的参与度和学习效果,营造积极的课堂氛围。
+
+1. **结构清晰**:发言内容按照时间顺序进行,逻辑性强,层次分明。老师先介绍活动背景和目的,然后逐步引导学生进行展示和互动,最后进行总结和评价。
+2. **互动性强**:老师频繁与学生互动,鼓励学生提问、分享和展示。例如,老师多次邀请学生上台展示成果,并给予鼓励和表扬。
+3. **鼓励参与**:老师通过掌声、表扬和鼓励性语言,激发学生的参与热情,增强他们的自信心。例如,老师多次使用“掌声欢迎”、“太棒了”等词语。
+4. **引导性强**:老师在发言中起到了引导和组织的作用,明确活动的流程和要求,帮助学生更好地理解和参与活动。例如,老师详细说明了展示的内容和形式,并在每个环节进行引导。
+5. **教育性和启发性**:发言内容不仅传授知识,还注重培养学生的思维能力和团队合作精神。例如,老师强调相互学习、汲取智慧、共同掌握知识等。
+6. **反馈及时**:老师在学生展示和分享后,及时给予反馈和评价,帮助学生认识到自己的优点和不足。例如,老师在学生展示后进行点评,并表扬表现优秀的学生。
+7. **语言简洁明了**:老师的发言内容简洁明了,易于学生理解和接受。例如,老师使用了大量简短的句子和明确的指令。
+8. **注重细节**:老师在发言中关注细节,确保活动顺利进行。例如,老师提醒学生坐端正、认真听讲,并对每个环节进行详细说明。
+
+#### 【老师提问或点名】的特征
+
+老师的发言内容具有频繁提问、鼓励参与、引导思考、关注情感、鼓励表达和互动性强等特征。这些特征有助于激发学生的学习兴趣,增强课堂的互动性和参与度,促进学生的思考和表达能力。
+
+1. **频繁提问**:老师在发言中频繁提问,涉及到学生的感受、意见和解决方案等。这种提问不仅包括直接的问题(如“谁来告诉我”、“你们想投给谁”),还包括引导学生思考和表达的开放性问题(如“这些困难又会给我们带来什么样的启发”)。
+2. **鼓励参与**:老师通过提问和点名的方式,鼓励学生积极参与课堂活动。例如,老师多次邀请学生上台展示或汇报(如“有请繁星植物队”、“让我们有请小苗护卫队的同学上来汇报”)。
+3. **引导思考**:老师的提问不仅仅是为了获取答案,更是为了引导学生进行深入思考。例如,老师在讨论植物成长过程中遇到的困难时,提出“这些困难又会给我们带来什么样的启发”,引导学生从问题中学习和反思。
+4. **关注情感**:老师关注学生的情感和感受,询问他们的想法和感受(如“那两位小朋友这一次获得胜利有什么想说的吗”、“那你们愿意分享一下你们此时此刻的感受吗”)。这种关注有助于建立良好的师生关系,增强学生的课堂参与感。
+5. **鼓励表达**:老师通过提问和点名,鼓励学生表达自己的观点和感受。例如,老师多次邀请学生举手发言,并给予积极的反馈(如“好非常棒还有吗”、“好支持”)。
+6. **互动性强**:老师的发言内容具有很强的互动性,通过提问、点名和邀请学生上台等方式,增加了课堂的互动性和参与度。
+
+#### 【老师评价或反馈 】的特征:
+
+老师的发言内容具有高度的评价性、鼓励性和指导性,旨在通过正面反馈和具体建议帮助学生提升,同时激励他们在未来的学习和生活中继续努力和探索。
+
+1. **频繁的评价和反馈**:老师在整个过程中频繁地对学生的表现进行评价和反馈。这些评价和反馈既有对具体表现的即时评价(如“缺少了节奏感”、“讲得很好”),也有对整体表现的总结性评价(如“非常感谢神探队的精彩分享”、“同学们种子舰队小组的分享很精彩”)。
+2. **正面鼓励和表扬**:老师的发言中充满了正面的鼓励和表扬,强调学生的优点和进步。例如,“我要为种子建队小组点赞”、“你们在老师心目中是一样优秀的”、“希望你们在未来的学习和生活中学会用科学的方法去探索”。
+3. **具体的改进建议**:除了表扬,老师也提供了具体的改进建议,帮助学生认识到需要改进的地方。例如,“缺少了节奏感”、“缺少了音乐”、“语速也很适中是吧”。
+4. **激励和引导**:老师通过发言激励学生继续努力,并引导他们在未来的学习和生活中应用所学知识。例如,“希望你们在未来的学习和生活中学会用科学的方法去探索”、“要勇于探索,学以致用”。
+5. **总结和过渡**:老师在不同环节之间进行总结和过渡,帮助学生理清思路,保持活动的连贯性。例如,“我们今天的汇报活动到此结束”、“下面的时间交给罗老师”。
+6. **互动性**:老师的发言中有一定的互动性,鼓励学生参与和思考。例如,“大家觉得他们俩谁写的比较好呢”、“大家猜一猜”。
+
+【】
+
+#### 【老师其它】的特征:
+
+无法归类为【老师讲课】【老师提问或点名】【老师评价或反馈】,则归类为【老师其它】。这类内容可能具备以下的特点:
+
+1. **引导和组织**:老师在多个时段引导活动的进行,如邀请嘉宾、介绍活动内容、安排学生讨论和投票等。例如,序号417、418、425、548、549、722、723、724、725、763、794等。
+2. **时间管理**:老师在发言中多次提到时间安排,确保活动按计划进行。例如,序号548、794等。
+3. **信息传达**:老师在发言中传达了活动的背景、过程和结果,确保学生了解活动的每个环节。例如,序号544、545、546、547、766、769等。
+
+---
+
+#### 【学生发言】的特征:
+
+学生的发言内容具有频繁且简短、重复和断续、描述和解释、讨论和建议、引用和推理、互动和回应以及内容多样性的特征。这些特征反映了学生在课堂讨论中的积极参与和多方面的思考。
+
+1. **频繁且简短**:学生的发言内容多为简短的句子或片段,时长通常在几秒钟内。这表明学生们的发言较为频繁,但每次发言的内容较为简短。
+2. **重复和断续**:有些发言内容存在重复和断续的现象,如“谁知谁知谁知谁知这个习惯的过程”、“4个4个”等。这可能反映了学生在表达时的思维跳跃或语言组织上的困难。
+3. **描述和解释**:学生们经常描述某些现象或解释某些概念,如“海洋面积大于陆地面积”、“水可以帮助我们发电”等。这表明学生们在尝试通过语言来传达他们的理解和知识。
+4. **讨论和建议**:学生们不仅仅是陈述事实,还会提出建议和进行讨论,如“我建议他们可以不要把两个陆地给重合了”、“因为他外他们有一些群岛就非常多的一些海洋就还是得接触一点”等。这显示了学生们在互动中积极参与并提出自己的见解。
+5. **引用和推理**:有些发言内容引用了书本知识或进行了一些推理,如“我在科普书上看到过”、“如果没有了水的话就会非常的炎热”等。这表明学生们在发言时会结合已有的知识进行推理和论证。
+6. **互动和回应**:学生们的发言中有不少是对他人发言的回应或互动,如“请你说”、“同意请坐”等。这显示了课堂上学生之间的互动性较强,发言不仅仅是单向的表达。
+7. **多样性**:发言内容涉及多个主题和方面,从地理知识到水资源的用途,再到环境保护等,内容多样且广泛。这反映了学生们在课堂讨论中涉及的知识面较广。
+
+#### 【学生小组活动】的特征:
+
+1. **频繁重复**:发言中多次重复“数据”、“谁知”、“谢谢”等词语,显示出学生在表达过程中可能存在词汇匮乏或表达不清的情况。
+2. **短促且断续**:大部分发言时长较短,通常在几秒钟内完成,且内容断续,缺乏连贯性。这可能反映了学生在小组活动中交流的即时性和随意性。
+3. **非正式语言**:使用了大量口语化的表达,如“唉”、“嗯”、“啊”等,显示出学生在小组活动中的交流较为随意和非正式。
+4. **任务导向**:尽管语言较为随意,但发言内容多与任务相关,如讨论数据、完成任务、粘贴结果等,表明学生在进行小组活动时仍然围绕着特定的任务展开。
+5. **互动性强**:发言中多次出现对他人发言的回应和感谢,如“谢谢大家”、“谢谢谢谢”,显示出学生之间的互动频繁,合作性较强。
+6. **信息量有限**:由于发言多为短句和重复,实际传递的信息量较为有限,可能需要更多的时间和交流来完成任务。
+
+#### 【学生讨论】的特征:
+
+发言内容显示出学生在讨论过程中可能存在表达不清、思路不明确、互动不足等问题,影响了讨论的有效性和信息传递的清晰度。
+
+1. **频繁使用填充词**:发言中大量使用“嗯”、“谁知”等填充词,显示出说话者在表达过程中可能存在思考或犹豫。
+2. **表达不清晰**:许多句子结构不完整,逻辑不连贯,难以理解具体意思。例如,“谁知谁知到时候谁知所以患者嗯谁知谁知嗯谁知嗯谁知嗯谁知谁知嗯嗯嗯谁知谁谁知他没有这个应该要做翻译”。
+3. **重复和冗长**:发言中有大量重复的词语和短语,导致内容显得冗长且缺乏重点。例如,“谁知谁知谁知谁知谁知谁知谁知谁知”。
+4. **缺乏具体信息**:大部分发言内容缺乏具体的、有意义的信息,更多的是一些模糊的、泛泛的表述。
+5. **互动性低**:虽然是学生讨论,但从发言内容来看,互动性较低,更多是单方面的表达,缺乏有效的交流和回应。
+6. **情绪表达**:偶尔有情绪表达的词语,如“谢谢”、“好好好”,但整体情绪表达不强烈。
+
+#### 【学生汇报分享 】的特征:
+
+1. **结构化和条理性**:学生的发言内容通常按照一定的逻辑顺序进行,先介绍方法,再给出数据,最后得出结论。例如,学生先介绍使用的方法(拼接法、粘豆子法、数格子法),然后提供具体的测量数据,最后总结出海洋面积大于陆地面积的结论。
+2. **重复和确认**:在发言过程中,学生多次重复和确认数据和结论。这种重复不仅帮助巩固信息,也确保听众能够清楚理解。例如,学生多次确认陆地和海洋的重量或格子数。
+3. **多样化的方法**:学生使用了多种方法来比较海陆面积,包括拼接法、粘豆子法和数格子法。这显示了学生在解决问题时的多样化思维和尝试不同方法的能力。
+4. **数据驱动**:学生的发言内容高度依赖于具体的数据和计算结果。每个方法的介绍都伴随着具体的数值和计算过程,显示了学生对数据的重视和对结果的严谨态度。
+5. **合作和综合**:学生在发言中提到综合不同小组的结果,显示了合作学习和综合分析的特征。例如,学生在总结时提到综合两个小组的结果得出结论。
+6. **简洁明了**:学生的发言内容简洁明了,直接切入主题,避免了冗长的描述。这有助于听众快速抓住重点信息。
+
+综上所述,【发言内容】具有内容丰富、结构清晰、互动性强、语言生动、注重实践、团队合作、教育意义和情感表达等特征,展示了学生们在科学探究和团队合作中的积极表现和学习成果。
+
+#### 【学生其它】的特征:
+
+无法归类为【学生发言】【学生小组活动】【学生讨论】【学生汇报分享】,则归类为【学生其它】。
+
+
+## 数据
+
+这是你需要打标签的特定的多行文本:
+${JSON.stringify(_list)}
+
+# Format example
+[{index:1,message:"早上好",time:"00:00:2",role:"老师",behavior:"老师其它"},{index:2,message:"今天我们来学物理学",time:"00:00:5",role:"老师",behavior:"老师讲课"},{index:3,message:"有谁知道什么是物理吗",time:"00:00:3",role:"老师",behavior:"老师提问或点名"}]
+`
+				console.log(_msg)
+			let params = {
+			  assistant_id: '6063369f-289a-11ef-8bf4-12e77c4cb76b',
+			  userId: this.userId,
+				// message:_msg,
+			  // message: [{role:"user",content:_msg}],
+				message: [{"type":"text","text":_msg}],
+			  session_name:_uuid,
+			  // uid: _uuid,
+			  file_ids: []
+			};
+
+			
+			this.ajax.post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params).then(res=>{
+				// let _data = res.data.FunctionResponse.choices[0].message.content;
+				let _data = res.data.FunctionResponse.message;
+				_data = _data.replaceAll("```json", "").replaceAll("```", "");
+				// console.log(_data)
+				// console.log(JSON.parse(_data))
+				_data = JSON.parse(_data);
+				console.log("👇")
+				console.log(_data)
+				console.log("👆")
+				// resolve({startIndex:start,endIndex:end,data:_data})
+			}).catch(err=>{
+				console.log(err);
+				this.$message.error("行为编码错误")
+			})
+
+			})
+		},
 		// convertToMp3(wavDataView) {
 		// 	// 获取wav头信息
 		// 	const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置
@@ -1494,7 +1749,7 @@ export default {
 							// 判断是不是音频文件
 							const audioRegex = /\.(mp3|wav|ogg|flac|m4a)$/i;
 							const txtRegex = /\.(txt)$/i;
-							const otherRegex = /\.(pdf|xlsx|doc|docx)$/i;
+							const otherRegex = /\.(pdf|xlsx|doc|docx|csv)$/i;
 							// if (audioRegex.test(data.Location)) {
 							// 	// console.log(data);
 							// 	_this.uploadWavFileAndGetText(file)
@@ -1519,6 +1774,7 @@ export default {
 								_this.saveEditorBar();
 								return;
 							}
+
 							_this.ajax
 								.put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
 									url: data.Location,
@@ -1782,28 +2038,36 @@ export default {
 				// let div = document.createElement("div");
 				// div.innerHTML = this.editorBarData.content;
 				// return this.loading = false;
-				let _data = this.editorBarData.content;
-				let _div = document.createElement("div");
+				
 				let _sentence = 0;
 				let _words = 0;
+
+				if(this.editorBarData.type==0){
+					let _data = this.editorBarData.content;
+				let _div = document.createElement("div");
 				_div.innerHTML = _data;
+				let _test = []
 				let _tableRows = _div.querySelectorAll(`table tbody tr`);
 				_tableRows.forEach((i, index) => {
 					if (index == 0) return;
-					// let obj = {
-					// 	index: i.cells[0].textContent,
-					// 	startTime: i.cells[1].textContent,
-					// 	endTime: i.cells[2].textContent,
-					// 	message: i.cells[3].textContent,
-					// 	time: i.cells[4].textContent,
-					// 	role: i.cells[5].textContent,
-					// 	behavior: i.cells[6].textContent,
-					// };
+					let obj = {
+						index: i.cells[0].textContent,
+						startTime: i.cells[1].textContent,
+						endTime: i.cells[2].textContent,
+						message: i.cells[3].textContent,
+						time: i.cells[4].textContent,
+						role: i.cells[5].textContent,
+						behavior: i.cells[6].textContent,
+					};
+					_test.push(obj)
 					if(i.cells[3].textContent!=""){
 						_sentence+=1;
 						_words+=i.cells[3].textContent.length;
 					}
 				});
+				// this.getBehaviorCoding(_test)
+				}
+				
 				this.editorBarData.sentenceNum = _sentence;
 				this.editorBarData.wordsNum = _words;
 				this.$parent.saveWordFrequency({_sentence,_words})
@@ -1911,6 +2175,17 @@ export default {
 			// console.log(this.editorBarData)
 			this.$forceUpdate();
 		},
+		// 初始化
+		init(){
+			this.transcriptionData.content="";
+			this.chatList = [];
+			this.editorBarData = {
+				type: "0", //0---文字   1-文件
+				content: "",
+				url: "",
+			}
+			this.audioUrl = "";
+		}
 	},
 	mounted() {},
 };

ファイルの差分が大きいため隠しています
+ 127 - 95
src/components/pages/classroomObservation/components/messageArea.vue


+ 23 - 7
src/components/pages/classroomObservation/components/saveTemplateDialog.vue

@@ -50,6 +50,11 @@
 </template>
 
 <script>
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 export default {
 	emits: ["success"],
 	props: {
@@ -122,13 +127,24 @@ export default {
 						let _result = [];
 						
 						_data.forEach(i=>{
-							i.jsonData.content = "";
-							i.jsonData.dataFileList = [];
-							i.jsonData.fileList = [];
-							i.createtime = "";
-							i.id = "",
-							i.tId = "",
-							i.userid = "";
+							if(converter(i.jsonData.name)==converter('词频词汇分析')){
+								i.jsonData.wordNum = 0;
+								i.jsonData.wordCountNum = 0;
+								i.createtime = "";
+								i.jsonData.content = "";
+								i.id = "",
+								i.tId = "",
+								i.userid = "";
+							}else{
+								i.jsonData.content = "";
+								i.jsonData.dataFileList = [];
+								i.jsonData.fileList = [];
+								i.createtime = "";
+								i.id = "",
+								i.tId = "",
+								i.userid = "";
+							}
+							
 							_result.push(i)
 						})
 						let params = [{

+ 215 - 77
src/components/pages/classroomObservation/index.vue

@@ -34,13 +34,15 @@
 							<div class="selectBox">
 								<span>{{ item.label }}</span>
 								<div class="controlsBox">
-									<span class="changeSelect" @click.stop="changeCourse(item)"></span>
 									<span
-									class="delSelect"
-									@click.stop="delCourse(item.id)"
-								></span>
+										class="changeSelect"
+										@click.stop="changeCourse(item)"
+									></span>
+									<span
+										class="delSelect"
+										@click.stop="delCourse(item.id)"
+									></span>
 								</div>
-								
 							</div>
 						</el-option>
 					</el-select>
@@ -55,7 +57,7 @@
 			</div>
 			<div class="co-h2-right">
 				<div
-					:class="['co-h2-r-btn', fileId ? '' : 'ca-h2-r-noActive']"
+					:class="['co-h2-r-btn', fileId && tid ? '' : 'ca-h2-r-noActive']"
 					style="background: rgba(54, 129, 252, 1)"
 					@click.stop="getReport()"
 				>
@@ -64,7 +66,7 @@
 				</div>
 
 				<div
-					:class="['co-h2-r-btn', fileId ? '' : 'ca-h2-r-noActive']"
+					:class="['co-h2-r-btn', fileId && tid ? '' : 'ca-h2-r-noActive']"
 					style="background: #ffffff"
 					@click.stop="preview()"
 				>
@@ -156,8 +158,12 @@
 			:tid="tid"
 			@shareBtn="shareBtn"
 		></sharePdf>
-		<changeCourseNameDialog :tid="tid" ref="changeCourseNameDialogRef" @success="changeCourseSuccess"/>
-		
+		<changeCourseNameDialog
+			:tid="tid"
+			ref="changeCourseNameDialogRef"
+			@success="changeCourseSuccess"
+		/>
+
 		<!-- <addNewCourseDialog
 			:courseList="optionData"
 			ref="addNewCourseDialogRef"
@@ -178,7 +184,7 @@ import { v4 as uuidv4 } from "uuid";
 // 添加课堂弹窗
 // import addNewCourseDialog from "./components/addNewCourseDialog.vue";
 //修改课程名称弹窗
-import changeCourseNameDialog from './components/changeCourseNameDialog';
+import changeCourseNameDialog from "./components/changeCourseNameDialog";
 //保存模板弹窗
 
 export default {
@@ -208,37 +214,150 @@ export default {
 				this.$refs.messageAreaRef.getData();
 				this.$refs.chatAreaRef.getData();
 				this.getFileIdId();
+
+			// 	setTimeout(()=>{
+			// 		this.$refs.messageAreaRef.init();
+			// 		this.$refs.chatAreaRef.init();
+			// 		this.tid = "";
+			// 		this.fileId = "";
+			// 		this.fileIdId = "";
+			// 	},6000)
 			});
 		},
 		addNewCourse() {
+			return new Promise((resolve,reject)=>{
+				this.addNewCourseByDefault().then(_=>{
+					resolve();
+				})
+			})
+			// var OpenCC = require("opencc-js");
+			// let converter = OpenCC.Converter({
+			// 	from: "hk",
+			// 	to: "cn",
+			// });
+			// return new Promise((resolve, reject) => {
+			// 	if (this.loading) return this.$message.info("请稍等");
+			// 	this.loading = true;
+			// 	let date = new Date();
+			// 	let month = date.getMonth() + 1;
+			// 	let day = date.getDate();
+			// 	let classroomName = `${month < 10 ? "0" + month : month}${
+			// 		day < 10 ? "0" + day : day
+			// 	}新建课堂`;
+			// 	let sum = this.optionData.filter(
+			// 		(i) => i.label.indexOf(classroomName) != -1
+			// 	).length;
+			// 	if (!sum == 0) {
+			// 		classroomName += sum;
+			// 	}
+			// 	let params = {
+			// 		tid: uuidv4(),
+			// 		name: classroomName,
+			// 		userid: this.userId,
+			// 	};
+			// 	this.ajax
+			// 		.post(
+			// 			"https://gpt4.cocorobo.cn/insert_classroom_observation_tid",
+			// 			params
+			// 		)
+			// 		.then((res) => {
+			// 			let _data = res.data.FunctionResponse;
+			// 			if (converter(_data.message) == converter("创建成功")) {
+			// 				// 设置该课堂的tid
+			// 				this.tid = params.tid;
+			// 				this.ajax
+			// 					.post("https://gpt4.cocorobo.cn/insert_classroom_observation", {
+			// 						tid: params.tid,
+			// 						type: 10,
+			// 						index: 0,
+			// 						json_data: JSON.stringify({ file_ids: "" }),
+			// 						userid: this.userId,
+			// 					})
+			// 					.then((res2) => {
+			// 						let _data2 = res2.data.FunctionResponse;
+			// 						if (converter(_data2.message) == converter("创建成功")) {
+			// 							this.loading = false;
+			// 							this.$nextTick(() => {
+			// 								this.getCourseList().then((_) => {
+			// 									this.getFileIdId();
+			// 									this.$refs.messageAreaRef.getData();
+			// 									this.$refs.chatAreaRef.getData();
+			// 									resolve();
+			// 								});
+			// 							});
+			// 						} else {
+			// 							this.$message.error("创建fileIds失败");
+			// 						}
+			// 					});
+			// 			} else if (converter(_data.message) == converter("tid重复")) {
+			// 				this.$message.error("该课堂已存在");
+			// 				this.loading = false;
+			// 			} else {
+			// 				this.$message.error("创建失败");
+			// 				this.loading = false;
+			// 			}
+			// 		});
+			// });
+		},
+		addNewCourseByDefault() {
+			// 通过用户ID获取默认的模板
+			return new Promise((resolve,reject)=>{
+				let params = {
+				uid: this.userId,
+			};
+			this.loading = true;
+			this.ajax.get(this.$store.state.api + "selectClassroomDefault", params).then((res) => {
+				let _data = res.data[0][0];
+				if (_data) {
+					this.loading = true;
+					_data.tips = JSON.parse(_data.tips);
+					let _result = [];
+					_data.tips.forEach((i) => {
+						let _obj = {
+							jsonData: i.jsonData,
+							type: i.Type,
+							index: i.tIndex,
+						};
+						_result.push(_obj);
+					});
+					this.loading = false;
+					// console.log('👇要生成的模板')
+					// console.log(_result)
+					this.addNewCourseByTemplate(_result).then(_=>{
+						resolve();
+					})
+				}else{
+					this.loading = false;
+					this.$message.error("获取模板详细为空");
+				}
+			});
+			})
+			
+		},
+		addNewCourseByTemplate(json = []) {
+			if (json.length <= 0) return;
+
+			var OpenCC = require("opencc-js");
+			let converter = OpenCC.Converter({
+				from: "hk",
+				to: "cn",
+			});
 			return new Promise((resolve, reject) => {
-				if (this.loading) return this.$message.info("请稍等");
 				this.loading = true;
-				let date = new Date();
-				let month = date.getMonth() + 1;
-				let day = date.getDate();
-				let classroomName = `${month < 10 ? "0" + month : month}${
-					day < 10 ? "0" + day : day
-				}新建课堂`;
-				let sum = this.optionData.filter(
-					(i) => i.label.indexOf(classroomName) != -1
-				).length;
-				if (!sum == 0) {
-					classroomName += sum;
-				}
+				const _newTid = uuidv4();
 				let params = {
-					tid: uuidv4(),
-					name: classroomName,
+					tid: _newTid,
 					userid: this.userId,
+					template: json,
 				};
 				this.ajax
 					.post(
-						"https://gpt4.cocorobo.cn/insert_classroom_observation_tid",
+						"https://gpt4.cocorobo.cn/insert_classroom_observation_template",
 						params
 					)
 					.then((res) => {
 						let _data = res.data.FunctionResponse;
-						if (_data.message == "创建成功") {
+						if (converter(_data.message) == converter("创建成功")) {
 							// 设置该课堂的tid
 							this.tid = params.tid;
 							this.ajax
@@ -251,7 +370,7 @@ export default {
 								})
 								.then((res2) => {
 									let _data2 = res2.data.FunctionResponse;
-									if (_data2.message == "创建成功") {
+									if (converter(_data2.message) == converter("创建成功")) {
 										this.loading = false;
 										this.$nextTick(() => {
 											this.getCourseList().then((_) => {
@@ -265,7 +384,7 @@ export default {
 										this.$message.error("创建fileIds失败");
 									}
 								});
-						} else if (_data.message == "tid重复") {
+						} else if (converter(_data.message) == converter("tid重复")) {
 							this.$message.error("该课堂已存在");
 							this.loading = false;
 						} else {
@@ -281,18 +400,18 @@ export default {
 		// 生成报告
 		getReport() {
 			if (!this.fileId) return;
-			this.$confirm("操作将覆盖原有内容,是否继续?", "提示", {
-				confirmButtonText: "确定",
-				cancelButtonText: "取消",
-				type: "warning",
-			})
-				.then(() => {
-					this.$refs.messageAreaRef.getReport();
-				})
-				.catch((e) => {
-					console.log(e)
-					console.log("取消生成报告");
-				});
+			// this.$confirm("操作将覆盖原有内容,是否继续?", "提示", {
+			// 	confirmButtonText: "确定",
+			// 	cancelButtonText: "取消",
+			// 	type: "warning",
+			// })
+			// 	.then(() => {
+			this.$refs.messageAreaRef.getReport();
+			// 	})
+			// 	.catch((e) => {
+			// 		console.log(e)
+			// 		console.log("取消生成报告");
+			// 	});
 		},
 		//预览
 		preview() {
@@ -355,13 +474,22 @@ export default {
 								type: "success",
 								message: "删除成功!",
 							});
+							this.tid = "";
+
 							// 清空tid
 							this.tid = "";
+							this.fileIdId = "";
+							this.fileId = "";
 							this.getCourseList().then((_) => {
-								if (!this.tid) return;
-								this.getFileIdId();
+								if (!this.tid){
+									this.$refs.messageAreaRef.init();
+									this.$refs.chatAreaRef.init();
+								}else{
+									this.getFileIdId();
 								this.$refs.messageAreaRef.getData();
 								this.$refs.chatAreaRef.getData();
+								}
+								
 							});
 						});
 				})
@@ -439,6 +567,10 @@ export default {
 						this.loading = false;
 						console.log(this.optionData);
 						resolve();
+					})
+					.catch((e) => {
+						console.log(e);
+						this.$message.error("获取课堂列表失败");
 					});
 			});
 		},
@@ -468,45 +600,50 @@ export default {
 			this.createTime = time;
 		},
 		// 修改课程名称
-		changeCourse(item){
+		changeCourse(item) {
 			this.$refs.changeCourseNameDialogRef.open(item);
 			// console.log(item);
 		},
 		// 修改课程名称确定
-		changeCourseSuccess(data){
+		changeCourseSuccess(data) {
 			this.loading = true;
-			if(this.tid==data.tid){
+			if (this.tid == data.tid) {
 				this.$refs.messageAreaRef.bmData.jsonData.courseName = data.name;
-				this.$refs.messageAreaRef.saveData(this.$refs.messageAreaRef.bmData).then(res=>{
-					this.loading = false;
-					this.optionData.find(i=>i.id==data.id).label=data.name
-					this.$message.success('修改成功')
-				})
-			}else{
-				this.ajax.post("https://gpt4.cocorobo.cn/get_classroom_observation_new",{
-				tid:data.tid,
-				type:0
-			}).then(res=>{
-				let _data = res.data.FunctionResponse.result;
-				_data = JSON.parse(_data);
-				let _bmData = _data.find(i=>i.tIndex==0);
-				_bmData.jsonData = JSON.parse(_bmData.jsonData);
-				_bmData.jsonData.courseName = data.name;
-				this.$refs.messageAreaRef.saveData(_bmData).then(res=>{
-					this.loading = false;
-					this.optionData.find(i=>i.id==data.id).label=data.name
-					this.$message.success('修改成功')
-				})
-			}).catch(e=>{
-				console.log(e);
-				this.$message.error('修改失败')
-				this.loading = false;
-			})
+				this.$refs.messageAreaRef
+					.saveData(this.$refs.messageAreaRef.bmData)
+					.then((res) => {
+						this.loading = false;
+						this.optionData.find((i) => i.id == data.id).label = data.name;
+						this.$message.success("修改成功");
+					});
+			} else {
+				this.ajax
+					.post("https://gpt4.cocorobo.cn/get_classroom_observation_new", {
+						tid: data.tid,
+						type: 0,
+					})
+					.then((res) => {
+						let _data = res.data.FunctionResponse.result;
+						_data = JSON.parse(_data);
+						let _bmData = _data.find((i) => i.tIndex == 0);
+						_bmData.jsonData = JSON.parse(_bmData.jsonData);
+						_bmData.jsonData.courseName = data.name;
+						this.$refs.messageAreaRef.saveData(_bmData).then((res) => {
+							this.loading = false;
+							this.optionData.find((i) => i.id == data.id).label = data.name;
+							this.$message.success("修改成功");
+						});
+					})
+					.catch((e) => {
+						console.log(e);
+						this.$message.error("修改失败");
+						this.loading = false;
+					});
 			}
 		},
 		//保存词频词汇分析
-		saveWordFrequency({_sentence=0,_words=0}){
-			this.$refs.messageAreaRef.saveWordFrequency({_sentence,_words})
+		saveWordFrequency({ _sentence = 0, _words = 0 }) {
+			this.$refs.messageAreaRef.saveWordFrequency({ _sentence, _words });
 		},
 	},
 	mounted() {
@@ -767,7 +904,7 @@ export default {
 	justify-content: space-between;
 }
 
-.controlsBox{
+.controlsBox {
 	display: flex;
 	align-items: center;
 	width: auto;
@@ -775,17 +912,18 @@ export default {
 	display: none;
 }
 
-.selectBox:hover>.controlsBox{
+.selectBox:hover > .controlsBox {
 	display: flex;
 }
 
-.changeSelect{
+.changeSelect {
 	width: 16px;
 	height: 16px;
 	/* display: none; */
 	align-items: center;
 	justify-content: center;
-	background: url("../../../assets/icon/classroomObservation/editIcon.svg") no-repeat;
+	background: url("../../../assets/icon/classroomObservation/editIcon.svg")
+		no-repeat;
 	background-size: 100% 100%;
 	box-sizing: border-box;
 	margin-right: 10px;

+ 49 - 1
src/components/pages/components/studentReport.vue

@@ -1,6 +1,10 @@
 <template>
   <div style="width: 100%; height: 100%">
-    <div class="sr_head">学生成长报告</div>
+    <div class="sr_head">
+      学生成长报告
+      <el-button type="primary" size="small" @click="downloadFile('https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/student01-%E5%AD%A6%E7%94%9F%E6%88%90%E9%95%BF%E6%8A%A5%E5%91%8A1719315423787.pdf');">导出报告</el-button>
+      
+    </div>
     <div class="sr_body">
       <div class="sr_box">
         <div class="sr_first">
@@ -74,6 +78,50 @@ export default {
       this.scoid = this.oid;
     },
   },
+  methods: {
+    downloadFile(url){
+      var credentials = {
+        accessKeyId: "AKIATLPEDU37QV5CHLMH",
+        secretAccessKey: "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",
+      }; //秘钥形式的登录上传
+      window.AWS.config.update(credentials);
+      window.AWS.config.region = "cn-northwest-1"; //设置区域
+      let url2 = url;
+      let _url2 = "";
+      if (
+        url2.indexOf("https://view.officeapps.live.com/op/view.aspx?src=") != -1
+      ) {
+        _url2 = url2.split(
+          "https://view.officeapps.live.com/op/view.aspx?src="
+        )[1];
+      } else {
+        _url2 = url2;
+      }
+      let _this = this;
+
+      _this.downLoading = true
+      var s3 = new window.AWS.S3({ params: { Bucket: "ccrb" } });
+      let name = decodeURIComponent(_url2.split("https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/")[1])
+      var params = {
+        Bucket: "ccrb",
+        Key: name
+      };
+      s3.getObject(params, function (err, data) {
+        _this.downLoading = false
+        if (err) console.log(err, err.stack); // an error occurred
+        else {
+          let url = window.URL.createObjectURL(new Blob([data.Body]));
+          let a = document.createElement("a");
+          a.name = 'student01-学生成长报告.pdf';
+          a.href = url;
+          a.download = 'student01-学生成长报告.pdf';
+          a.click();
+          console.log(data); 
+        }          // sxuccessful response
+
+      });
+    },
+  },
   created() {
     this.userid = this.checkStudent;
     this.courseid = this.checkCourse;

+ 6 - 1
src/components/pages/easy/addCourse.vue

@@ -4658,6 +4658,11 @@ import sourceDialog from "../teacherSource/dialog.vue";
 import interVideo from "../interVideo/index.vue";
 import englishRight from "./commpont/englishRight.vue";
 import EnglishVoice from '../EnglishVoice/index.vue'
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 
 export default {
   components: {
@@ -4894,7 +4899,7 @@ export default {
       ppage: 1,
       imageList: [],
       heightPx: '100%',
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
       oldIndex: 0,
       oldData: null,
       newIndex: "",

+ 6 - 1
src/components/pages/newCourse/addCourse.vue

@@ -7375,6 +7375,11 @@ import interVideo from "../interVideo/index.vue";
 import englishRight from "../components/englishRight.vue";
 import evaBox from "../evaBox/index.vue";
 import EnglishVoice from "../EnglishVoice/index.vue";
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 
 export default {
   components: {
@@ -7625,7 +7630,7 @@ export default {
       imageloading: false,
       searchImageValue: "",
       ppage: 1,
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
       oldIndex: 0,
       dragType: "",
       oldUnitIndex: 0,

+ 6 - 1
src/components/pages/student/addCourse.vue

@@ -2387,6 +2387,11 @@ import * as imageConversion from "image-conversion";
 import courseDetailVue from "../courseDetail.vue";
 import sourceDialog from "../teacherSource/dialog.vue";
 import { tools as toolsData } from "../../../common/tools.js";
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 
 export default {
   components: {
@@ -2701,7 +2706,7 @@ export default {
       newIndex: "",
       checkUnitIndex: 0,
       isdrag: '',
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
     };
   },
   directives: {

+ 6 - 1
src/components/pages/synergyCourse/addCourse.vue

@@ -2706,6 +2706,11 @@ import weilaiData from "../components/weilai.js";
 import sourceDialog from "../teacherSource/dialog.vue";
 import interVideo from "../interVideo/index.vue";
 import groupBox from "./group/group.vue"
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 
 export default {
   components: {
@@ -2940,7 +2945,7 @@ export default {
       ppage: 1,
       imageList: [],
       heightPx: '100%',
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
       pageSize: 20,
       total: 0,
       page: 0,

+ 6 - 1
src/components/pages/task/addCourse.vue

@@ -8226,6 +8226,11 @@ import weilaiData from "../components/weilai.js";
 import sourceDialog from "../teacherSource/dialog.vue";
 import interVideo from "../interVideo/index.vue";
 import englishRight from "./commpont/englishRight.vue";
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 
 export default {
   components: {
@@ -8460,7 +8465,7 @@ export default {
       ppage: 1,
       imageList: [],
       heightPx: "100%",
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
       oldIndex: 0,
       oldData: null,
       newIndex: "",

+ 24 - 3
src/components/pages/test/check/index.vue

@@ -63,7 +63,7 @@
           </div>
           <div class="search_nav" v-if="isDesktop">
             <div class="right">
-              <span :class="{ active: stype == 1 }" @click="checkDataType(1)">按题目查看</span>
+              <span :class="{ active: stype == 1 }" @click="checkDataType(1)" v-if="!peopleId">按题目查看</span>
               <span :class="{ active: stype == 2 }" @click="checkDataType(2)">按人员查看</span>
               <span :class="{ active: stype == 3 }" @click="checkDataType(3)" v-show="false">按数量查看</span>
             </div>
@@ -104,8 +104,8 @@
                 </el-select> -->
               </div>
               <div style="margin-right: 10px;position: relative;" v-if="stype == 2 || stype == 3">
-                <el-input v-model="courseName" class="student_input" placeholder="请输入需要搜索的姓名"></el-input>
-                <span class="serach_icon" @click="searchCourse"></span>
+                <el-input v-model="courseName" class="student_input" :disabled="!(!peopleId)" placeholder="请输入需要搜索的姓名"></el-input>
+                <span class="serach_icon" @click="searchCourse" ></span>
               </div>
               <div class="btnA" v-if="stype == 1 && !pdfLoading" @click="exportPDF">导出PDF</div>
               <div class="btnA" v-if="stype == 2" @mouseenter="btnDisplay = true" @mouseleave="btnDisplay = false">
@@ -846,6 +846,7 @@ export default {
       role: this.$route.query.role,
       cid: this.$route.query.cid,
       isN: this.$route.query.isN,
+      peopleId: this.$route.query.peopleId,
       screenWidth: window.innerWidth,
       isDesktop: false,
       title: "",
@@ -2016,12 +2017,32 @@ export default {
           });
       });
 		},
+    getUserInfo() {
+      let params = {
+        uid: this.peopleId,
+      };
+      this.ajax
+        .get(this.$store.state.api + "selectTestUser", params)
+        .then((res) => {
+          console.log('111111111111111111111',res.data[0][0]);
+          // 用于存储归类后的数据的对象
+          this.checkDataType(2)
+          this.courseName = res.data[0][0].name
+          this.searchCourse()
+        })
+        .catch((err) => {
+          console.error(err);
+        });
+    },
   },
   beforeDestroy() {
     document.getElementsByTagName('html')[0].style.overflow = '';
     window.removeEventListener("resize", this.checkScreenSize);
   },
   mounted() {
+    if(this.peopleId){
+      this.getUserInfo();
+    }
     this.checkScreenSize();
     window.addEventListener("resize", this.checkScreenSize);
     document.getElementsByTagName('html')[0].scrollTop = 0

+ 1 - 1
src/components/pages/test/examine/conpoments/personPage.vue

@@ -73,7 +73,7 @@
 export default {
   props: {
     pType: {
-      //0专任教师 1班主任
+      //2专任教师 1班主任
       type: Number,
       default: 0
     }

ファイルの差分が大きいため隠しています
+ 1032 - 563
src/components/pages/test/examine/conpoments/targetPage.vue


+ 4 - 3
src/components/pages/test/examine/index.vue

@@ -4,8 +4,8 @@
       <div class="teaLis">
         <div
           class="teal"
-          @click="cutPage(0)"
-          :class="[pType == 0 ? 'Tbor' : '']"
+          @click="cutPage(2)"
+          :class="[pType == 2 ? 'Tbor' : '']"
         >
           专任教师
         </div>
@@ -47,7 +47,7 @@ export default {
   },
   data() {
     return {
-      pType: 0,
+      pType: 2,
       cutTable: 0,
       cutTabOpts: [
         {
@@ -72,6 +72,7 @@ export default {
 <style scoped>
 .testExamine {
   width: 100%;
+  min-width: calc(150px * 10);
   min-height: 100%;
   padding: 10px;
   box-sizing: border-box;

+ 665 - 312
src/components/pages/testPerson/examine/index.vue

@@ -1,381 +1,734 @@
 <template>
-  <div class="all">
-    <div class="top">
-      <div class="top_left">
-        <div class="teacher">专任教师</div>
-        <div class="headteacher">班主任考核</div>
+  <div class="testPersonExamine">
+    <div class="testTit">
+      <div class="teaLis">
+        <div
+          class="teal"
+          @click="cutPage(2)"
+          :class="[pType == 2 ? 'Tbor' : '']"
+        >
+          专任教师
+        </div>
+        <div
+          class="teal"
+          @click="cutPage(1)"
+          :class="[pType == 1 ? 'Tbor' : '']"
+        >
+          班主任考核
+        </div>
       </div>
+      <div style="margin-right: 30px;display: flex;">
+        <el-button
+          type="primary"
+          size="mini"
+          style="margin-right: 15px;"
+          @click="saveTab"
+          v-if="allData.type == 1"
+          >保存</el-button
+        >
+        <el-button
+          v-if="!allData.rjson"
+          type="primary"
+          size="mini"
+          @click="Submit"
+          >提交</el-button
+        >
+      </div>
+    </div>
 
-      <div class="top_right">
-        <span style="margin-left:20px ;">审核进度:3/5</span>
-        <span style="margin-left:10px ;">认定分数:35.5分</span>
-        <div class="btn">
-          <div class="submit">提交</div>
-          <div class="save" style="margin-right: 15px;">保存</div>
+    <div v-if="pType == 2" v-loading="tabLoad">
+      <div class="sBox_table">
+        <div class="table_title">
+          <div>一级指标</div>
+          <div>二级指标</div>
+          <div>评价方法</div>
+          <div>分值</div>
+          <div>自评</div>
+          <div>自评概述</div>
+          <div>数据来源</div>
+          <div>认定</div>
+          <div>认定概述</div>
+        </div>
+        <div class="table_Content" v-for="item in PageBaseData" :key="item.id">
+          <div class="twoCol">
+            <div class="ColTit">{{ item.name }}</div>
+            <div class="ColCon">
+              <div class="twoCon" v-for="k in item.children" :key="k.id">
+                <div>{{ k.name }}</div>
+                <div style="padding: 10px;box-sizing: border-box;">
+                  {{ k.evaMethod }}
+                </div>
+                <div>{{ k.score }}</div>
+                <div>
+                  <el-input-number
+                    v-model="k.sco1"
+                    :controls="false"
+                    :min="0"
+                    :max="k.score"
+                  ></el-input-number>
+                </div>
+                <div class="tArea">
+                  <textarea v-model.trim="k.selfSummary" />
+                </div>
+                <div>
+                  <div v-if="!k.testid.test.length">/</div>
+                  <div v-else style="padding-top: 10px;">
+                    <!-- {{ reverseString(k.testid.test) }} -->
+                    <div
+                      v-for="(item2, index) in k.testid.test"
+                      :key="item2.courseId"
+                      class="orgData"
+                    >
+                      <div @click="lookPrize(item2.courseId)">
+                        {{ item2.title }}:{{ item2.num }}份
+                      </div>
+                      <div
+                        style="color: black;"
+                        @click="goFillIn(item2.courseId)"
+                      >
+                        去填写
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div style="display: flex;justify-content: center;">
+                  {{ k.sco2 }}
+                </div>
+                <div style="display: flex;justify-content: center;">
+                  {{ k.cogSum }}
+                </div>
+              </div>
+            </div>
+          </div>
         </div>
       </div>
-
     </div>
-    <div class="main">
-      <table>
-        <tr>
-          <th style="width: 122px;">一级指标</th>
-          <th style="width: 184px;">二级指标</th>
-          <th style="width: 122px;">评价方法</th>
-          <th style="width: 82px;">分值</th>
-          <th style="width: 82px;">自评</th>
-          <th style="width: 123px;">自评概述</th>
-          <th style="width: 203px;">数据来源</th>
-          <th style="width: 103px;">认定</th>
-          <th style="width: 103px;">认定概述</th>
-
-        </tr>
-        <tr>
-          <td rowspan="4" style="height: 318px;"></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick"></td>
-          <td></td>
-          <td></td>
-        </tr>
-        <tr>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick"></td>
-          <td></td>
-          <td></td>
-
-        </tr>
-        <tr>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick"></td>
-          <td></td>
-          <td></td>
-
-        </tr>
-        <tr>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick"></td>
-          <td></td>
-          <td></td>
-
-        </tr>
-        <tr>
-          <td rowspan="3" style="height: 244px;"></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick"></td>
-          <td></td>
-          <td></td>
-
-        </tr>
-        <tr>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick"></td>
-          <td></td>
-          <td></td>
-
-        </tr>
-        <tr>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td class="dataFrom" @click="handleClick">单元格 7-6</td>
-          <td></td>
-          <td></td>
-
-
-        </tr>
-
-
-      </table>
-    </div>
-    <!-- 弹窗 -->
-    <div v-if="showModal" class="modal">
-      <div class="modal_top">
-        <div>数据来源</div>
-        <div style="margin-right:25px" @click="closeModal">关闭</div>
-      </div>
-      <div class="modal_top">
-        <div style="display: flex;">
-          <div>表单名称</div>
-          <div style="margin-left:15px">创建者</div>
-        </div>
 
-        <div class="more">再填一份</div>
+    <div v-if="pType == 1" v-loading="tabLoad">
+      <div class="sBox_table">
+        <div class="table_title2">
+          <div>一级指标</div>
+          <div>二级指标</div>
+          <div>评价方法</div>
+          <div>分值</div>
+          <div>自评</div>
+          <div>自评概述</div>
+          <div>数据来源</div>
+          <div>认定</div>
+          <div>认定概述</div>
+        </div>
+        <div class="table_Content2" v-for="item in PageBaseData" :key="item.id">
+          <div class="twoCol">
+            <div class="ColTit">{{ item.name }}</div>
+            <div class="ColCon">
+              <div class="twoCon" v-for="k in item.children" :key="k.id">
+                <div>{{ k.name }}</div>
+                <div>{{ k.evaMethod }}</div>
+                <div>{{ k.score }}</div>
+                <div>
+                  <el-input-number
+                    v-model="k.sco1"
+                    :controls="false"
+                    :min="0"
+                    :max="k.score"
+                  ></el-input-number>
+                </div>
+                <div class="tArea">
+                  <textarea v-model.trim="k.selfSummary" />
+                </div>
+                <div>
+                  <div v-if="!k.testid.test.length">/</div>
+                  <div v-else style="padding-top: 10px;">
+                    <div
+                      v-for="(item2, index) in k.testid.test"
+                      :key="item2.courseId"
+                      class="orgData"
+                    >
+                      <div @click="lookPrize(item2.courseId)">
+                        {{ item2.title }}:{{ item2.num }}份
+                      </div>
+                      <div
+                        style="color: black;"
+                        @click="goFillIn(item2.courseId)"
+                      >
+                        去填写
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div>{{ k.sco2 }}</div>
+                <div>{{ k.cogSum }}</div>
+              </div>
+            </div>
+          </div>
+        </div>
       </div>
-
-      <table style="width: 1950px;height: 616px;">
-        <thead>
-          <tr>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">序号</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">提交人</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">提交时间</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">学年</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">获奖内容</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">获奖级别</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">获奖名次</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">证书或相关资料</th>
-            <th style="background-color:rgb(241, 241, 241);color:rgb(156, 159, 165)">操作</th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td>
-              <el-button size="mini">编辑</el-button>
-              <el-button size="mini" type="danger">删除</el-button>
-            </td>
-          </tr>
-          <tr>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td>
-              <el-button size="mini">编辑</el-button>
-              <el-button size="mini" type="danger">删除</el-button>
-            </td>
-          </tr>
-          <tr>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td>
-              <el-button size="mini">编辑</el-button>
-              <el-button size="mini" type="danger">删除</el-button>
-            </td>
-          </tr>
-          <tr>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td>
-              <el-button size="mini">编辑</el-button>
-              <el-button size="mini" type="danger">删除</el-button>
-            </td>
-          </tr>
-          <tr>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td>
-              <el-button size="mini">编辑</el-button>
-              <el-button size="mini" type="danger">删除</el-button>
-            </td>
-          </tr>
-          <tr>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td></td>
-            <td>
-              <el-button size="mini">编辑</el-button>
-              <el-button size="mini" type="danger">删除</el-button>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-
     </div>
-  </div>
-
 
+    <!-- 点击数据来源 -->
+    <el-dialog
+      title=""
+      :visible.sync="diaIframe"
+      :append-to-body="true"
+      width="95%"
+      :before-close="handleClose"
+      class="dialog_diy"
+    >
+      <div style="height: 100%;">
+        <iframe
+          ref="viframe"
+          style="width: 100%; height: 99%; border: none"
+          :src="ifmUrl"
+        ></iframe>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="diaIframe = false">关 闭</el-button>
+      </span>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
 export default {
   data() {
     return {
-      showModal: false,
-
+      pType: 2,
+      allData: {
+        type: 1,
+        rjson: ""
+      },
+      // 页面填写数据
+      tableJsonCon: [],
+      // 页面基础ui
+      PageBaseData: [],
+      tabLoad: false, //表格加载状态
+      userid: this.$route.query.userid, //用户id
+      oid: this.$route.query.oid, //学校id
+      org: this.$route.query.org, //组织id
+      role: this.$route.query.role,
+      ifmUrl: "", //数据来源地址
+      diaIframe: false //数据来源弹框
     };
   },
+  watch: {
+    pType(newVal, oldVal) {
+      this.getPageBase();
+    }
+  },
+  computed: {},
+  mounted() {
+    this.getPageBase();
+    // console.log(JSON.stringify(this.TeaTabJson));
+  },
   methods: {
-    handleClick() {
-      this.showModal = true;
+    goFillIn(val) {
+      this.$router.push(
+        `/doTest?cid=${val}&userid=${this.userid}&oid=${this.oid}&org=${this.org}&type=3&role=${this.role}`
+      );
+      // this.ifmUrl = `https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/#/checkToTest?cid=${val}&oid=${this.oid}&org=${this.org}&type=2&role=0&peopleId=${this.userid}`;
+      // this.ifmUrl = `https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/#/test?userid=${this.userid}&oid=45facc0a-1211-11ec-80ad-005056b86db5&org=&role=0`;
+      // this.diaIframe = true;
     },
-    closeModal() {
-      this.showModal = false;
+    // 提交
+    Submit() {
+      if (this.allData.type == 2) {
+        this.$message({
+          type: "info",
+          message: "您已提交过,请勿重复提交"
+        });
+        return;
+      }
+
+      for (const e of this.PageBaseData) {
+        for (const k of e.children) {
+          if (k.testid.test.length > 0) {
+            k.testid.test = k.testid.test.map(item => item.courseId);
+          }
+        }
+      }
+
+      this.$confirm("确认提交?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: " info"
+      })
+        .then(() => {
+          let params = [
+            {
+              uid: this.userid,
+              oid: this.oid,
+              org: this.org,
+              type: this.pType,
+              json: JSON.stringify(this.PageBaseData),
+              ttype: 2
+            }
+          ];
+          this.ajax
+            .post(this.$store.state.api + "addTestExamineWorks", params)
+            .then(res => {
+              this.getData();
+            })
+            .catch(error => {
+              console.log(error);
+            });
+        })
+        .catch(() => {
+          this.handleData();
+
+          this.$message({
+            type: "info",
+            message: "已取消提交"
+          });
+        });
     },
-
-  },
+    // 保存
+    saveTab() {
+      for (const e of this.PageBaseData) {
+        for (const k of e.children) {
+          if (k.testid.test.length > 0) {
+            k.testid.test = k.testid.test.map(item => item.courseId);
+          }
+        }
+      }
+      this.$confirm("确认保存?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: " info"
+      })
+        .then(() => {
+          let params = [
+            {
+              uid: this.userid,
+              oid: this.oid,
+              org: this.org,
+              type: this.pType,
+              json: JSON.stringify(this.PageBaseData),
+              ttype: 1
+            }
+          ];
+          this.ajax
+            .post(this.$store.state.api + "addTestExamineWorks", params)
+            .then(res => {
+              console.log("addTestExamineWorks", res);
+              this.getData();
+              // console.log();
+              // console.log("resresresres", res.data[0]);
+            })
+            .catch(error => {
+              console.log(error);
+            });
+        })
+        .catch(() => {
+          this.handleData();
+
+          this.$message({
+            type: "info",
+            message: "已取消保存"
+          });
+        });
+    },
+    // 切换专任,班主任
+    cutPage(e) {
+      this.pType = e;
+    },
+    // 获取页面ui
+    getData() {
+      this.tabLoad = true;
+      let params = {
+        uid: this.userid,
+        type: this.pType
+      };
+      this.ajax
+        .get(this.$store.state.api + "getTestExamineByUserId", params)
+        .then(res => {
+          console.log("getTestExamineByUserId", res);
+
+          if (res.data[0].length > 0) {
+            this.allData = res.data[0][0];
+            let val = JSON.parse(res.data[0][0].json);
+
+            this.PageBaseData.forEach(e => {
+              val.forEach(i => {
+                if (e.id == i.id) {
+                  e.name = i.name;
+                  e.children.forEach(a => {
+                    i.children.forEach(b => {
+                      if (a.id == b.id) {
+                        a.name = b.name;
+                        a.score = b.score;
+                        a.sco1 = b.sco1;
+                        a.sco2 = b.sco2;
+                        a.evaStandard = b.evaStandard;
+                        a.evaMethod = b.evaMethod;
+                        a.cogSum = b.cogSum;
+                        a.selfSummary = b.selfSummary;
+                        a.dep = b.dep;
+                        a.type = b.type;
+                        a.testid = b.testid;
+                      }
+                    });
+                  });
+                }
+              });
+            });
+
+            this.handleData();
+            return (this.tabLoad = false);
+          } else {
+            this.allData.type = 1;
+            this.allData.rjson = "";
+            this.handleData();
+            this.tabLoad = false;
+          }
+          // this.$forceUpdate();
+          //  else {
+          //   this.allData.type = 1;
+          //   this.getPageBase();
+          //   this.tabLoad = false;
+          // }
+        })
+        .catch(error => {
+          console.log(error);
+        });
+    },
+    // 获取页面基础ui信息
+    getPageBase() {
+      let params = {
+        typ: this.pType,
+        org: this.org,
+        oid: this.oid
+      };
+      this.ajax
+        .get(this.$store.state.api + "selectTestExamineBase", params)
+        .then(res => {
+          // console.log("resresresres", res.data[0]);
+          // this.allData = res.data[0][0];
+
+          console.log("selectTestExamineBase", res.data[0][0]);
+          this.PageBaseData = JSON.parse(res.data[0][0].json);
+          // 先获取基础模板,然后再获取用户又没有填写过,填写过就开始循环赋值给基础模板,最后提交基础模板
+          this.getData();
+
+          // this.handleData();
+        })
+        .catch(error => {
+          console.log(error);
+        });
+    },
+    async handleData() {
+      for (const e of this.PageBaseData) {
+        for (const k of e.children) {
+          if (k.testid.test.length > 0) {
+            k.testid.test = await this.computedTest(k.testid.test);
+          }
+        }
+      }
+    },
+    computedTest(val) {
+      let params = [
+        {
+          uid: this.uid,
+          testId: val.join(",")
+        }
+      ];
+      return new Promise(resolve => {
+        this.ajax
+          .post(this.$store.state.api + "selectExamineTestName", params)
+          .then(res => {
+            resolve(res.data[0]);
+          })
+          .catch(error => {
+            console.log(error);
+          });
+      });
+    },
+    // 查看数据来源
+    lookPrize(val) {
+      // return;
+      this.ifmUrl = `https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/#/checkToTest?cid=${val}&oid=${this.oid}&org=${this.org}&type=2&role=0&peopleId=${this.userid}`;
+      // this.ifmUrl = `https://beta.pbl.cocorobo.cn/pbl-teacher-table/dist/#/test?userid=${this.userid}&oid=45facc0a-1211-11ec-80ad-005056b86db5&org=&role=0`;
+      this.diaIframe = true;
+    },
+    // 关闭弹框
+    handleClose(done) {
+      done();
+    }
+  }
 };
 </script>
 
 <style scoped>
-.top {
+.testPersonExamine {
+  width: 100%;
+  min-width: calc(100px * 10);
+  min-height: 100%;
+  padding: 10px;
+  box-sizing: border-box;
+  background-color: #fff;
+}
+.tArea {
+  box-sizing: border-box;
+  padding: 5px;
+}
+.testPersonExamine > .testTit {
+  height: 100px;
   display: flex;
   justify-content: space-between;
   align-items: center;
+}
+.teaLis {
+  display: flex;
+}
+.teal {
+  padding: 10px 20px;
+  cursor: pointer;
+}
+.Tbor {
+  border-bottom: 2px rgba(54, 129, 252, 1) solid;
+  font-weight: 600;
+}
+.testCon {
+  box-sizing: border-box;
+  padding: 20px;
+}
 
+.orgData {
+  cursor: pointer;
+  color: #528df6;
+  margin-bottom: 10px;
 }
 
-.top_left {
+.diaScoreTop {
   display: flex;
+  justify-content: space-between;
+  height: 60px;
 }
 
-.top_right {
+.diaScoreLeft {
   display: flex;
+  justify-content: space-between;
   align-items: center;
 }
 
-.teacher {
-  width: 96px;
-  height: 44px;
-  line-height: 44px;
-  padding: 8px;
-  background-color: #FFFFFF;
-  font-size: 20px;
-  font-weight: 500;
-  border-bottom: 3px solid rgba(54, 129, 252, 1);
-  text-align: center;
+.diaScoreLeft > div {
+  margin-right: 30px;
+}
 
+.diaScoreRight {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
 }
 
-.headteacher {
-  width: 116px;
-  height: 44px;
-  line-height: 44px;
-  font-size: 20px;
-  font-weight: 400;
-  background-color: #FFFFFF;
-  text-align: center;
-  padding: 8px;
-  color: #ccc;
-  margin-left: 20px;
+.TabBtn {
+  cursor: pointer;
+  color: #528df6;
 }
 
-span {
-  font-size: 20px;
-  margin-right: 15px;
+.sBox_table {
+  width: 100%;
+  min-width: calc(110px * 9);
+  margin: 0 auto;
+  /* min-width: 1520px; */
+  font-size: 14px;
 }
 
-.btn {
-  margin-right: 20px;
+.table_title {
+  width: 100%;
+  min-width: calc(110px * 9);
+  height: 50px;
+  background: #e0eafb;
+  border: 1px solid #d5d8df;
   display: flex;
-  flex-direction: row-reverse;
-  cursor: pointer;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
 }
 
-.submit,
-.save {
-  width: 48px;
-  height: 28px;
-  background: rgba(54, 129, 252, 1);
-  border-radius: 6px;
+.table_title > div {
+  width: calc(100% / 9);
+  min-width: 110px;
   text-align: center;
-  line-height: 28px;
-  color: #fff;
+  height: 100%;
+  line-height: 50px;
+  border-right: 1px solid #d5d8df;
+}
+
+.table_title2 {
+  width: 100%;
+  min-width: calc(110px * 8);
+  height: 50px;
+  background: #e0eafb;
+  border: 1px solid #d5d8df;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  align-items: center;
+}
+.table_title2 > div {
+  width: calc(100% / 8);
+  min-width: 110px;
+  text-align: center;
+  height: 100%;
+  line-height: 50px;
+  border-right: 1px solid #d5d8df;
+}
+
+.table_title > div:last-child {
+  border: none;
 }
 
-.main {
-  margin-top: 34px;
+.table_Content {
+  width: 100%;
+  min-width: calc(110px * 9);
+  border: 1px solid #d5d8df;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  text-align: center;
+  align-items: center;
+}
+.table_Content2 {
+  width: 100%;
+  min-width: calc(110px * 8);
+  border: 1px solid #d5d8df;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  text-align: center;
+  align-items: center;
 }
 
-table {
+.twoCol {
   width: 100%;
-  border-collapse: collapse;
+  display: flex;
 }
 
-th,
-td {
-  border: 1px solid gray;
+.ColTit {
+  width: calc(100% / 9);
+  min-width: 110px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.ColTit2 {
+  width: calc(100% / 8);
+  min-width: 110px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.twoCon {
+  display: flex;
+}
+.twoCon > div >>> .el-input-number {
+  height: 100% !important;
+}
+.twoCon > div >>> .el-input {
+  height: 100% !important;
+}
+.twoCon > div > input {
+  border: none;
+  width: 100%;
+  height: 100%;
+  outline-style: none;
   text-align: center;
-  padding: 8px;
-  background-color: #fff;
+}
+.twoCon {
+  display: flex;
+}
+.twoCon > div > textarea {
+  border: none;
+  width: 100%;
+  height: 100%;
+  resize: none;
+  outline-style: none;
+}
+/* 取消[type='number']的input的上下箭头 */
+input::-webkit-inner-spin-button {
+  -webkit-appearance: none !important;
+}
 
+input::-webkit-outer-spin-button {
+  -webkit-appearance: none !important;
 }
 
-.dataFrom {
-  color: rgba(0, 32, 228, 1);
-  cursor: pointer;
+input[type="number"] {
+  -moz-appearance: textfield;
+}
 
+.twoCon > div {
+  width: calc(100% / 8);
+  /* min-width: 110px; */
+  min-height: 50px;
+  /* line-height: 50px; */
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-left: 1px #ccc solid;
+  border-bottom: 1px #ccc solid;
+}
+.twoCon > div >>> .el-input__inner {
+  height: 100%;
+  border: none;
+  padding-left: 15px;
+  padding-right: 15px;
+}
+.twoCon2 {
+  display: flex;
+}
+.twoCon2 > div {
+  width: calc(100% / 7);
+  min-width: 110px;
+  min-height: 50px;
+  /* line-height: 50px; */
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-left: 1px #ccc solid;
+  border-bottom: 1px #ccc solid;
 }
 
-.modal {
-  position: fixed;
-  top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
-  background-color: white;
+.ColCon {
+  flex: 1;
+}
 
-  padding: 20px;
-  border-radius: 5px;
-  box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.2), 0px 4px 10px rgba(0, 0, 0, 0.1);
-
-  .modal_top {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 15px;
-    margin-top: 15px;
-    font-size: 22px;
-    cursor: pointer;
-  }
+.dialog_diy >>> .el-dialog {
+  height: 95%;
+  margin: 0 auto !important;
+  margin-top: 20px !important;
+  overflow: hidden;
 }
 
-.more {
-  background-color: rgb(54, 129, 252);
+.dialog_diy >>> .el-dialog__header {
+  background: #454545 !important;
+  padding: 25px 20px;
+}
+
+.dialog_diy >>> .el-dialog__body {
+  height: calc(100% - 50px);
+  box-sizing: border-box;
+  padding: 0px;
+}
+
+.dialog_diy >>> .el-dialog__title {
   color: #fff;
-  text-align: center;
-  width: 80px;
-  height: 40px;
-  line-height: 40px;
-  padding: 8px;
-  font-size: 17px
+}
+
+.dialog_diy >>> .el-dialog__headerbtn {
+  top: 19px;
+}
+
+.dialog_diy >>> .el-dialog__headerbtn .el-dialog__close {
+  color: #fff;
+}
+
+.dialog_diy >>> .el-dialog__headerbtn .el-dialog__close:hover {
+  color: #fff;
+}
+
+.dialog_diy >>> .el-dialog__body,
+.dialog_diy >>> .el-dialog__footer {
+  background: #fafafa;
 }
 </style>

+ 26 - 8
src/components/pages/testPerson/test/test.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="i_body_box">
         <div class="check_nav">
-            <div class="nav all" v-show="true" :class="{ active: type == '1' }" @click="checkType('1')">
+            <div class="nav all" v-show="this.ExamineBase.length > 0" :class="{ active: type == '1' }" @click="checkType('1')">
                 年度考核
             </div>
             <div class="nav all" :class="{ active: type == '' }" @click="checkType('')">
@@ -57,7 +57,7 @@
                         <div class="test" v-for="(test, index) in item.array" :key="test.id">
                             <div class="time">
                                 <span>提交记录{{item.array.length - index}}</span>
-                            </div> 
+                            </div>
                             <!-- <img @click="deleteTest(test.id)" class="delete"
                                 src="../../../../assets/icon/test/delete.png" alt="" /> -->
                             <div class="utime">
@@ -92,7 +92,7 @@
                                 <el-tooltip :content="course.title+'-'+course.username" placement="top" effect="dark">
                                     <span>{{ course.title }}-{{ course.username }}</span>
                                 </el-tooltip>
-                            </div> 
+                            </div>
                             <div class="finishBox" :class="{is: course.array.length}">
                                 <span class="finish"></span>
                                 <span v-if="course.array.length">已评分</span>
@@ -132,6 +132,7 @@ export default {
     data() {
         return {
             type: "",
+            ExamineBase: [],
             typeArray: [],
             typeArrayCheck: [],
             worksArray: [],
@@ -268,6 +269,22 @@ export default {
         }
     },
     methods: {
+        getPageBase() {
+            let params = {
+                typ: 1,
+                org: this.org,
+                oid: this.oid
+            };
+            this.ajax
+                .get(this.$store.state.api + "selectTestExamineBase", params)
+                .then(res => {
+                    this.ExamineBase = res.data[0]
+                    // console.log("selectTestExamineBase", res.data);
+                })
+                .catch(error => {
+                    console.log(error);
+                });
+        },
         isDeadlinePassed(deadline) {
             let _line = new Date(deadline)
             const currentDate = new Date();
@@ -481,7 +498,7 @@ export default {
                     course.courseid +
                     "&role=" +
                     this.role
-                ); 
+                );
             }
         },
         copyTest(tid) {
@@ -544,7 +561,7 @@ export default {
                                 if (
                                     item2.ttype == 1 &&
                                     item2.type == 6 &&
-                                    item2.json 
+                                    item2.json
                                 ) {
                                     courseJson = item2.json
                                     break s;
@@ -562,7 +579,7 @@ export default {
                 } else if (
                     el.ttype == 1 &&
                     el.type == 6 &&
-                    el.json 
+                    el.json
                 ) {
                     courseJson = el.json
                                     break s;
@@ -621,6 +638,7 @@ export default {
     },
     mounted() {
         this.selectTestType(1);
+        this.getPageBase()
     },
     activated(){
         console.log('testperson',1111111111111111111111);
@@ -855,7 +873,7 @@ export default {
     align-items: center;
     padding: 0 15px;
     cursor: pointer;
-		
+
 }
 
 .test_panel_title>.time>span+span {
@@ -1045,7 +1063,7 @@ export default {
     margin-left: 15px;
 }
 
-/* 
+/*
 .test_add_box>.test>.mask>div>span:nth-child(1) {
   display: block;
   width: 13px;

+ 6 - 1
src/components/pages/trainCourse/addCourse.vue

@@ -3911,6 +3911,11 @@ import weilaiData from "../components/weilai.js";
 import sourceDialog from "../teacherSource/dialog.vue";
 import interVideo from "../interVideo/index.vue";
 import englishRight from "../components/englishRight.vue";
+var OpenCC = require("opencc-js");
+let converter = OpenCC.Converter({
+		from:'hk',
+		to:'cn'
+})
 
 export default {
   components: {
@@ -4152,7 +4157,7 @@ export default {
       imageloading: false,
       searchImageValue: "",
       ppage: 1,
-      toolsData: toolsData,
+      toolsData: JSON.parse(converter(JSON.stringify(toolsData))),
       oldIndex: 0,
       dragType:'',
       oldUnitIndex: 0,

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

@@ -364,7 +364,8 @@
 import WorkDate from "./components/workData";
 import Report from "./components/report";
 import studentReport from "./components/studentReport";
-import { T } from "caniuse-lite/data/browserVersions";
+import "../../common/aws-sdk-2.235.1.min.js";
+
 export default {
   components: {
     WorkDate,
@@ -552,6 +553,48 @@ export default {
           console.error(err);
         });
     },
+    downloadFile(url){
+      var credentials = {
+        accessKeyId: "AKIATLPEDU37QV5CHLMH",
+        secretAccessKey: "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",
+      }; //秘钥形式的登录上传
+      window.AWS.config.update(credentials);
+      window.AWS.config.region = "cn-northwest-1"; //设置区域
+      let url2 = url;
+      let _url2 = "";
+      if (
+        url2.indexOf("https://view.officeapps.live.com/op/view.aspx?src=") != -1
+      ) {
+        _url2 = url2.split(
+          "https://view.officeapps.live.com/op/view.aspx?src="
+        )[1];
+      } else {
+        _url2 = url2;
+      }
+      let _this = this;
+
+      _this.downLoading = true
+      var s3 = new window.AWS.S3({ params: { Bucket: "ccrb" } });
+      let name = decodeURIComponent(_url2.split("https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/")[1])
+      var params = {
+        Bucket: "ccrb",
+        Key: name
+      };
+      s3.getObject(params, function (err, data) {
+        _this.downLoading = false
+        if (err) console.log(err, err.stack); // an error occurred
+        else {
+          let url = window.URL.createObjectURL(new Blob([data.Body]));
+          let a = document.createElement("a");
+          a.name = 'student01-学生成长报告.pdf';
+          a.href = url;
+          a.download = 'student01-学生成长报告.pdf';
+          a.click();
+          console.log(data); 
+        }          // sxuccessful response
+
+      });
+    },
     getCourseDetail() {
       let params = {
         cid: this.checkCourse,
@@ -570,6 +613,7 @@ export default {
       this.reportVisible = true;
       this.signDialog = false;
     },
+
     getClass() {
       let params = {
         oid: this.oid,

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません