|
@@ -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;
|