SanHQin 1 ano atrás
pai
commit
cf84428f3d

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
     "vant": "^2.12.7",
     "vconsole": "^3.3.4",
     "vue": "^2.6.11",
+    "vue-audio-better": "^3.0.1",
     "vue-calendar-component": "^2.8.2",
     "vue-h5-template": "file:",
     "vue-markdown": "^2.2.4",

+ 3 - 0
src/assets/images/classObserve/Vector.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.4801 13.0878C13.4801 13.5278 13.1441 13.8717 12.6961 13.8717H12.5361C12.6401 13.6637 12.6961 13.4557 12.6961 13.2157V2.78375C12.6961 2.55175 12.6401 2.31175 12.5361 2.12775H12.6961C13.1361 2.12775 13.4801 2.46375 13.4801 2.91175V13.0878ZM4.59214 4.97575C4.31214 4.97575 4.07214 4.79175 4.07214 4.58375C4.07214 4.37575 4.31214 4.19175 4.59214 4.19175H10.1441C10.4241 4.19175 10.6641 4.37575 10.6641 4.58375C10.6641 4.79175 10.4241 4.97575 10.1441 4.97575H4.59214ZM4.45614 7.60775C4.24814 7.60775 4.06414 7.42375 4.06414 7.21575C4.06414 7.00775 4.24814 6.82375 4.45614 6.82375H8.63214C8.84014 6.82375 9.02414 7.00775 9.02414 7.21575C9.02414 7.42375 8.84014 7.60775 8.63214 7.60775H4.45614ZM4.45614 9.98375C4.24814 9.98375 4.06414 9.79975 4.06414 9.59175C4.06414 9.38375 4.24814 9.19975 4.45614 9.19975H6.80814C7.01614 9.19975 7.20014 9.38375 7.20014 9.59175C7.20014 9.79975 7.01614 9.98375 6.80814 9.98375H4.45614ZM3.17614 1.35175C2.39214 1.35175 1.74414 2.00775 1.74414 2.78375V13.1918C1.74414 13.9998 2.40014 14.6237 3.17614 14.6237H12.6961C13.5601 14.6237 14.2641 13.9198 14.2641 13.0557V2.91175C14.2641 2.04775 13.5601 1.34375 12.6961 1.34375H3.17614V1.35175Z" fill="black" fill-opacity="0.26"/>
+</svg>

+ 9 - 0
src/assets/images/classObserve/Vector2.svg

@@ -0,0 +1,9 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M13.4799 13.0878C13.4799 13.5278 13.1439 13.8717 12.6959 13.8717H12.5359C12.6399 13.6637 12.6959 13.4557 12.6959 13.2157V2.78375C12.6959 2.55175 12.6399 2.31175 12.5359 2.12775H12.6959C13.1359 2.12775 13.4799 2.46375 13.4799 2.91175V13.0878ZM4.5919 4.97575C4.3119 4.97575 4.0719 4.79175 4.0719 4.58375C4.0719 4.37575 4.3119 4.19175 4.5919 4.19175H10.1439C10.4239 4.19175 10.6639 4.37575 10.6639 4.58375C10.6639 4.79175 10.4239 4.97575 10.1439 4.97575H4.5919ZM4.4559 7.60775C4.2479 7.60775 4.0639 7.42375 4.0639 7.21575C4.0639 7.00775 4.2479 6.82375 4.4559 6.82375H8.6319C8.8399 6.82375 9.0239 7.00775 9.0239 7.21575C9.0239 7.42375 8.8399 7.60775 8.6319 7.60775H4.4559ZM4.4559 9.98375C4.2479 9.98375 4.0639 9.79975 4.0639 9.59175C4.0639 9.38375 4.2479 9.19975 4.4559 9.19975H6.8079C7.0159 9.19975 7.1999 9.38375 7.1999 9.59175C7.1999 9.79975 7.0159 9.98375 6.8079 9.98375H4.4559ZM3.1759 1.35175C2.3919 1.35175 1.7439 2.00775 1.7439 2.78375V13.1918C1.7439 13.9998 2.3999 14.6237 3.1759 14.6237H12.6959C13.5599 14.6237 14.2639 13.9198 14.2639 13.0557V2.91175C14.2639 2.04775 13.5599 1.34375 12.6959 1.34375H3.1759V1.35175Z" fill="url(#paint0_linear_655_6834)"/>
+<defs>
+<linearGradient id="paint0_linear_655_6834" x1="1.7439" y1="14.6237" x2="14.2639" y2="14.6237" gradientUnits="userSpaceOnUse">
+<stop stop-color="#3673E8"/>
+<stop offset="1" stop-color="#AD88FD"/>
+</linearGradient>
+</defs>
+</svg>

BIN
src/assets/images/classObserve/loading.gif


BIN
src/assets/images/classObserve/rt-ch.png


Diferenças do arquivo suprimidas por serem muito extensas
+ 2 - 0
src/assets/images/classObserve/zhuanlu.svg


Diferenças do arquivo suprimidas por serem muito extensas
+ 2 - 0
src/assets/images/classObserve/zhuanlu2.svg


+ 2 - 0
src/main.js

@@ -31,6 +31,8 @@ import 'video.js/dist/video-js.css' // videoJs的样式
 import 'vue-video-player/src/custom-theme.css' // vue-video-player的样式
 Vue.use(WechatPlugin)
 Vue.use(VideoPlayer)
+import VueAudio from 'vue-audio-better'
+Vue.use(VueAudio)
 // 引入本地存储
 import { storage, sessionStorage } from '@/utils/storage'
 import hevueImgPreview from '@/components/hevue-img-preview'

+ 50 - 3
src/views/classObserve/components/analysisItem.vue

@@ -43,6 +43,17 @@
         <!-- {{ data.jsonData }} -->
         <mdView :text="data.jsonData ? data.jsonData.content : ''" />
       </div>
+			<div v-if="data.jsonData.eChartData && show" class="eChart">
+				<eChartTemplate ref="eChartTemplateRef" :data="data.jsonData.eChartData" style="max-height: 600px;max-width: 600px;width: 100%;height: 400px;margin: auto;"/>
+			</div>
+
+			<div v-if="data.jsonData.RT && data.jsonData.CH" class="teacherMode">
+				<img src="../../../assets/images/classObserve/rt-ch.png"> 
+				<div>
+					<span>RT={{ data.jsonData.RT }}</span>
+					<span>CH={{ data.jsonData.CH }}</span>
+				</div>
+			</div>
       <div class="outcomeBtn" v-if="[0,2,3].includes(status)">
         <div @click.stop="down()" :class="[historyIndex==0?'ob_no':'']">
           <img src="../../../assets/images/classObserve/restore.png" alt="" style="transform:rotateY(180deg);"/><span>撤销</span>
@@ -62,6 +73,7 @@
 import mdView from './mdView.vue'
 import { v4 as uuidv4 } from "uuid";
 import {chatRequest,updateObsRequest} from '@/api/classObserve'
+import eChartTemplate from './eChartTemplate.vue';
 export default {
   props: {
     data: {
@@ -82,7 +94,8 @@ export default {
 		}
   },
   components: {
-    mdView
+    mdView,
+		eChartTemplate
   },
   data() {
     return {
@@ -100,6 +113,10 @@ export default {
 			if(![0,2,3].includes(this.status))return this.$toast("正在优化中...")
       this.show = !this.show
 			this.status = 0;
+			if(this.$refs.eChartTemplateRef){
+				console.log("优化")
+				// this.$refs.eChartsView.resize()
+			}
     },
     abuShowItem() {
       this.abuShow = true
@@ -176,8 +193,8 @@ export default {
 				
     },
 		optimize2(value){
-			this.status = 2;
-			return console.log('特殊处理');
+			// this.status = 2;
+			// return console.log('特殊处理');
 			if(this.bmData.jsonData.editorBarData.type != 0){
 				this.status = 2;
 				return this.$toast.fail("请上传表格形式的转录文稿");
@@ -191,6 +208,7 @@ export default {
 				_tableRows.forEach((i, index) => {
 					if (index == 0) return;
 					if(!i.cells[0].innerText)return;
+					if(i.cells[0].innerText=='序号')return;
 					let obj = {
 						index: i.cells[0].innerText,
 						startTime: i.cells[1].innerText,
@@ -529,4 +547,33 @@ export default {
 
 	}
 }
+.eChart{
+	width: 100% !important;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	position: relative;
+}
+
+.teacherMode{
+	width: 100%;
+	height: 400px;
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+	img{
+			width: 100%;
+		}
+	div{
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		margin-top: 20px;
+		span{
+			margin: 0 10px;
+			font-size: 18px;
+		}
+	}
+}
 </style>

+ 49 - 0
src/views/classObserve/components/eChartTemplate.vue

@@ -0,0 +1,49 @@
+<template>
+	<div class="chart" id="charts_canvas" ref="chartRef"></div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+export default {
+	props: {
+		data: {
+			type: Object,
+			default: () => {},
+		},
+	},
+	data() {
+		return {
+			chartObj: null,
+			chartData: null,
+		};
+	},
+	watch: {
+		data() {
+			this.getChartData();
+		},
+	},
+	methods: {
+		getChartData() {
+			this.chartObj = echarts.init(this.$refs.chartRef);
+			this.chartObj.setOption(this.data);
+			window.addEventListener("resize", () => {
+					this.resize();
+      });
+		},
+		resize(){
+			this.chartObj.resize();
+		}
+	},
+	mounted() {
+		this.getChartData();
+	},
+};
+</script>
+
+<style scoped>
+.chart {
+	max-width: 100%;
+	width: 100%;
+	height: 100%;
+}
+</style>

+ 335 - 0
src/views/classObserve/components/wangEnduit.vue

@@ -0,0 +1,335 @@
+<template lang="html">
+  <div class="editor cont">
+    <div ref="toolbar" class="toolbar">
+    </div>
+    <div ref="editor" class="text">
+    </div>
+		<slot></slot>
+    <div v-if="proVisible" class="mask">
+      <div class="progressBox">
+        <div class="lbox">
+          <img src="../../../assets/images/classObserve/loading.gif" />上传中,请稍后
+        </div>
+      </div>
+    </div>
+  </div>
+</template>  
+  
+<script>
+import E from "wangeditor";
+import "../../../utils/aws-sdk-2.235.1.min.js";
+import { Loading } from 'element-ui';
+// import 'wangeditor/release/wangEditor.min.css'
+export default {
+  name: "editoritem",
+  data() {
+    return {
+      // uploadPath,
+      editor: null,
+      info_: null,
+      proVisible:false,
+      progress:0
+    };
+  },
+  model: {
+    prop: "value",
+    event: "change",
+  },
+  props: {
+    value: {
+      type: String,
+      default: "",
+    },
+    isClear: {
+      type: Boolean,
+      default: false,
+    },
+    placeholder: {
+      type: String,
+      default: "请输入正文"
+    },
+		showGetTextLoading:{
+			type:Boolean,
+			default:false,
+		}
+  },
+  watch: {
+    isClear(val) {
+      // 触发清除文本域内容
+      if (val) {
+        this.editor.txt.clear();
+        this.info_ = null;
+      }
+    },
+    value: function (value) {
+      if (value !== this.editor.txt.html()) {
+        this.editor.txt.html(this.value);
+      }
+    },
+    //value为编辑框输入的内容,这里我监听了一下值,当父组件调用得时候,如果给value赋值了,子组件将会显示父组件赋给的值
+  },
+  mounted() {
+    this.seteditor();
+    this.editor.txt.html(this.value);
+  },
+  methods: {
+    seteditor() {
+      this.editor = new E(this.$refs.toolbar, this.$refs.editor);
+      // 关闭菜单栏fixed
+      this.editor.config.menuFixed = false;
+      // 普通的自定义菜单
+      this.editor.config.menus = [
+        "head", //标题
+        "bold", //加粗
+        "fontSize", //字体大小
+        // "fontName", //字体
+        // "italic", //斜体
+        // "underline", //下划线
+        // "strikeThrough", //删除线
+        // "indent", //缩进
+        // "lineHeight", //行高
+        // "foreColor",
+        // "backColor",
+        // "link",
+        // "list",
+        // "todo",
+        // "justify",
+        // "quote",
+        // "emoticon",
+        "image",
+        // "video",
+        "table",
+        // "code",
+        // "splitLine",
+        "undo",
+        "redo",
+      ];
+      // 带格式粘贴
+      this.editor.config.pasteFilterStyle = false;
+      //忽略粘贴内容中的图片
+      this.editor.config.pasteIgnoreImg = false;
+      this.editor.config.showLinkImg = false;
+      this.editor.config.placeholder = this.placeholder;
+      var that = this;
+      this.editor.config.customUploadImg = function (files, insert) {
+        // const loading = Loading.service({
+        //   lock: true,
+        //   background: 'rgba(0, 0, 0, 0.7)'
+        // });
+        // 图片自定义上传方法
+        var kk = 0
+        for (var i = 0; i < files.length; i++) {
+          var file = files[i];
+          var credentials = {
+            accessKeyId: "AKIATLPEDU37QV5CHLMH",
+            secretAccessKey: "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",
+          }; //秘钥形式的登录上传
+          window.AWS.config.update(credentials);
+          window.AWS.config.region = "cn-northwest-1"; //设置区域
+
+          var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
+          that.proVisible = true
+          if (file) {
+            var params = {
+              Key:
+                file.name.split(".")[0] +
+                new Date().getTime() +
+                "." +
+                file.name.split(".")[file.name.split(".").length - 1],
+              ContentType: file.type,
+              Body: file,
+              "Access-Control-Allow-Credentials": "*",
+              ACL: "public-read",
+            }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
+            var options = {
+              partSize: 2048 * 1024 * 1024,
+              queueSize: 2,
+              leavePartsOnError: true,
+            };
+            bucket
+              .upload(params, options)
+              .on("httpUploadProgress", function (evt) {
+                //这里可以写进度条
+                // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
+              })
+              .send(function (err, data) {
+                kk++
+                if(kk == files.length - 1 || kk > files.length - 1){
+                  that.proVisible = false
+                }
+                // loading.close();
+                if (err) {
+                  that.$message.error("上传失败");
+                } else {
+                  //上传成功处理
+                  insert(data.Location);
+                }
+              });
+          }
+        }
+      };
+      //配置 自定义处理粘贴的文本内容
+      this.editor.config.pasteTextHandle = function (content) {
+        if (content == '' && !content) return ''
+        var str = content
+        str = str.replace(/<xml>[\s\S]*?<\/xml>/ig, '')
+        str = str.replace(/<style>[\s\S]*?<\/style>/ig, '')
+        str = str.replace(/<\/?[^>]*>/g, '')
+        str = str.replace(/[ | ]*\n/g, '\n')
+        str = str.replace(/&nbsp;/ig, '')
+        // console.log('****', content)
+        // console.log('****', str)
+        return str
+      };
+      this.editor.config.onchange = (html) => {
+        this.info_ = html; // 绑定当前逐渐地值
+        this.$emit("change", this.info_); // 将内容同步到父组件中
+      };
+      // 创建富文本编辑器
+      this.editor.create();
+    },
+  },
+};
+</script>  
+  
+<style lang="css" scoped>
+.editor {
+   width: 100%;
+	 height: 100%;
+	 display: flex;
+	 flex-direction: column;
+   /* margin: 10px auto; */
+   position: relative;
+   z-index: 0;
+	 box-sizing: border-box;
+ }
+
+ .toolbar {
+   border: 1px solid #ccc;
+ }
+
+ .text {
+   border: 1px solid #ccc;
+	 flex: 1;
+   /* height: calc(100% - 38px); */
+   overflow: auto;
+ }
+
+
+ /* table 样式 */
+ .cont>>>table {
+  border-top: 1px solid #ccc;
+  border-left: 1px solid #ccc;
+}
+
+.cont>>>table td,
+.cont>>>table th {
+  border-bottom: 1px solid #ccc;
+  border-right: 1px solid #ccc;
+  /* padding: 20px 5px; */
+  padding: 5px 10px;
+  max-width: 0px;
+  height: 30px;
+  vertical-align: baseline;
+}
+
+.cont>>>table th {
+  border-bottom: 2px solid #ccc;
+  text-align: center;
+}
+
+ /* blockquote 样式 */
+ .cont>>>blockquote {
+   display: block;
+   border-left: 8px solid #d0e5f2;
+   padding: 5px 10px;
+   margin: 10px 0;
+   line-height: 1.4;
+   font-size: 100%;
+   background-color: #f1f1f1;
+ }
+
+ /* code 样式 */
+ .cont>>>code {
+   display: inline-block;
+   *display: inline;
+   *zoom: 1;
+   background-color: #f1f1f1;
+   border-radius: 3px;
+   padding: 3px 5px;
+   margin: 0 3px;
+ }
+
+ .cont>>>pre code {
+   display: block;
+ }
+
+ /* ul ol 样式 */
+ .cont>>>ul,
+ ol {
+   margin: 0 !important;
+ }
+
+ /* .cont>>>.w-e-droplist{
+  width: 80px !important;
+ } */
+
+ .mask {
+  background-color: rgb(0 0 0 / 30%);
+  /* position: fixed; */
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99999;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.mask2 {
+  position: fixed !important;
+  z-index: 999999;
+}
+
+.progressBox {
+  width: 300px;
+  height: 150px;
+  background: #fff;
+  border-radius: 10px;
+  box-shadow: 0 0 6px 1px #bfbfbf;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+}
+
+.progressBox .lbox {
+  height: 100px;
+  font-size: 16px;
+  display: flex;
+  align-items: center;
+}
+
+.progressBox .lbox img {
+  width: 40px;
+  margin-right: 20px;
+}
+
+.progressBox>>>.el-progress-bar__outer {
+  background-color: #d1dfff !important;
+}
+
+.progressBox .lbox {
+  height: 100px;
+  font-size: 19px;
+  display: flex;
+  align-items: center;
+}
+
+.progressBox .lbox img {
+  width: 40px;
+  margin-right: 20px;
+}
+</style>  

+ 448 - 98
src/views/classObserve/homePage.vue

@@ -33,23 +33,118 @@
           <!-- <img src="../../assets/images/classObserve/lianjie.png" alt="" /> -->
         </span>
       </div>
+      <div class="tit" v-else></div>
       <div class="teaInfo" @click="cutPage(3)" v-if="tid">
         <div class="teaName">{{ bmData.jsonData ? bmData.jsonData.teacherName : '' }}</div>
         <div class="classInfo" v-if="bmData.jsonData && bmData.jsonData.grade">{{ bmData.jsonData.grade }}</div>
         <div class="classInfo" v-if="bmData.jsonData && bmData.jsonData.subject">{{ bmData.jsonData.subject }}</div>
         <img src="../../assets/images/classObserve/fillInfo.svg" alt="" />
       </div>
+      <div v-else class="teaInfo"></div>
       <!-- <div class="noTid" v-if="!tid">
 				<div class="nt_btn">创建新的课堂</div>
 			</div> -->
       <div class="chat">
+        <div class="transcriptionArea" v-if="tid">
+          <div class="ta_btn">
+            <span>
+              <img src="../../assets/images/classObserve/Vector2.svg" v-if="[0].includes(showTranscriptType)" />
+              <img src="../../assets/images/classObserve/Vector.svg" v-else @click.stop="changeTranscriptType(0)" />
+            </span>
+            <span>
+              <img src="../../assets/images/classObserve/zhuanlu2.svg" v-if="[1].includes(showTranscriptType)" />
+              <img src="../../assets/images/classObserve/zhuanlu.svg" v-else @click.stop="changeTranscriptType(1)" />
+            </span>
+          </div>
+          <div
+            v-show="showTranscriptType == 0"
+            ref="transcriptionDataRef"
+            class="chatTxt"
+            v-text="bmData.jsonData ? bmData.jsonData.transcriptionData : ''"
+          ></div>
+          <div v-show="showTranscriptType == 1" class="editorBarData">
+            <template v-if="bmData.jsonData">
+              <div class="ebd_save" v-if="false">
+                <van-popover placement="left" v-model="showEditorBarDataPopover" trigger="click">
+                  <div class="ebd_s_btnArea">
+                    <el-button size="small" type="primary" @click.stop="speakerCodingFn">说话人编码</el-button>
+
+                    <el-button size="small" type="primary" @click.stop="behaviorCodingFn">行为编码</el-button>
+
+                    <el-button size="small" type="primary" @click.stop="saveEditorBarFn">保存</el-button>
+                  </div>
+                  <template #reference>
+                    <svg
+                      t="1724054294290"
+                      viewBox="0 0 1024 1024"
+                      version="1.1"
+                      xmlns="http://www.w3.org/2000/svg"
+                      p-id="2400"
+                      width="200"
+                      height="200"
+                      :style="showEditorBarDataPopover ? 'transform: rotate(180deg);' : ''"
+                    >
+                      <path
+                        d="M704 908.8 307.2 512 704 115.2c25.6-25.6 25.6-70.4 0-96-25.6-25.6-70.4-25.6-96 0L166.4 460.8C147.2 480 140.8 492.8 140.8 512s6.4 32 19.2 51.2l441.6 441.6c25.6 25.6 70.4 25.6 96 0C729.6 979.2 729.6 934.4 704 908.8z"
+                        p-id="2401"
+                      ></path>
+                    </svg>
+                  </template>
+                </van-popover>
+              </div>
+
+              <EditorBar v-model="bmData.jsonData.editorBarData.content">
+                <!-- <el-popover placement="top" trigger="hover">
+                <el-button size="small" @click.stop="startContinuousJobs('role')">
+                  说话人编码
+                </el-button>
+                <el-button size="small" @click.stop="startContinuousJobs('actionType')">
+                  行为编码
+                </el-button>
+                <el-button
+                  slot="reference"
+                  style="position: absolute; bottom: 20px; right: 90px; z-index: 10002"
+                  size="small"
+                  type="primary"
+                  >自动编码</el-button
+                >
+              </el-popover>
+              <el-button
+                style="position: absolute; bottom: 20px; right: 20px; z-index: 10002"
+                size="small"
+                type="primary"
+                @click.stop="saveEditorBar(true)"
+                >保存</el-button
+              > -->
+              </EditorBar>
+            </template>
+          </div>
+        </div>
+        <img
+          src="../../assets/images/classObserve/waveanimation.png"
+          alt=""
+          v-if="
+            (imageList.jsonData ? imageList.jsonData.fileList.length == 0 : true) ||
+              [1, 2, 3].includes(recordedForm.status)
+          "
+        />
+        <div class="time" v-if="[1, 2, 3].includes(recordedForm.status)">
+          {{ recordedForm.time }}
+        </div>
+				<div class="time" v-else></div>
         <div
-          ref="transcriptionDataRef"
-          class="chatTxt"
-          v-text="bmData.jsonData ? bmData.jsonData.transcriptionData : ''"
-        ></div>
-        <img src="../../assets/images/classObserve/waveanimation.png" alt="" />
-        <div class="time">{{ recordedForm.time }}</div>
+          class="sourceFile"
+          v-if="
+            (imageList.jsonData ? imageList.jsonData.fileList.length != 0 : false) &&
+              ![1, 2, 3].includes(recordedForm.status)
+          "
+        >
+          <mini-audio
+            v-if="imageList.jsonData ? imageList.jsonData.fileList.length != 0 : false"
+            :audio-source="imageList.jsonData.fileList[0].url"
+            class="audio_class"
+          ></mini-audio>
+        </div>
       </div>
       <div class="controlArea" v-loading="recordedForm.loading">
         <div class="ca_left">
@@ -197,6 +292,8 @@ import _ from 'lodash'
 import Papa from 'papaparse'
 import '../../utils/aws-sdk-2.235.1.min.js'
 import { upload_file_knowledgeRequest } from '@/api/classObserve.js'
+let OpenCC = require('opencc-js')
+import EditorBar from './components/wangEnduit.vue'
 
 const getFile = url => {
   return new Promise((resolve, reject) => {
@@ -248,12 +345,21 @@ export default {
     tid: {
       type: String,
       default: ''
+    },
+    imageList: {
+      type: Object,
+      default: () => {}
     }
   },
+  components: {
+    EditorBar
+  },
   data() {
     return {
       isParse: false,
       loading: false,
+      showTranscriptType: 0, //0:原文速览   1;转录文稿
+      showEditorBarDataPopover: false,
       recordedForm: {
         time: '00:00:00', //时间
         status: 0, //0--未录音  1--正在录音  2--暂停  3--录音结束
@@ -280,6 +386,51 @@ export default {
     }
   },
   methods: {
+    changeTranscriptType(newType) {
+      this.showTranscriptType = newType
+    },
+    saveEditorBarFn() {
+      Dialog.confirm({
+        title: '保存',
+        message: `确定保存转录文稿?`
+      })
+        .then(() => {
+          console.log('保存')
+          this.showEditorBarDataPopover = false
+        })
+        .catch(() => {
+          console.log('不保存')
+          this.showEditorBarDataPopover = true
+        })
+    },
+    speakerCodingFn() {
+      Dialog.confirm({
+        title: '说话人编码',
+        message: `确定获取说话人编码?`
+      })
+        .then(() => {
+          console.log('获取说话人编码')
+          this.showEditorBarDataPopover = false
+        })
+        .catch(() => {
+          console.log('不获取')
+          this.showEditorBarDataPopover = true
+        })
+    },
+    behaviorCodingFn() {
+      Dialog.confirm({
+        title: '行为编码',
+        message: `确定获取行为编码?`
+      })
+        .then(() => {
+          console.log('获取行为编码')
+          this.showEditorBarDataPopover = false
+        })
+        .catch(() => {
+          console.log('不获取')
+          this.showEditorBarDataPopover = true
+        })
+    },
     changeLanguageFn(newIndex) {
       if (this.isParse) return this.$toast('正在录音中...')
       this.choiceLanguageIndex = newIndex
@@ -359,7 +510,7 @@ export default {
         this.uploadFile(file, { changeText: false, flag: true })
       }
     },
-    startRecord() {
+    startRecord(type = true) {
       if (this.recordedForm.loading) return this.$toast('请稍等')
       if (!this.tid) {
         return Dialog.confirm({
@@ -368,7 +519,7 @@ export default {
         })
           .then(() => {
             return this.$parent.addNewCourseByDefault().then(_ => {
-              this.startRecord()
+              this.startRecord(false)
             })
           })
           .catch(_ => {
@@ -379,86 +530,89 @@ export default {
       // console.log('开始录音')
       if (this.uploadFileLoading) return this.$toast('请稍等...')
       if ([0].includes(this.recordedForm.status)) {
-        Dialog.confirm({
-          title: '开始录音',
-          message: `确定开始录音?`
-        })
-          .then(() => {
-            let iiframe = this.$refs['iiframe']
-						console.log(iiframe.contentWindow.window)
-						console.log(iiframe.contentWindow)
-            // 设置语言
-            iiframe.contentWindow.window.document.getElementById(
-              'languageOptions'
-            ).selectedIndex = this.choiceLanguageIndex
+        if (type) {
+          return Dialog.confirm({
+            title: '开始录音',
+            message: `确定开始录音?`
+          })
+            .then(() => {
+              this.startRecord(false)
+            })
+            .catch(e => {
+              console.log(e)
+              console.log('不录音')
+            })
+        }
+        console.log('开始录音')
+        let iiframe = this.$refs['iiframe']
+        // console.log(iiframe.contentWindow.window)
+        // console.log(iiframe.contentWindow)
+        // 设置语言
+        iiframe.contentWindow.window.document.getElementById('languageOptions').selectedIndex = this.choiceLanguageIndex
 
-            iiframe.contentWindow.testdoContinuousPronunciationAssessment()
+        iiframe.contentWindow.testdoContinuousPronunciationAssessment()
 
-            this.recordedForm.status = 1
-            this.$toast('已开始录音')
-            this.recordedForm.timer = setInterval(() => {
-              this.recordedForm.timeDuration += 1
-              this.recordedForm.time = this.updateRecordedTime({
-                duration: this.recordedForm.timeDuration
-              })
-            }, 1000)
+        this.recordedForm.status = 1
+        this.showTranscriptType = 1
+        this.$toast('已开始录音')
+        this.recordedForm.timer = setInterval(() => {
+          this.recordedForm.timeDuration += 1
+          this.recordedForm.time = this.updateRecordedTime({
+            duration: this.recordedForm.timeDuration
+          })
+        }, 1000)
 
-            let flag = true
-            this.recordedForm.textList = []
-            this.recordedForm.timeDuration = 0
-            this.recordedForm.startTime = 1
-            this.recordedForm.endTime = 0
+        let flag = true
+        this.recordedForm.textList = []
+        this.recordedForm.timeDuration = 0
+        this.recordedForm.startTime = 1
+        this.recordedForm.endTime = 0
 
-            iiframe.contentWindow.onRecognizedResult = e => {
-              this.recordedForm.endTime = this.recordedForm.timeDuration
-              if (flag) {
-                // this.controlsStatus = 1
-                // this.showIndexPage = false
-                // this.pageStatus = 2
-                this.$parent.bmData.jsonData.editorBarData.type = '0'
-                flag = false
-                this.uploadFileLoading = false
-                this.$parent.bmData.jsonData.transcriptionData = ''
-                this.$parent.bmData.jsonData.editorBarData.content = ''
-                this.recordedForm.textList = []
-              }
-              let privText = e.privText
-              if (privText == undefined || privText == 'undefined') return
-              console.log('👇转译对象👇')
-              console.log(e)
-              console.log('👇转译结果👇')
-              console.log(privText)
-              this.recordedForm.textList.push({
-                value: privText,
-                startTime: this.updateRecordedTime({
-                  duration: this.recordedForm.startTime
-                }),
-                endTime: this.updateRecordedTime({
-                  duration: this.recordedForm.endTime
-                }),
-                time: this.updateRecordedTime({
-                  duration: this.recordedForm.endTime - this.recordedForm.startTime
-                })
-              })
-              this.recordedForm.startTime = this.recordedForm.timeDuration + 1
-              this.$parent.bmData.jsonData.transcriptionData += privText
-              this.$nextTick(
-                () => (this.$refs.transcriptionDataRef.scrollTop = this.$refs.transcriptionDataRef.scrollHeight)
-              )
-              let _result = `<table border="0" width="100%" cellpadding="0" cellspacing="0" style="text-align: center"><tbody><tr><th>序号</th><th>开始时间</th><th>结束时间</th><th>发言内容</th><th>时长</th><th>说话人身份</th><th>行为编码</th></tr>`
-              this.recordedForm.textList.forEach((item, index) => {
-                _result += `<tr><td>${index + 1}</td><td>${item.startTime}</td><td>${item.endTime}</td><td>${
-                  item.value
-                }</td><td>${item.time}</td><td></td><td></td></tr>`
-              })
-              _result += `<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr></tbody></table>`
-              this.$parent.bmData.jsonData.editorBarData.content = _result
-            }
+        iiframe.contentWindow.onRecognizedResult = e => {
+          this.recordedForm.endTime = this.recordedForm.timeDuration
+          if (flag) {
+            // this.controlsStatus = 1
+            // this.showIndexPage = false
+            // this.pageStatus = 2
+            this.$parent.bmData.jsonData.editorBarData.type = '0'
+            flag = false
+            this.uploadFileLoading = false
+            this.$parent.bmData.jsonData.transcriptionData = ''
+            this.$parent.bmData.jsonData.editorBarData.content = ''
+            this.recordedForm.textList = []
+          }
+          let privText = e.privText
+          if (privText == undefined || privText == 'undefined') return
+          console.log('👇转译对象👇')
+          console.log(e)
+          console.log('👇转译结果👇')
+          console.log(privText)
+          this.recordedForm.textList.push({
+            value: privText,
+            startTime: this.updateRecordedTime({
+              duration: this.recordedForm.startTime
+            }),
+            endTime: this.updateRecordedTime({
+              duration: this.recordedForm.endTime
+            }),
+            time: this.updateRecordedTime({
+              duration: this.recordedForm.endTime - this.recordedForm.startTime
+            })
           })
-          .catch((e) => {
-						console.log(e)
-            console.log('不录音')
+          this.recordedForm.startTime = this.recordedForm.timeDuration + 1
+          this.$parent.bmData.jsonData.transcriptionData += privText
+          this.$nextTick(
+            () => (this.$refs.transcriptionDataRef.scrollTop = this.$refs.transcriptionDataRef.scrollHeight)
+          )
+          let _result = `<table border="0" width="100%" cellpadding="0" cellspacing="0" style="text-align: center"><tbody><tr><th>序号</th><th>开始时间</th><th>结束时间</th><th>发言内容</th><th>时长</th><th>说话人身份</th><th>行为编码</th></tr>`
+          this.recordedForm.textList.forEach((item, index) => {
+            _result += `<tr><td>${index + 1}</td><td>${item.startTime}</td><td>${item.endTime}</td><td>${
+              item.value
+            }</td><td>${item.time}</td><td></td><td></td></tr>`
           })
+          _result += `<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr></tbody></table>`
+          this.$parent.bmData.jsonData.editorBarData.content = _result
+        }
       } else if ([1, 2].includes(this.recordedForm.status)) {
         this.$toast.fail('正在录音中')
       } else {
@@ -499,6 +653,7 @@ export default {
         iiframe.contentWindow.testdoContinuousPronunciationAssessment()
         // this.controlsStatus = 1;
         this.recordedForm.status = 1
+        this.showTranscriptType = 1
         this.$toast('已继续录音')
         this.recordedForm.loading = false
         this.recordedForm.timer = setInterval(() => {
@@ -670,11 +825,16 @@ export default {
                         _this.showIndexPage = false
                         _this.pageStatus = 2
                         _this.$parent.bmData.jsonData.editorBarData.type = '0'
+                        let converter = OpenCC.Converter({
+                          from: 'hk',
+                          to: 'cn'
+                        })
                         // _this.$parent.bmData.jsonData.transcriptionData = _res.data
                         if (flag) {
-                          const arr = Papa.parse(_res.data, {
+                          let arr = Papa.parse(_res.data, {
                             header: false
                           }).data
+                          arr = arr.filter(i => _.get(i, 0) != converter('序号'))
                           const _editorBarDataContent = `<table border="0" width="100%" cellpadding="0" cellspacing="0" style="text-align: center"><tbody><tr><th>序号</th><th>开始时间</th><th>结束时间</th><th>发言内容</th><th>时长</th><th>说话人身份</th><th>行为编码</th></tr>${arr
                             .map(
                               row =>
@@ -803,6 +963,97 @@ export default {
       return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds
         .toString()
         .padStart(2, '0')}`
+    },
+    wavFileGetText(audioFile) {
+      let flag = true
+      let textList = []
+      let iiframe = this.$refs['iiframe']
+
+      iiframe.contentWindow.window.document.getElementById('languageOptions').selectedIndex = this.choiceLanguageIndex
+      this.bmData.jsonData.transcriptionData = ''
+      iiframe.contentWindow.onRecognizedResult = () => {
+        if (flag) {
+          // 这里上传文件
+          // _this.uploadWavFile(audioFile);
+
+          this.bmData.jsonData.editorBarData.type = '0'
+          flag = false
+          this.uploadFileLoading = false
+          this.bmData.jsonData.transcriptionData = ''
+          this.bmData.jsonData.editorBarData.content = ''
+          textList = []
+        }
+        // this.showGetTextLoading = true;
+        let privText = e.privText
+        console.log('👇转译对象👇')
+        console.log(e)
+        console.log('👇转译结果👇')
+        console.log(privText)
+        textList.push({
+          value: privText,
+          startTime: '',
+          endTime: '',
+          time: ''
+        })
+        this.bmData.jsonData.transcriptionData += privText
+
+        let _result = `
+				<table
+						border="0"
+						width="100%"
+						cellpadding="0"
+						cellspacing="0"
+						style="text-align: center"
+					>
+						<tbody>
+							<tr>
+								<th>序号</th>
+								<th>开始时间</th>
+								<th>结束时间</th>
+								<th>发言内容</th>
+								<th>时长</th>
+								<th>说话人身份</th>
+								<th>行为编码</th>
+						</tr>
+				`
+        textList.forEach((item, index) => {
+          _result += `<tr>
+							<td>${index + 1}</td>
+							<td></td>
+							<td></td>
+							<td>${item.value}</td>
+							<td></td>
+							<td></td>
+							<td></td>
+						</tr>`
+        })
+        _result += `
+				<tr>
+							<td></td>
+							<td></td>
+							<td></td>
+							<td></td>
+							<td></td>
+							<td></td>
+							<td></td>
+						</tr>
+					</tbody>
+				</table>`
+        this.bmData.jsonData.editorBarData.content = _result
+        // _this.editorBarData.content += privText;
+      }
+
+      iiframe.contentWindow.onSessionStopped = function(e) {
+        console.log('转译完成')
+        console.log(e)
+        this.$toast.success('转译完成')
+        // _this.showGetTextLoading = false;
+        this.saveEditorBar()
+      }
+
+      iiframe.contentWindow.doContinuousPronunciationAssessment('', {
+        files: [audioFile]
+      })
     }
   }
 }
@@ -814,7 +1065,7 @@ export default {
   height: calc(100%);
   display: flex;
   flex-direction: column;
-  justify-content: space-between;
+  // justify-content: space-between;
   overflow: auto;
 }
 /deep/.van-action-sheet {
@@ -822,10 +1073,11 @@ export default {
 }
 .top {
   width: 100%;
+  height: 150px;
   box-sizing: border-box;
   padding-top: 15px;
   background-color: rgba(54, 129, 252, 1);
-  flex: 1;
+  // flex: 1;
   box-sizing: border-box;
   border-radius: 0 0 23% 23%;
   display: flex;
@@ -854,7 +1106,8 @@ export default {
 }
 .brief {
   width: 100%;
-  padding-bottom: 20px;
+  height: 80px;
+  // padding-bottom: 20px;
   .txt {
     height: 50px;
     display: flex;
@@ -873,12 +1126,13 @@ export default {
 }
 .FunctionalArea {
   width: 100%;
+  height: calc(100vh - 230px);
   padding: 0 30px;
   box-sizing: border-box;
   .tit {
     display: flex;
     justify-content: space-between;
-
+    height: 30px;
     div {
       font-weight: 600;
       font-size: 22px;
@@ -893,6 +1147,10 @@ export default {
     display: flex;
     justify-content: flex-start;
     padding: 10px 0;
+    height: 15px;
+    display: flex;
+    align-items: center;
+    // background-color: yellow;
     .teaName {
       padding-right: 10px;
       font-size: 14px;
@@ -907,11 +1165,35 @@ export default {
       padding: 0 10px;
       margin-right: 10px;
       color: rgba(0, 0, 0, 0.6);
-			
     }
   }
 }
 .chat {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  flex: 1;
+  height: calc(100% - 205px);
+  justify-content: flex-end;
+  img {
+    width: 100%;
+    height: 100px;
+  }
+  .time {
+    color: rgba(54, 129, 252, 1);
+    width: 100%;
+    font-size: 12px;
+		height: 15px;
+    display: flex;
+		align-items: center;
+    justify-content: center;
+  }
+}
+
+.transcriptionArea {
+  width: 100%;
+  height: calc(100% - 115px);
+  position: relative;
   .chatTxt {
     font-weight: 400;
     font-size: 14px;
@@ -921,20 +1203,57 @@ export default {
     // -webkit-box-orient: vertical;
     // overflow: hidden;
     // text-overflow: ellipsis;
-    max-height: 150px;
-    min-height: 100px;
+		min-height: 100px;
+    height: 100%;
     overflow: auto;
     color: rgba(0, 0, 0, 0.6);
   }
-  img {
-    width: 100%;
+  .editorBarData {
+    min-height: 100px;
+    // max-height: 10vh;
+    height:100%;
+    position: relative;
+    .ebd_save {
+      left: 100%;
+      bottom: 0;
+      width: 28px;
+      height: 40px;
+      position: absolute;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      border-radius: 0 10px 10px 0;
+      background-color: #fff;
+      box-sizing: border-box;
+      border: solid 1px #cccccc;
+      border-left: none;
+      svg {
+        width: 17px;
+        height: 17px;
+        transition: 0.3s;
+      }
+    }
   }
-  .time {
-    color: rgba(54, 129, 252, 1);
-    width: 100%;
-    font-size: 12px;
+  .ta_btn {
+    width: auto;
+    height: auto;
+    position: absolute;
+    right: 0;
+    bottom: 100%;
     display: flex;
-    justify-content: center;
+    span {
+      width: 22px;
+      height: 22px;
+      padding: 5px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      margin-left: 5px;
+      img {
+        width: 22px;
+        height: 22px;
+      }
+    }
   }
 }
 .controlArea {
@@ -989,7 +1308,7 @@ export default {
   display: flex;
   justify-content: space-around;
   margin-bottom: 10px;
-
+  height: 50px;
   div {
     flex: 1;
     display: flex;
@@ -1145,4 +1464,35 @@ export default {
     color: rgba(54, 129, 252, 1);
   }
 }
+
+.audio_class {
+  /* width: 100% !important; */
+  /* height: 100% !important; */
+  background: #ccc !important;
+  // margin: 0 !important;
+  width: 100% !important;
+  box-sizing: border-box;
+  // margin: 20px 0 !important;
+}
+
+.sourceFile {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100px;
+}
+.audio_class >>> .slider .process {
+  background: #000;
+}
+
+.ebd_s_btnArea {
+  width: auto;
+  height: 45px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 0 10px;
+  // background-color: red;
+}
 </style>

+ 17 - 5
src/views/classObserve/index.vue

@@ -9,6 +9,7 @@
       :classList="classList"
       :tid="tid"
       :bmData="bmData"
+      :imageList="imageList"
     ></homePage>
     <bindFrom
       ref="bindFromRef"
@@ -40,7 +41,7 @@
       :analysisList="analysisList"
       :fileId="fileId"
       :dataList="dataList"
-			:tid="tid"
+      :tid="tid"
     />
   </div>
 </template>
@@ -90,7 +91,13 @@ export default {
           name: '',
           studentNum: 0,
           subject: '',
-          textbook: ''
+          textbook: '',
+          transcriptionData: '',
+          editorBarData: {
+            type: '0',
+            content: '',
+            url: ''
+          }
         }
       },
       imageList: {},
@@ -432,7 +439,7 @@ export default {
       delClassRequest({ tid: item.id }).then(_ => {
         this.$toast.success('删除成功')
         this.getCourseList().then(_ => {
-					if (item.value == this.tid) {
+          if (item.value == this.tid) {
             this.tid = ''
             this.fileId = ''
             this.fileIdId = ''
@@ -449,7 +456,13 @@ export default {
                 name: '',
                 studentNum: 0,
                 subject: '',
-                textbook: ''
+                textbook: '',
+                transcriptionData: '',
+                editorBarData: {
+                  type: '0',
+                  content: '',
+                  url: ''
+                }
               }
             }
             this.imageList = {}
@@ -741,7 +754,6 @@ export default {
       this.fileIdId = ''
       this.fileId = ''
       getObsRequest(pram).then(res => {
-        console.log(res)
         let _data = res.FunctionResponse.result.length ? JSON.parse(res.FunctionResponse.result) : []
         if (_data.length <= 0) return
         this.fileIdId = _data[0].id

+ 15 - 0
src/views/classObserve/transcript.vue

@@ -0,0 +1,15 @@
+<template>
+	<div>
+		转录文稿
+	</div>
+</template>
+
+<script>
+	export default {
+		
+	}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff