SanHQin 1 mesiac pred
rodič
commit
6fd40f0de6

+ 1 - 1
dist/index.html

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

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
dist/static/css/app.4fabe840f9333f720df8ca90397cbd95.css


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
dist/static/css/app.4fabe840f9333f720df8ca90397cbd95.css.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
dist/static/js/app.581e1edf2207f62dfdf6.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
dist/static/js/app.581e1edf2207f62dfdf6.js.map


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
dist/static/js/manifest.161e82026ac2ae03ab6f.js.map


+ 1 - 3
src/components/pages/classroomObservation/dialog/batchCreationClassDialog.vue

@@ -1385,9 +1385,7 @@ export default {
           fileList.forEach((i, index) => {
             let fileName = i.name;
 
-            if(fileList.map(i=>i.name).includes(fileName)){
-              fileName = fileName.replace(/\.[^/.]+$/, "") + `(${index}).` + fileName.replace(/^.*\./, "");
-            }
+            if (fileList.map(i => i.name).filter((fi,findex)=>findex!==index).includes(fileName))fileName = fileName.replace(/\.[^/.]+$/, "") + `(${index}).` + fileName.replace(/^.*\./, "");
             // let fileName = i.name;
             // let fileNames = fileList.map(file => file.name);
             // let count = 1;

+ 738 - 0
src/components/pages/classroomObservation/test.vue

@@ -0,0 +1,738 @@
+<template>
+  <div>
+   <div class="left">
+    <el-button type="primary" @click="start">开始</el-button>
+   </div>
+   <div class="right">
+
+   </div>
+  </div>
+</template>
+
+<script>
+import markdownIt from "markdown-it";
+
+import QRCode from "qrcodejs2";
+import * as echarts from "echarts";
+import "echarts-wordcloud";
+// word
+import htmlDocx from "html-docx-js/dist/html-docx";
+import JSZip from "jszip";
+export default {
+  data() {
+    return {
+      tidList: [
+        "1f01ab3b-2249-453d-9b97-980fed675f94",
+        "3f854673-e3a3-4165-994d-d9bac0ea41cd",
+        "02a78b78-322a-4f43-9671-6ac533efd110",
+        "c2903392-1066-4512-8e8d-3256db2d2518",
+        "a4300c9c-4fc5-4f72-b337-f285fa9d033f",
+        "bb8d66ab-9876-4d17-b0e4-a095ecea58d1",
+        "2655a7b9-4add-472f-a62b-3c72bccc7a07",
+        "659af006-7415-4c73-aba6-2946d8b9ac6c",
+        "90926fc7-1c39-46e6-aa3e-34eeada89fa6",
+        "734bbdd4-a6eb-4e0e-acdb-bd5127cc8260",
+        "af8c74e5-cde8-4a33-ab3e-db077c37cec4",
+        "f665bb6f-54e5-4041-9b9b-489ea5814c7a",
+        "95453e35-9182-4e0c-a045-6757a84b7933",
+        "08958289-8d62-4468-b050-2e84a68edb26",
+        "2420d2d4-0627-43cc-9a8e-758ed074169c",
+        "4334e60d-f705-42bd-a89c-2bfc69b7615b",
+        "62e76f44-1f25-4a13-a699-93c4e58dc5ce",
+        "83891871-9eed-4aae-a318-9a1a1b52c047",
+        "7e32c688-051d-40b6-b2bd-a076fcf83ff5",
+      ],
+      message:[],
+      doTid: "",
+      dataList: [],
+      bmData: [],
+      dialogTagList: [
+        { value: 0, name: "通用课堂分析", loading: false },
+        { value: 1, name: "学科课堂分析", loading: false },
+        { value: 2, name: "扩展分析", loading: false }
+      ],
+      imageList: [],
+      tag: {
+        0: "一",
+        1: "二",
+        2: "三",
+        3: "四",
+        4: "五",
+        5: "六",
+        6: "七",
+        7: "八",
+        8: "九",
+        9: "十",
+        10: "十一",
+        11: "十二",
+        12: "十三",
+        13: "十四",
+        14: "十五",
+        15: "十六",
+        16: "十七",
+        17: "十八",
+        18: "十九",
+        19: "二十"
+      }
+    };
+  },
+  methods: {
+    start() {
+      this.getData();
+    },
+    init() {
+      this.doTid = "";
+      this.dataList = [];
+      this.bmData = {};
+      this.dialogTagList = [
+        { value: 0, name: "通用课堂分析", loading: false },
+        { value: 1, name: "学科课堂分析", loading: false },
+        { value: 2, name: "扩展分析", loading: false }
+      ];
+      this.imageList = [];
+    },
+    getAnalysisData(type) {
+      if (!this.doTid) return;
+      return new Promise(resolve => {
+        let params = {
+          tid: this.doTid,
+          type: type
+        };
+
+        if (type == 0) {
+          this.bmData = {
+            id: "",
+            tId: this.doTid,
+            tIndex: 0,
+            jsonData: {
+              activity_methods: "",
+              activity_structure: "",
+              classroom_resources: "",
+              courseName: "",
+              name: "",
+              studentNum: 0,
+              subject: "",
+              textbook: ""
+            }
+          };
+          this.imageList = [];
+          this.dataList = [];
+          this.dialogTagList = [
+            { value: 0, name: "通用课堂分析", loading: true },
+            { value: 1, name: "学科课堂分析", loading: true },
+            { value: 2, name: "扩展分析", loading: true }
+          ];
+        }
+
+        this.ajax
+          .post(
+            "https://gpt4.cocorobo.cn/get_classroom_observation_new",
+            params
+          )
+          .then(res => {
+            let _data = res.data.FunctionResponse.result.length
+              ? JSON.parse(res.data.FunctionResponse.result)
+              : [];
+
+            if (type == 0) {
+              //第一个分析
+              let _bmData = _data.find(i => i.tIndex == 0);
+              let _dialogTagList = [];
+              // 基础信息
+              _bmData.jsonData = JSON.parse(_bmData.jsonData);
+              _dialogTagList = _bmData.jsonData.dialogTagList || [
+                { value: 0, name: "通用课堂分析", loading: false },
+                { value: 1, name: "学科课堂分析", loading: false },
+                { value: 2, name: "扩展分析", loading: false }
+              ];
+              // 图片
+              let _imageList = _data.find(i => i.tIndex == 1);
+              _imageList.jsonData = JSON.parse(_imageList.jsonData);
+
+              if (!_imageList.jsonData.videoList) {
+                _imageList.jsonData.videoList = [];
+              }
+              if (!_imageList.jsonData.NephogramList) {
+                _imageList.jsonData.NephogramList = [];
+              }
+              //通用分析
+              let currency = [];
+              for (let i = 2; i < _data.length; i++) {
+                let _currency = _data[i];
+                _currency.jsonData = JSON.parse(_currency.jsonData);
+                currency.push(_currency);
+              }
+
+              //判断是否有保留装了文稿数据
+              this.dataList.push(...currency);
+              this.bmData = _bmData;
+              this.dialogTagList = _dialogTagList;
+              this.imageList = _imageList;
+              resolve();
+            } else {
+              let _analysisData = [];
+              for (let i = 0; i < _data.length; i++) {
+                let _analysis = _data[i];
+                _analysis.jsonData = JSON.parse(_analysis.jsonData);
+                _analysisData.push(_analysis);
+              }
+              this.dataList.push(..._analysisData);
+              resolve();
+            }
+          })
+          .catch(e => {
+            console.log(type, "获取分析失败", e);
+            resolve();
+          });
+      });
+    },
+    async getData() {
+      let fileData = [];
+
+      for (let i = 0; i < this.tidList.length; i++) {
+        this.doTid = this.tidList[i];
+        let dataList2 = [];
+        let bmData2 = {};
+        let dialogTagList2 = [
+          { value: 0, name: "通用课堂分析", loading: false },
+          { value: 1, name: "学科课堂分析", loading: false },
+          { value: 2, name: "扩展分析", loading: false }
+        ];
+        let imageList2 = [];
+        await this.getAnalysisData(0);
+        let promise = [];
+        this.dialogTagList.forEach(i2 => {
+          if (i2.value == 0) return;
+          promise.push(this.getAnalysisData(i2.value));
+        });
+
+        await Promise.all(promise);
+
+        this.dataList.sort((a, b) => a.tIndex - b.tIndex);
+        this.dataList.sort((a, b) => a.Type - b.Type);
+
+        dataList2 = JSON.parse(JSON.stringify(this.dataList));
+        bmData2 = JSON.parse(JSON.stringify(this.bmData));
+        dialogTagList2 = JSON.parse(JSON.stringify(this.dialogTagList));
+        imageList2 = JSON.parse(JSON.stringify(this.imageList));
+
+        // return
+        let file = await this.getDocFnPromise({
+          bmData: bmData2.jsonData,
+          dataList: dataList2,
+          tagList: dialogTagList2,
+          tid: this.doTid
+        });
+        fileData.push(file);
+        // console.log("👉file",file,this.doTid)
+        console.log("=========================")
+        console.log(`进度:${(i+1)}/${this.tidList.length}`)
+        console.log("课程id:",this.doTid)
+        console.log("文件名:",file.name)
+        console.log("文件:",file)
+        console.log("=========================")
+        this.init();
+      }
+
+      console.log("👉文件列表", fileData);
+
+      if (fileData.length == 1) {
+        saveAs(fileData[0], `${fileData[0].name}`);
+        this.$message.success("导出报告成功");
+      } else if (fileData.length > 1) {
+        const zip = new JSZip();
+        fileData.forEach((i, index) => {
+          let fileName = i.name;
+          if (fileData.map(i => i.name).filter((fi,findex)=>findex!==index).includes(fileName))
+            fileName =
+              fileName.replace(/\.[^/.]+$/, "") +
+              `(${index}).` +
+              fileName.replace(/^.*\./, "");
+          zip.file(fileName, i, { binary: true });
+        });
+        zip.generateAsync({ type: "blob" }).then(content => {
+          // 生成二进制流
+          saveAs(content, `课堂观察报告.zip`); // 利用file-saver保存文件  自定义文件名
+        });
+
+        this.$message.success("导出报告成功");
+      }
+    },
+    getQrCodeImageSrc(url) {
+      return new Promise((resolve, reject) => {
+        let qrcode = new QRCode(document.createElement("div"), {
+          text: url, // 需要转换为二维码的内容
+          width: 150,
+          height: 150,
+          colorDark: "#000000",
+          colorLight: "#ffffff",
+          correctLevel: QRCode.CorrectLevel.H
+        });
+        let img = qrcode._el.getElementsByTagName("img")[0];
+        img.onload = () => {
+          resolve(img.src);
+        };
+      });
+    },
+    getEChartsImageSrc(option) {
+      return new Promise(resolve => {
+        try {
+          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);
+
+
+          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();
+              }, 200);
+            })
+            .on("error", error => {
+              console.log("生成echarts失败", error);
+              resolve("#");
+            });
+
+          // 设置图标配置
+          myChart.setOption(option);
+          // console.log("词云图???",option)
+        } catch (error) {
+          console.log(error, "error");
+          resolve("#");
+        }
+      });
+    },
+    getImageSrcToBase64(src) {
+      return new Promise((resolve, reject) => {
+        const image = new Image();
+        image.src = src;
+        image.onload = () => {
+          const canvas = document.createElement("canvas");
+          canvas.width = image.naturalWidth;
+          canvas.height = image.naturalHeight;
+          canvas.style.width = `${canvas.width / window.devicePixelRatio}px`;
+          canvas.style.height = `${canvas.height / window.devicePixelRatio}px`;
+
+          const context = canvas.getContext("2d");
+          context.drawImage(image, 0, 0);
+          const base64 = canvas.toDataURL("image/png");
+          resolve(base64);
+        };
+      });
+    },
+    getEChartsSpectrogramImage(data) {
+      return new Promise(resolve => {
+        try {
+          let canvas = document.createElement("canvas");
+          let ctx = canvas.getContext("2d");
+          canvas.width = 600 * window.devicePixelRatio;
+          canvas.height = 200 * window.devicePixelRatio;
+          // 缩放绘图上下文
+          ctx.scale(1, 1);
+
+          let canvasWidth = canvas.width;
+          let canvasWidth2 = canvasWidth - 20;
+          let canvasHeight = canvas.height;
+          ctx.imageSmoothingEnabled = false;
+          ctx.lineWidth = 1;
+
+          // 设置颜色和文字
+          const teacherColor = "#5470C6"; // 老师的颜色
+          const studentColor = "#91CC75"; // 学生的颜色
+          const fontSize = 14; //字体大小
+
+          ctx.fillStyle = teacherColor;
+          this.drawRoundedRect(ctx, 0, canvasHeight - 20, 20, 15, 4);
+          // ctx.fillRect(0, canvasHeight - 20, 25, 20);
+          ctx.fillStyle = "black";
+          ctx.font = `${fontSize}px serif`;
+          ctx.fillText("老师", 28, canvasHeight - 7);
+
+          ctx.fillStyle = studentColor;
+          // ctx.fillRect(100, canvasHeight - 20, 25, 20);
+          this.drawRoundedRect(ctx, 100, canvasHeight - 20, 20, 15, 4);
+          ctx.fillStyle = "black";
+          ctx.font = `${fontSize}px serif`;
+          ctx.fillText("学生", 128, canvasHeight - 7);
+          let sum = data.data.reduce((pre, cur) => (pre += cur.value), 0);
+          // 当前x位置的起始点
+          let currentX = 10;
+          // 计算并绘制每个区域
+          data.data.forEach(i => {
+            const segmentWidth = parseFloat(
+              (i.value / (sum / canvasWidth2)).toFixed(2)
+            );
+            ctx.fillStyle = i.type == 0 ? teacherColor : studentColor;
+            ctx.fillRect(currentX, 20, segmentWidth, canvasHeight - 100);
+
+            // 更新x位置
+            currentX += segmentWidth;
+          });
+
+          // 绘制红色垂直线(指定位置)
+          // ctx.strokeStyle = "red";
+          // ctx.lineWidth = 2;
+
+          // data.breakpoint.forEach(i => {
+          //   const breakpointPo = parseFloat(
+          //     (i / (sum / canvasWidth2)).toFixed(2)
+          //   );
+          //   ctx.beginPath();
+          //   ctx.moveTo(breakpointPo, 10);
+          //   ctx.lineTo(breakpointPo, canvasHeight - 70);
+          //   ctx.stroke();
+          // });
+
+          let interval = parseFloat((300 / (sum / canvasWidth2)).toFixed(2));
+          //绘制竖线
+          let _lastI = 0;
+          //绘制竖线
+          for (let i = 0; i < canvasWidth2; i += interval) {
+            ctx.beginPath();
+            ctx.strokeStyle = "#BFBFBF";
+            ctx.moveTo(i == 0 ? 10 : i, canvasHeight - 70);
+            ctx.lineTo(i == 0 ? 10 : i, canvasHeight - 55);
+            ctx.stroke();
+            ctx.fillStyle = "#868686";
+            let timeLabel = (((i / canvasWidth2) * sum) / 60).toFixed(0); // 时间标识计算
+            ctx.font = `${fontSize}px serif`;
+            if (i == 0) {
+              ctx.fillText(`${timeLabel}min`, i + 10, canvasHeight - 40);
+            } else if (i + interval >= canvasWidth2) {
+              ctx.fillText(`${timeLabel}min`, i - 20, canvasHeight - 40);
+            } else {
+              ctx.fillText(`${timeLabel}min`, i - 15, canvasHeight - 40);
+            }
+            _lastI = i;
+          }
+          if (canvasWidth2 - _lastI > 60) {
+            ctx.beginPath();
+            ctx.strokeStyle = "#BFBFBF";
+            ctx.moveTo(canvasWidth2 + 10, canvasHeight - 70);
+            ctx.lineTo(canvasWidth2 + 10, canvasHeight - 55);
+            ctx.stroke();
+            ctx.fillStyle = "#868686";
+            let timeLabel = (sum / 60).toFixed(0); // 时间标识计算
+            ctx.font = `${fontSize}px serif`;
+            ctx.fillText(
+              `${timeLabel}min`,
+              canvasWidth2 - 20,
+              canvasHeight - 40
+            );
+          }
+
+          ctx.beginPath();
+          ctx.strokeStyle = "#BFBFBF";
+          ctx.moveTo(10, canvasHeight - 55);
+          ctx.lineTo(canvasWidth2 + 10, canvasHeight - 55);
+          ctx.stroke();
+
+          // 将 canvas 转换为 base64 格式的图片地址
+          const base64Image = canvas.toDataURL("image/png");
+          resolve(base64Image);
+        } catch (e) {
+          console.log(e);
+          resolve("#");
+        }
+      });
+    },
+    getEChartsechartsRTCHImage(data) {
+      return new Promise(resolve => {
+        try {
+          let canvas = document.createElement("canvas");
+          let ctx = canvas.getContext("2d");
+          canvas.width = 300 * window.devicePixelRatio;
+          canvas.height = 350 * window.devicePixelRatio;
+          // 缩放绘图上下文
+          ctx.scale(1, 1);
+
+          let canvasWidth = canvas.width;
+          let canvasHeight = canvas.height;
+          let fontColor = "#1a7ad3";
+          ctx.imageSmoothingEnabled = false;
+          ctx.lineWidth = 1;
+          const img = new Image();
+          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.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();
+            ctx.stroke();
+            ctx.fillStyle = fontColor;
+            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
+            );
+            const base64Image = canvas.toDataURL("image/png");
+            resolve(base64Image);
+          };
+        } catch (e) {
+          console.log(e);
+          resolve("#");
+        }
+      });
+    },
+    drawRoundedRect(ctx, x, y, width, height, radius) {
+      // 限制 radius 的最大值,防止它超过矩形的宽度或高度的一半
+      const actualRadius = Math.min(radius, width / 2, height / 2);
+
+      ctx.beginPath();
+      ctx.moveTo(x + actualRadius, y); // 起点,矩形顶部的左侧
+
+      // 右上角的弧线
+      ctx.arcTo(x + width, y, x + width, y + height, actualRadius);
+
+      // 右下角的弧线
+      ctx.arcTo(x + width, y + height, x, y + height, actualRadius);
+
+      // 左下角的弧线
+      ctx.arcTo(x, y + height, x, y, actualRadius);
+
+      // 左上角的弧线
+      ctx.arcTo(x, y, x + width, y, actualRadius);
+
+      ctx.closePath();
+      ctx.fill(); // 填充颜色
+    },
+    async getDocFnPromise({ bmData, dataList, tagList, tid }) {
+      return new Promise(async resolve => {
+        try {
+          const md = new markdownIt();
+          let showBrief = true;
+          tagList.forEach(i => (i.dataList = []));
+          let url = `https://beta.cloud.cocorobo.cn/aigpt/#/classroom_observation_board?tid=${tid}`;
+          const qRCodeSrc = await this.getQrCodeImageSrc(url);
+
+          // dataList.sort((a, b) => a.tIndex - b.tIndex);
+
+          dataList.sort((a, b) => a.tIndex - b.tIndex);
+          dataList.sort((a, b) => a.Type - b.Type);
+          dataList.forEach(i1 => {
+            tagList.forEach(i2 => {
+              if (i2.value == i1.Type) {
+                i2.dataList.push(i1);
+              }
+            });
+          });
+
+          let directoryHtml = `<div style="margin-bottom:1in"><div style="text-align:center;font-size:20pt;margin-bottom:0.5in">目录</div>`;
+
+          let analysisHtml = ``;
+
+          for (let c = 0; c < tagList.length; c++) {
+            let i = tagList[c];
+            let dire = `<div>`;
+            let tagHtml = `<div style="margin-bottom:0.5in">`;
+            if (i.value == 0) {
+              i.dataList = i.dataList.filter(i2 => i2.tIndex != 2);
+            }
+            i.dataList.sort((a, b) => a.tIndex - b.tIndex);
+            tagHtml += `<h1 style="font-size:16pt;margin-bottom:-1in">${
+              this.tag[i.value]
+            }、${i.name}</h1>`;
+            dire += `<p style="font-size:14pt;margin-bottom:-0.8in">${
+              this.tag[i.value]
+            }、${i.name}</p>`;
+
+            for (let d = 0; d < i.dataList.length; d++) {
+              let i2 = i.dataList[d];
+              let i2Index = d;
+              tagHtml += `<h2 style="font-size:14pt;margin-bottom:-1in">${i2Index +
+                1}、${
+                i2.jsonData.anotherName
+                  ? i2.jsonData.anotherName
+                  : i2.jsonData.name
+              }</h2>`;
+              dire += `<p style="font-size:11pt;margin-bottom:-0.8in;margin-left:0.1in">${i2Index +
+                1}、${
+                i2.jsonData.anotherName
+                  ? i2.jsonData.anotherName
+                  : i2.jsonData.name
+              }</p>`;
+              if (showBrief && i2.jsonData.result) {
+                tagHtml += `<p style="font-size:10.5pt;font-style:italic;margin-bottom:-0.7in;color:#6b798e">${i2.jsonData.result}</p>`;
+              }
+              if (i2.jsonData.eChartData) {
+                tagHtml += `<div style="width:100vw;padding:70%;box-sizing: border-box;text-align:center"><img style="margin:auto" src="${await this.getEChartsImageSrc(
+                  i2.jsonData.eChartData
+                )}"/></div>`;
+              }
+
+              if (i2.jsonData.spectrogramData) {
+                tagHtml += `<div style="width:100vw;padding:70%;box-sizing: border-box;text-align:center"><img style="margin:auto" src="${await this.getEChartsSpectrogramImage(
+                  i2.jsonData.spectrogramData
+                )}"/></div>`;
+              }
+
+              if (i2.jsonData.CH && i2.jsonData.RT) {
+                tagHtml += `<div style="width:100vw;text-align:center;padding:70%;box-sizing: border-box;"><img style="margin:auto" src="${await this.getEChartsechartsRTCHImage(
+                  {
+                    RT: i2.jsonData.RT,
+                    CH: i2.jsonData.CH
+                  }
+                )}"/></div>`;
+              }
+              let _content = md
+                .render(i2.jsonData.content ? 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>";
+            dire += "</div>";
+            analysisHtml += tagHtml;
+            directoryHtml += dire;
+          }
+
+          directoryHtml += "</div>";
+          let _html = `
+				<div>
+					<p style="width:100vw;margin-bottom:1.5in">*分析结果仅供参考</p>
+					<p style="font-size:28pt;width:100vw;text-align:center;">课堂观察报告</p>
+					<p style="font-size:10pt;width:100vw;text-align:center;margin-bottom:0.6in">报告生成时间:${new Date().toLocaleString()}</p>
+					<div style="font-size:16pt;width:100vw;text-align:center;margin-bottom:1in">
+						<p style="font-size:20pt;margin-bottom:0.7in">《${bmData.courseName}》</p>
+						<p style="margin-bottom:-1in">授课老师:${
+              bmData.teacherName ? bmData.teacherName : "未填写"
+            }</p>
+						<p style="margin-bottom:-1in">授课年级:${
+              bmData.grade ? bmData.grade : "未填写"
+            }</p>
+						<p style="margin-bottom:-1in">授课科目:${
+              bmData.subject ? bmData.subject : "未填写"
+            }</p>
+						<p style="margin-bottom:-1in">授课时间:${
+              bmData.time ? bmData.time : "未填写"
+            }</p>
+					</div>
+					<div style="font-size:16pt;width:100vw;text-align:center;margin-bottom:0.5in">
+						<img src="${qRCodeSrc}" style="width:150px;height:150px;margin:auto;"/>
+						<p>扫码查看网页版</p>
+					</div>
+				</div>
+				${directoryHtml}
+
+				<div>
+					${analysisHtml}
+				</div>
+				`;
+
+          const content = `<!DOCTYPE html>
+				<html xmlns:v='urn:schemas-microsoft-com
+				:vml'xmlns:o='urn:schemas-microsoft-com:office
+				:office'xmlns:w='urn:schemas-microsoft-com:office
+				:word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'
+				xmlns='http://www.w3.org/TR/REC-html40'
+				xmlns='http://www.w3.org/1999/xhtml'>
+				<head>
+						<meta charset="UTF-8">
+						<meta http-equiv="X-UA-Compatible" content="IE=edge">
+						<meta name="viewport" content="width=device-width, initial-scale=1.0">
+						<title>《${bmData.courseName}》课堂观察报告</title>
+						<style>
+							*{
+								font-family: '宋体';
+								margin:0;
+								padding:0;
+								line-height:1;
+							}
+							table {
+								border-collapse: collapse; /* 折叠边框 */
+								width: 100%;
+								font-size:10.5pt;
+							}
+							th, td {
+								border: 1px solid black; /* 线条样式 */
+								padding: 8px;
+								text-align: left;
+								font-size:10.5pt;
+							}
+							ol,ul{
+								margin:0;
+								padding:0;
+								margin-right:-1in;
+							}
+							li{
+								position: relative;
+								padding-left: 1.5em; /* 控制项目符号与文本的距离 */
+								margin-bottom: 0.5em;
+								text-indent: -1.5em; /* 负缩进使文本与符号对齐 */
+								mso-special-format: bullet;
+								margin-left: 0;
+								padding-left: 10pt;
+								text-indent: -10pt;
+								mso-style-name: "Normal";
+								mso-style-priority: 99;
+								mso-style-unhide: no;
+								mso-style-qformat: yes;
+								mso-style-parent: "";
+							}
+							p{
+								margin:0;
+								padding:0
+							}
+						</style>
+				</head>
+				<body>
+				${_html}
+				</body>
+				</html>`;
+          // debugger
+          let blob = htmlDocx.asBlob(content);
+          const file = new File(
+            [blob],
+            `${bmData.courseName}课堂观察报告.docx`,
+            {
+              type: ".docx",
+              lastModified: new Date().getTime()
+            }
+          );
+          resolve(file);
+        } catch (error) {
+          console.log("👉", error);
+          resolve(error);
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style scoped></style>

+ 9 - 0
src/router/index.js

@@ -145,6 +145,7 @@ import cocoroboffmpeg from '@/components/pages/cocoroboffmpeg'
 import appStore from '@/components/pages/appStore'
 import knowledge from '@/components/pages/knowledge/index'
 import sassPlatform from '@/components/pages/sassPlatform/index'
+import classroomObservationTest from '@/components/pages/classroomObservation/test.vue'
 // 全局修改默认配置,点击空白处不能关闭弹窗
 ElementUI.Dialog.props.closeOnClickModal.default = false
 Vue.use(Router).use(ElementUI)
@@ -1250,6 +1251,14 @@ export default new Router({
             keepAlive: true,
             requireAuth:""//不需要鉴权
           }
+        },{
+          path:"/classroomObservationTest",
+          name:"/classroomObservationTest",
+          component:classroomObservationTest,
+          meta:{
+            keepAlive: true,
+            requireAuth:""//不需要鉴权
+          }
         }
     ]
 })

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov