SanHQin 1 týždeň pred
rodič
commit
df0026db69

+ 181 - 88
src/components/pages/classroomObservation/index.vue

@@ -16,7 +16,12 @@
 					class="co-h2-l-icon"
 					@click="$refs.addNewCourseDialogRef.open()"
 				></span> -->
-         <div class="r_pub_button_retrun"  style="margin-right: 10px;" v-if="gotype" @click.stop="$router.go(-1)">
+        <div
+          class="r_pub_button_retrun"
+          style="margin-right: 10px;"
+          v-if="gotype"
+          @click.stop="$router.go(-1)"
+        >
           <!-- <span class="co-h2-r-b-icon3"></span> -->
           返回
         </div>
@@ -86,8 +91,11 @@
 				</div> -->
       </div>
       <div class="co-h2-right">
-
-        <div class="co-h2-r-btn" style="background: rgba(54, 129, 252, 1)" @click.stop="batchBtn()">
+        <div
+          class="co-h2-r-btn"
+          style="background: rgba(54, 129, 252, 1)"
+          @click.stop="batchBtn()"
+        >
           <span class="co-h2-r-b-icon3"></span>
           <div style="color: #fff;">批量创建</div>
         </div>
@@ -199,7 +207,7 @@
           @changeTranscription="changeTranscription"
           @changeOptionData="changeOptionData"
           @updateTime="updateTime"
-					@getVideoAudioSuccess="getVideoAudioSuccess"
+          @getVideoAudioSuccess="getVideoAudioSuccess"
         />
       </div>
     </div>
@@ -209,7 +217,11 @@
       ref="changeCourseNameDialogRef"
       @success="changeCourseSuccess"
     />
-    <batchCreationClassDialog ref="batchCreationClassDialogRef" @addNewCourseOption="addNewCourseOption" @changeClass="changeTid"/>
+    <batchCreationClassDialog
+      ref="batchCreationClassDialogRef"
+      @addNewCourseOption="addNewCourseOption"
+      @changeClass="changeTid"
+    />
 
     <!-- <addNewCourseDialog
 			:courseList="optionData"
@@ -240,7 +252,7 @@ import "echarts-wordcloud";
 import htmlDocx from "html-docx-js/dist/html-docx";
 import saveAs from "file-saver";
 import MarkdownIt from "markdown-it";
-import batchCreationClassDialog from './dialog/batchCreationClassDialog.vue'
+import batchCreationClassDialog from "./dialog/batchCreationClassDialog.vue";
 export default {
   components: {
     chatArea,
@@ -252,7 +264,7 @@ export default {
   },
   data() {
     return {
-      gotype:sessionStorage.getItem('gotype'),
+      gotype: sessionStorage.getItem("gotype"),
       loading: false,
       createTime: new Date().toLocaleString().replaceAll("/", "-"),
       tid: "",
@@ -284,20 +296,22 @@ export default {
       }
     };
   },
-	watch:{
-		fileIdId(newValue){
-			let needUpdateFileId = window.localStorage.getItem("needUpdateFileId")?window.localStorage.getItem("needUpdateFileId"):null;
-			if(needUpdateFileId && newValue){
-				console.log("查询到needUpdateFileId,更新fileId👉",needUpdateFileId)
-				this.updateFileId(needUpdateFileId);
-				window.localStorage.removeItem("needUpdateFileId");
-			}
-		}
-	},
+  watch: {
+    fileIdId(newValue) {
+      let needUpdateFileId = window.localStorage.getItem("needUpdateFileId")
+        ? window.localStorage.getItem("needUpdateFileId")
+        : null;
+      if (needUpdateFileId && newValue) {
+        console.log("查询到needUpdateFileId,更新fileId👉", needUpdateFileId);
+        this.updateFileId(needUpdateFileId);
+        window.localStorage.removeItem("needUpdateFileId");
+      }
+    }
+  },
   methods: {
     //切换了课堂
     changeTid(newValue) {
-      if(this.tid!=newValue)this.tid = newValue;
+      if (this.tid != newValue) this.tid = newValue;
       this.$nextTick(async () => {
         this.getFileIdId();
         this.$refs.messageAreaRef.getData();
@@ -393,7 +407,7 @@ export default {
           userid: this.userId,
           template: json
         };
-        console.log("创建新课堂",params);
+        console.log("创建新课堂", params);
         this.ajax
           .post(
             "https://gpt4.cocorobo.cn/insert_classroom_observation_template",
@@ -448,10 +462,10 @@ export default {
       });
     },
     updateFileId(newValue) {
-			if(!this.fileIdId){
-				console.log("未查询到fileIdId,先保存到localStorage👉",newValue)
-				return window.localStorage.setItem("needUpdateFileId",newValue);
-			}
+      if (!this.fileIdId) {
+        console.log("未查询到fileIdId,先保存到localStorage👉", newValue);
+        return window.localStorage.setItem("needUpdateFileId", newValue);
+      }
       this.ajax
         .post("https://gpt4.cocorobo.cn/update_classroom_observation", {
           id: this.fileIdId,
@@ -485,7 +499,7 @@ export default {
     //预览
     preview() {
       if (!this.fileId) return;
-       window.topU.postMessage(
+      window.topU.postMessage(
         {
           tools: "classroom_observation_board",
           type: this.tid
@@ -517,9 +531,6 @@ export default {
           });
         });
 
-
-
-
         let directoryHtml = `<div style="margin-bottom:1in"><div style="text-align:center;font-size:20pt;margin-bottom:0.5in">目录</div>`;
 
         let analysisHtml = ``;
@@ -579,7 +590,14 @@ export default {
               )}"/></div>`;
             }
 
-            let _content = md.render(i2.jsonData.content).replace(/<p>/g, '').replace(/<\/p>/g, '').replace(/<strong>/g, '<span style="font-weight: bold;">').replace(/<\/strong>/g, '</span>');
+            let _content = this.processHtml(
+              md
+                .render(i2.jsonData.content)
+                .replace(/<p>/g, "")
+                .replace(/<\/p>/g, "")
+                .replace(/<strong>/g, '<span style="font-weight: bold;">')
+                .replace(/<\/strong>/g, "</span>")
+            );
             tagHtml += `<p style="font-size:10.5pt;margin-bottom:-0.5in">${_content}</p>`;
           }
           tagHtml += "</div>";
@@ -622,7 +640,7 @@ export default {
 				${analysisHtml}
 			</div>
 			`;
-      // return console.log(analysisHtml.replace(/<img.*?>/g, ''))
+        // return console.log(analysisHtml.replace(/<img.*?>/g, ''))
 
         this.generateDocx(`《${bmData.courseName}》课堂观察报告`, _html);
         this.loading = false;
@@ -650,32 +668,52 @@ export default {
     },
     getEChartsImageSrc(option) {
       return new Promise(resolve => {
-        let hiddenDiv = document.createElement("div");
-        hiddenDiv.style.width = "400px";
-        hiddenDiv.style.height = "400px";
-        hiddenDiv.style.position = "absolute";
-        hiddenDiv.style.left = "-9999px"; // 隐藏div
-        document.body.appendChild(hiddenDiv);
-
-        // 初始化图表
-        let myChart = echarts.init(hiddenDiv);
-
-        // 设置图标配置
-        myChart.setOption(option);
-
-        myChart.on("finished", () => {
-          // 获取图表的图片
-          let base64Image = myChart.getDataURL({
-            type: "png", // 图片格式
-            pixelRatio: 0.9, // 图像清晰度
-            backgroundColor: "#fff" // 背景颜色
-          });
+        try {
+          let hiddenDiv = document.createElement("div");
+          hiddenDiv.style.width = "600px";
+          hiddenDiv.style.height = "400px";
+          hiddenDiv.style.position = "absolute";
+          hiddenDiv.style.left = "-9999px"; // 隐藏div
+          document.body.appendChild(hiddenDiv);
+
+          // 初始化图表
+          let myChart = echarts.init(hiddenDiv);
+
+          console.log(option);
+          option.animation = false;
+
+          let time;
+          myChart
+            .on("rendered", async () => {
+              // console.log("生成echarts成功")
+              // 获取图表的图片
+
+              clearTimeout(time);
+              time = setTimeout(() => {
+                let base64Image = myChart.getDataURL({
+                  type: "png", // 图片格式
+                  pixelRatio: 0.9, // 图像清晰度
+                  backgroundColor: "#fff" // 背景颜色
+                });
 
-          resolve(base64Image);
-          // 清除隐藏的div和图表实例
-          document.body.removeChild(hiddenDiv);
-          myChart.dispose();
-        });
+                resolve(base64Image);
+                // 清除隐藏的div和图表实例
+                document.body.removeChild(hiddenDiv);
+                myChart.dispose();
+              }, 200);
+            })
+            .on("error", error => {
+              console.log("生成echarts失败", error);
+              resolve("#");
+            });
+
+          // 设置图标配置
+          myChart.setOption(option);
+          // console.log("词云图???",option)
+        } catch (error) {
+          console.log(error, "error");
+          resolve("#");
+        }
       });
     },
     getImageSrcToBase64(src) {
@@ -781,7 +819,7 @@ export default {
             }
             _lastI = i;
           }
-          if (canvasWidth2 - _lastI >60) {
+          if (canvasWidth2 - _lastI > 60) {
             ctx.beginPath();
             ctx.strokeStyle = "#BFBFBF";
             ctx.moveTo(canvasWidth2 + 10, canvasHeight - 70);
@@ -790,7 +828,11 @@ export default {
             ctx.fillStyle = "#868686";
             let timeLabel = (sum / 60).toFixed(0); // 时间标识计算
             ctx.font = `${fontSize}px serif`;
-            ctx.fillText(`${timeLabel}min`, canvasWidth2 - 20, canvasHeight - 40);
+            ctx.fillText(
+              `${timeLabel}min`,
+              canvasWidth2 - 20,
+              canvasHeight - 40
+            );
           }
 
           ctx.beginPath();
@@ -824,12 +866,19 @@ export default {
           ctx.imageSmoothingEnabled = false;
           ctx.lineWidth = 1;
           const img = new Image();
-          img.src = require("../../../assets/icon/classroomObservation/rt-ch_echarts2.svg");  //ch_echarts2
+          img.src = require("../../../assets/icon/classroomObservation/rt-ch_echarts2.svg"); //ch_echarts2
           img.onload = () => {
             ctx.drawImage(img, 0, 0, canvasWidth, canvasWidth);
             ctx.beginPath();
-            let _showWidth = canvasWidth-((canvasWidth/8.8)*2)
-            ctx.arc((canvasWidth/8.8)+(_showWidth*parseFloat(data.RT)),(canvasWidth/8.8)+_showWidth-(_showWidth*parseFloat(data.CH)),4,0,2*Math.PI);
+            let _showWidth = canvasWidth - (canvasWidth / 8.8) * 2;
+            ctx.fillStyle = fontColor;
+            ctx.arc(
+              canvasWidth / 8.8 + _showWidth * parseFloat(data.RT),
+              canvasWidth / 8.8 + _showWidth - _showWidth * parseFloat(data.CH),
+              4,
+              0,
+              2 * Math.PI
+            );
             ctx.lineWidth = 0.5; // 设置边框大小
             // ctx.arc((canvasWidth*parseFloat(this.data.RT))+(canvasWidth/8.8),(canvasWidth-(canvasWidth*parseFloat(this.data.CH))+(canvasWidth/8.8)), 4, 0, 2 * Math.PI);
             ctx.fill();
@@ -838,7 +887,11 @@ export default {
             ctx.font = "italic bold 24px Arial";
             const text = `RT=${data.RT}    CH=${data.CH}`;
             const textWidth = ctx.measureText(text).width;
-            ctx.fillText(text, (canvasWidth - textWidth) / 2, canvasHeight - canvasWidth / 12);
+            ctx.fillText(
+              text,
+              (canvasWidth - textWidth) / 2,
+              canvasHeight - canvasWidth / 12
+            );
             const base64Image = canvas.toDataURL("image/png");
             resolve(base64Image);
           };
@@ -887,29 +940,29 @@ export default {
           <title>${name}</title>
           <style>
 						*{
-							font-family: '宋体';
-							margin:0;
-							padding:0;
-							line-height:1;
-						}
+			      	font-family: '宋体';
+			      	margin:0;
+			      	padding:0;
+			      	line-height:1;
+			      }
             table {
               border-collapse: collapse; /* 折叠边框 */
               width: 100%;
-							font-size:10.5pt;
+			      	font-size:10.5pt;
             }
             th, td {
               border: 1px solid black; /* 线条样式 */
               padding: 8px;
               text-align: left;
-							font-size:10.5pt;
+			      	font-size:10.5pt;
             }
-						ol,ul{
-							margin:0;
-							padding:0;
-							margin-right:-1in;
-						}
-						li{
-							position: relative;
+			      ol,ul{
+			      	margin:0;
+			      	padding:0;
+			      	margin-right:-1in;
+			      }
+			      li{
+			      	position: relative;
               padding-left: 1.5em; /* 控制项目符号与文本的距离 */
               margin-bottom: 0.5em;
               text-indent: -1.5em; /* 负缩进使文本与符号对齐 */
@@ -922,11 +975,11 @@ export default {
               mso-style-unhide: no;
               mso-style-qformat: yes;
               mso-style-parent: "";
-						}
-						p{
-							margin:0;
-							padding:0
-						}
+			      }
+			      p{
+			      	margin:0;
+			      	padding:0
+			      }
           </style>
       </head>
       <body>
@@ -997,7 +1050,7 @@ export default {
     // 审核
     examine() {
       if (!this.tid) return;
-       window.topU.postMessage(
+      window.topU.postMessage(
         {
           tools: "classroom_observation_ob_comment",
           type: this.tid
@@ -1229,15 +1282,56 @@ export default {
       }
       return formattedTime;
     },
-		getVideoAudioSuccess(file){
-			this.$refs.chatAreaRef.getVideoAudioSuccess(file)
-		},
-    batchBtn(){
+    getVideoAudioSuccess(file) {
+      this.$refs.chatAreaRef.getVideoAudioSuccess(file);
+    },
+    batchBtn() {
       this.$refs.batchCreationClassDialogRef.open();
     },
-    addNewCourseOption(newOption){
+    addNewCourseOption(newOption) {
       this.optionData.unshift(newOption);
     },
+    processHtml(html) {
+      // 1. 先把 li 里的 ol 结构替换掉
+      html = html.replace(
+        /<li>\s*<ol[^>]*>\s*<li>([\s\S]*?)<\/li>\s*<\/ol>\s*<\/li>/g,
+        (match, content) => {
+          return `<li>\n${content.trim()}\n</li>`;
+        }
+      );
+
+      // 2. 给 li 里的内容按行加 br
+      html = html.replace(/<li>([\s\S]*?)<\/li>/g, (match, content) => {
+        const lines = content
+          .trim()
+          .split(/(?:\r?\n)+/)
+          .map(line => line.trim())
+          .filter(line => line); // 过滤空行
+
+        if (lines.length <= 1) {
+          return `<li>\n${lines.join("")}\n</li>`;
+        } else {
+          return `<li>\n${lines.join("<br>\n")}\n</li>`;
+        }
+      });
+
+      // 3. 处理 pre 里的换行
+      html = html.replace(/<pre>([\s\S]*?)<\/pre>/g, (match, content) => {
+        const lines = content
+          .trim()
+          .split(/(?:\r?\n)+/)
+          .map(line => line.trim())
+          .filter(line => line); // 过滤空行
+
+        if (lines.length <= 1) {
+          return `<pre>${lines.join("")}</pre>`;
+        } else {
+          return `<pre>${lines.join("<br>\n")}</pre>`;
+        }
+      });
+
+      return html;
+    }
   },
   mounted() {
     this.getCourseList().then(_ => {
@@ -1437,12 +1531,11 @@ export default {
 }
 
 .co-h2-r-b-icon3 {
-  background: url("../../../assets/icon/classroomObservation/batch_icon.svg") no-repeat;
+  background: url("../../../assets/icon/classroomObservation/batch_icon.svg")
+    no-repeat;
   background-size: 100% 100%;
 }
 
-
-
 /* .co-h2-r-b-icon2 {
 	background: url("../../../assets/icon/classroomObservation/daoChu.png")
 		no-repeat;

+ 2 - 1
src/components/pages/classroomObservation/tools/mixin.js

@@ -1263,6 +1263,7 @@ CH:${_CH}
         iframeRef.contentWindow.onRecognizedResult = (e) => {
           let privText = e.privText;
           let privSpeakerId = e.privSpeakerId;
+          let copySpeakerId = e.copySpeakerId;
           let privDuration = e.privDuration;
           let privOffset = e.privOffset;
 
@@ -1288,7 +1289,7 @@ CH:${_CH}
           });
 
           _startTime = _endTime;
-          transcriptionContent += privText;
+          transcriptionContent += copySpeakerId + ":" + privText + "\n";
         };
 
         //转录结束