|
@@ -378,15 +378,15 @@ export default {
|
|
!i.isOtherData &&
|
|
!i.isOtherData &&
|
|
converter(i.jsonData.name) != converter("词频词汇分析")
|
|
converter(i.jsonData.name) != converter("词频词汇分析")
|
|
);
|
|
);
|
|
- json.forEach(i=>{
|
|
|
|
- if(i.jsonData.eChartData){
|
|
|
|
- delete i.jsonData.eChartData
|
|
|
|
- }
|
|
|
|
- if(i.jsonData.RT && i.jsonData.CH){
|
|
|
|
- delete i.jsonData.RT
|
|
|
|
- delete i.jsonData.CH
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
|
|
+ json.forEach(i => {
|
|
|
|
+ if (i.jsonData.eChartData) {
|
|
|
|
+ delete i.jsonData.eChartData;
|
|
|
|
+ }
|
|
|
|
+ if (i.jsonData.RT && i.jsonData.CH) {
|
|
|
|
+ delete i.jsonData.RT;
|
|
|
|
+ delete i.jsonData.CH;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
this.loading = true;
|
|
this.loading = true;
|
|
const _newTid = uuidv4();
|
|
const _newTid = uuidv4();
|
|
@@ -592,10 +592,21 @@ export default {
|
|
)}"/>`;
|
|
)}"/>`;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (i2.jsonData.spectrogramData) {
|
|
|
|
+ tagHtml += `<img src="${await this.getEChartsSpectrogramImage(
|
|
|
|
+ i2.jsonData.spectrogramData
|
|
|
|
+ )}"/>`;
|
|
|
|
+ // console.log()
|
|
|
|
+ }
|
|
|
|
+
|
|
if (i2.jsonData.CH && i2.jsonData.RT) {
|
|
if (i2.jsonData.CH && i2.jsonData.RT) {
|
|
tagHtml += `<div style="width:100vw;text-align:center;">
|
|
tagHtml += `<div style="width:100vw;text-align:center;">
|
|
- <img src="${await this.getImageSrcToBase64(require('../../../assets/icon/classroomObservation/rt-ch.png'))}" style="width:200px;height:200px;margin:auto;">
|
|
|
|
- <div style="color:#1A7AD3;font-style:italic;font-weight:blob;">RT:${i2.jsonData.RT}CH:${i2.jsonData.CH}</div>
|
|
|
|
|
|
+ <img src="${await this.getImageSrcToBase64(
|
|
|
|
+ require("../../../assets/icon/classroomObservation/rt-ch.png")
|
|
|
|
+ )}" style="width:200px;height:200px;margin:auto;">
|
|
|
|
+ <div style="color:#1A7AD3;font-style:italic;font-weight:blob;">RT:${
|
|
|
|
+ i2.jsonData.RT
|
|
|
|
+ }CH:${i2.jsonData.CH}</div>
|
|
</div>`;
|
|
</div>`;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -614,15 +625,23 @@ export default {
|
|
// return console.log(analysisHtml);
|
|
// return console.log(analysisHtml);
|
|
let _html = `
|
|
let _html = `
|
|
<div>
|
|
<div>
|
|
- <p style="width:100vw;margin-bottom:1.5in">*分析结果仅供参考</p>
|
|
|
|
|
|
+ <p style="width:100vw;margin-bottom:1.5in">*分析结果仅供参考</p>
|
|
<p style="font-size:28pt;width:100vw;text-align:center;">课堂观察报告</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>
|
|
<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">
|
|
<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="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>
|
|
|
|
|
|
+ <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>
|
|
<div style="font-size:16pt;width:100vw;text-align:center;margin-bottom:0.5in">
|
|
<div style="font-size:16pt;width:100vw;text-align:center;margin-bottom:0.5in">
|
|
<img src="${qRCodeSrc}" style="width:150px;height:150px;margin:auto;"/>
|
|
<img src="${qRCodeSrc}" style="width:150px;height:150px;margin:auto;"/>
|
|
@@ -689,24 +708,117 @@ export default {
|
|
});
|
|
});
|
|
});
|
|
});
|
|
},
|
|
},
|
|
- getImageSrcToBase64(src){
|
|
|
|
- return new Promise((resolve,reject)=>{
|
|
|
|
- const image = new Image();
|
|
|
|
- image.src = src;
|
|
|
|
- image.onload = () =>{
|
|
|
|
- const canvas = document.createElement('canvas');
|
|
|
|
- canvas.width = image.naturalWidth;
|
|
|
|
- canvas.height = image.naturalHeight;
|
|
|
|
- canvas.style.width = `${canvas.width / window.devicePixelRatio}px`
|
|
|
|
- canvas.style.height = `${canvas.height / window.devicePixelRatio}px`
|
|
|
|
-
|
|
|
|
- const context = canvas.getContext('2d');
|
|
|
|
- context.drawImage(image, 0, 0);
|
|
|
|
- const base64 = canvas.toDataURL('image/png');
|
|
|
|
- resolve(base64);
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- },
|
|
|
|
|
|
+ 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 = 150 * window.devicePixelRatio;
|
|
|
|
+ // 缩放绘图上下文
|
|
|
|
+ ctx.scale(1, 1);
|
|
|
|
+ let canvasWidth = canvas.width;
|
|
|
|
+ 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, 5);
|
|
|
|
+ // 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, 5);
|
|
|
|
+ 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 = 0;
|
|
|
|
+ // 计算并绘制每个区域
|
|
|
|
+ data.data.forEach(i => {
|
|
|
|
+ const segmentWidth = parseFloat(
|
|
|
|
+ (i.value / (sum / canvasWidth)).toFixed(2)
|
|
|
|
+ );
|
|
|
|
+ ctx.fillStyle = i.type == 0 ? teacherColor : studentColor;
|
|
|
|
+ ctx.fillRect(currentX, 20, segmentWidth, canvasHeight - 60);
|
|
|
|
+
|
|
|
|
+ // 更新x位置
|
|
|
|
+ currentX += segmentWidth;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 绘制红色垂直线(指定位置)
|
|
|
|
+ ctx.strokeStyle = "red";
|
|
|
|
+ ctx.lineWidth = 2;
|
|
|
|
+
|
|
|
|
+ data.breakpoint.forEach(i => {
|
|
|
|
+ const breakpointPo = parseFloat(
|
|
|
|
+ (i / (sum / canvasWidth)).toFixed(2)
|
|
|
|
+ );
|
|
|
|
+ ctx.beginPath();
|
|
|
|
+ ctx.moveTo(breakpointPo, 0);
|
|
|
|
+ ctx.lineTo(breakpointPo, canvasHeight - 20);
|
|
|
|
+ ctx.stroke();
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 将 canvas 转换为 base64 格式的图片地址
|
|
|
|
+ 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(); // 填充颜色
|
|
|
|
+ },
|
|
// 导出docx
|
|
// 导出docx
|
|
async generateDocx(name, html) {
|
|
async generateDocx(name, html) {
|
|
// 将html文件中需要用到的数据挂载到store上
|
|
// 将html文件中需要用到的数据挂载到store上
|
|
@@ -715,7 +827,7 @@ export default {
|
|
:vml'xmlns:o='urn:schemas-microsoft-com:office
|
|
:vml'xmlns:o='urn:schemas-microsoft-com:office
|
|
:office'xmlns:w='urn:schemas-microsoft-com:office
|
|
:office'xmlns:w='urn:schemas-microsoft-com:office
|
|
:word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'
|
|
:word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'
|
|
- xmlns='http://www.w3.org/TR/REC-html40'
|
|
|
|
|
|
+ xmlns='http://www.w3.org/TR/REC-html40'
|
|
xmlns='http://www.w3.org/1999/xhtml'>
|
|
xmlns='http://www.w3.org/1999/xhtml'>
|
|
<head>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta charset="UTF-8">
|