lsc 2 rokov pred
rodič
commit
a30aa14594

+ 28 - 0
index.html

@@ -37,6 +37,34 @@
 
 </html>
 <script>
+  function stopSafari() {
+    //阻止safari浏览器双击放大功能
+    let lastTouchEnd = 0  //更新手指弹起的时间
+    document.documentElement.addEventListener("touchstart", function (event) {
+      //多根手指同时按下屏幕,禁止默认行为
+      if (event.touches.length > 1) {
+        event.preventDefault();
+      }
+    });
+    document.documentElement.addEventListener("touchend", function (event) {
+      let now = (new Date()).getTime();
+      if (now - lastTouchEnd <= 300) {
+        //当两次手指弹起的时间小于300毫秒,认为双击屏幕行为
+        event.preventDefault();
+      } else { // 否则重新手指弹起的时间
+        lastTouchEnd = now;
+      }
+    }, false);
+    //阻止双指放大页面
+    document.documentElement.addEventListener("gesturestart", function (event) {
+      event.preventDefault();
+    });
+  }
+
+  window.onload = () => {
+    stopSafari();
+  }
+  
   document.domain = "cocorobo.cn"
 
 </script>

+ 32 - 12
js/jietu2.js

@@ -41,7 +41,7 @@ function dataURLtoFile_shishi(dataurl, filename) {
 }
 
 
-function beforeUpload_shishi(nfile, uid, cid, stage, task, tool, loading, atool) {
+function beforeUpload_shishi(nfile, uid, cid, stage, task, tool, loading, atool, text) {
   // loading.style.display = 'flex'
   // top.document.getElementById(loading);
   //  document.body.appendChild(_loading)
@@ -83,12 +83,12 @@ function beforeUpload_shishi(nfile, uid, cid, stage, task, tool, loading, atool)
           url: data.Location,
           uid: file.uid,
         }
-        addSWork_shishi(uid, cid, stage, task, tool, data.Location, loading, atool)
+        addSWork_shishi(uid, cid, stage, task, tool, data.Location, loading, atool, text)
       });
   }
 }
 
-function addSWork_shishi(uid, cid, stage, task, tool, a, loading, atool) {
+function addSWork_shishi(uid, cid, stage, task, tool, a, loading,atool, text) {
   let params = {
     uid: uid,
     cid: cid,
@@ -97,15 +97,16 @@ function addSWork_shishi(uid, cid, stage, task, tool, a, loading, atool) {
     tool: tool,
     content: a,
     type: 1,
-    atool:atool
+    atool:atool,
+    text:text
     // upload: JSON.stringify(this.imgFileUp),
   };
   $.ajax({
-    type: 'GET',
-    url: 'https://pbl.cocorobo.cn/api/pbl/addCourseWorks3',
+    type: 'POST',
+    url: 'https://pbl.cocorobo.cn/api/pbl/addCourseWorks4',
     data: params,
     dataType: "json",
-    success: (data) => {
+    error: (XMLHttpRequest, textStatus, errorThrown) => {
       var _a = document.getElementsByTagName("img")
       for (var i = 0; i < _a.length; i++) {
         _a[i].removeAttribute("crossorigin")
@@ -115,14 +116,33 @@ function addSWork_shishi(uid, cid, stage, task, tool, a, loading, atool) {
       _div.style = "width:100%;height:100%;background:#0000008f;position:fixed;top:0;left:0;z-index:99999999999999;display: flex;justify-content: center;align-items: center;"
       let _inner = document.createElement('div')
       _inner.style = "color: #fff;padding: 15px;background: #00000070;border-radius: 5px;font-size: 18px;"
-      _inner.innerHTML = "截图上传成功"
+      _inner.innerHTML = "上传失败,网络错误"
       _div.appendChild(_inner)
       document.body.appendChild(_div)
       setTimeout(() => {
-        //  document.body.removeChild(_loading)
         document.body.removeChild(_div)
-      }, 2000);
-      console.log("截图上传成功");
+      }, 1000);
+    },
+    success: (data) => {
+      setTimeout(() =>{
+        var _a = document.getElementsByTagName("img")
+        for (var i = 0; i < _a.length; i++) {
+          _a[i].removeAttribute("crossorigin")
+        }
+        top.document.getElementById(loading).children[0].style.display = "none"
+        let _div = document.createElement('div')
+        _div.style = "width:100%;height:100%;background:#0000008f;position:fixed;top:0;left:0;z-index:99999999999999;display: flex;justify-content: center;align-items: center;"
+        let _inner = document.createElement('div')
+        _inner.style = "color: #fff;padding: 15px;background: #00000070;border-radius: 5px;font-size: 18px;"
+        _inner.innerHTML = "截图上传成功"
+        _div.appendChild(_inner)
+        document.body.appendChild(_div)
+        setTimeout(() => {
+          //  document.body.removeChild(_loading)
+          document.body.removeChild(_div)
+        }, 1000);
+        console.log("截图上传成功");
+      },3000)
     }
   })
-}
+}

+ 9 - 7
src/common/jietu2.js

@@ -41,7 +41,7 @@ function dataURLtoFile_shishi(dataurl, filename) {
 }
 
 
-function beforeUpload_shishi(nfile, uid, cid, stage, task, tool, loading) {
+function beforeUpload_shishi(nfile, uid, cid, stage, task, tool, loading, atool, text) {
   // loading.style.display = 'flex'
   // top.document.getElementById(loading);
   //  document.body.appendChild(_loading)
@@ -83,12 +83,12 @@ function beforeUpload_shishi(nfile, uid, cid, stage, task, tool, loading) {
           url: data.Location,
           uid: file.uid,
         }
-        addSWork_shishi(uid, cid, stage, task, tool, data.Location, loading)
+        addSWork_shishi(uid, cid, stage, task, tool, data.Location, loading, atool, text)
       });
   }
 }
 
-function addSWork_shishi(uid, cid, stage, task, tool, a, loading) {
+function addSWork_shishi(uid, cid, stage, task, tool, a, loading,atool, text) {
   let params = {
     uid: uid,
     cid: cid,
@@ -97,11 +97,13 @@ function addSWork_shishi(uid, cid, stage, task, tool, a, loading) {
     tool: tool,
     content: a,
     type: 1,
+    atool:atool,
+    text:text
     // upload: JSON.stringify(this.imgFileUp),
   };
   $.ajax({
-    type: 'GET',
-    url: 'https://pbl.cocorobo.cn/api/pbl/addCourseWorks2',
+    type: 'POST',
+    url: 'https://pbl.cocorobo.cn/api/pbl/addCourseWorks4',
     data: params,
     dataType: "json",
     error: (XMLHttpRequest, textStatus, errorThrown) => {
@@ -114,7 +116,7 @@ function addSWork_shishi(uid, cid, stage, task, tool, a, loading) {
       _div.style = "width:100%;height:100%;background:#0000008f;position:fixed;top:0;left:0;z-index:99999999999999;display: flex;justify-content: center;align-items: center;"
       let _inner = document.createElement('div')
       _inner.style = "color: #fff;padding: 15px;background: #00000070;border-radius: 5px;font-size: 18px;"
-      _inner.innerHTML = "上传失败,网络错误终端"
+      _inner.innerHTML = "上传失败,网络错误"
       _div.appendChild(_inner)
       document.body.appendChild(_div)
       setTimeout(() => {
@@ -143,4 +145,4 @@ function addSWork_shishi(uid, cid, stage, task, tool, a, loading) {
       },3000)
     }
   })
-}
+}

+ 112 - 3
src/components/GM/studyStudentGM.vue

@@ -66,6 +66,8 @@
             <div class="returnBtn" @click="nextOrpreSteps(0)">上一步</div>
             <div class="returnBtn" @click="nextOrpreSteps(1)">下一步</div>
             <div class="returnBtn" @click="allScrell">全屏</div>
+            <div class="returnBtn" @click="startRecording" v-if="(!videoStart && tType == 1 || tType == 4)">开始录制</div>
+            <div class="returnBtn" @click="stopRecording" v-else-if="(tType == 1 || tType == 4)">停止录制</div>
             <div class="returnBtn" @click="juriVisible = true" v-if="tType == 1">
               权限
             </div>
@@ -2755,6 +2757,7 @@ import SeeBoard from "../tools/seeBoard";
 import * as imageConversion from "image-conversion";
 import Audio from "../components/audioGM.vue";
 import ImgDraw from "../tools/imgDraw/imgDraw";
+import RecordRTC from 'recordrtc';
 
 export default {
   components: {
@@ -2990,6 +2993,8 @@ export default {
       pzType: 1,
       wScore: 0,
       scoreDetail: "",
+      videoStart: false,
+				recorder: null,
     };
   },
   methods: {
@@ -6112,7 +6117,110 @@ export default {
             });
         })
         .catch(() => { });
-    }
+    },
+    /**
+			 * 开始录制
+			 */
+			startRecording(callback){
+				this.captureScreen((screenStream)=>{
+					this.addStreamStopListener(screenStream,()=>{
+						console.log("流停止监听");
+						this.$emit("streamStop",{})
+						// this.stopRecording();
+					});
+					var options = {
+					    type: 'video',
+					    mimeType: 'video/webm',
+					    disableLogs: false,
+					    getNativeBlob: false, // enable it for longer recordings
+						ignoreMutedMedia:false
+					};
+					// this.video.srcObject = screenStream;
+					this.recorder = RecordRTC(screenStream, options);
+					this.recorder.startRecording();
+					this.recorder.screen = screenStream;
+					this.videoStart = true;
+					// callback(true);
+				});
+			},
+			/**
+			 * 停止录制
+			 */
+			stopRecording(callback){
+				this.recorder.stopRecording(()=>{
+					// this.video.src = this.video.srcObject = null;
+					// this.video.src = URL.createObjectURL(this.recorder.getBlob());
+					const url = URL.createObjectURL(this.recorder.getBlob());
+					const a = document.createElement("a");//this.fileName+
+					let videoFile = new File([this.recorder.getBlob()], this.courseDetail.title+"录屏.mp4", {
+						type: 'video/mp4'  
+					})
+					let downloadUrl = URL.createObjectURL(videoFile);
+					document.body.appendChild(a);
+					a.style.display = "none";
+					a.href = url;
+					a.download = this.courseDetail.title+"录屏.mp4";//this.fileName + 
+					a.click();
+					this.recorder.screen.stop();
+					this.recorder.destroy();
+					this.recorder = null;
+					this.videoStart = false;
+					// callback(false);
+				});
+			},
+			//初始化
+			captureScreen(callback) {
+				if (navigator.getDisplayMedia) {
+					//录制结束,文件下载
+				    navigator.getDisplayMedia({
+				        video: true
+				    }).then(screenStream => {
+						navigator.mediaDevices.getUserMedia({audio:true}).then((mic)=>{
+						    screenStream.addTrack(mic.getTracks()[0]);
+							callback(screenStream);
+						});
+				    }).catch(function(error) {
+						console.log('error',error);
+				    });
+				} else if (navigator.mediaDevices.getDisplayMedia) {
+				    navigator.mediaDevices.getDisplayMedia({
+				        video: true
+				    }).then(screenStream => {
+						navigator.mediaDevices.getUserMedia({audio:true}).then((mic)=>{
+						    screenStream.addTrack(mic.getTracks()[0]);
+							callback(screenStream);
+						});
+				    }).catch(function(error) {
+						console.log('error',error);
+				    });
+				} else {
+				    var error = 'getDisplayMedia API are not supported in this browser.';
+				   console.log('error',error);
+				    alert(error);
+				}
+			},
+			
+			//流监听
+			addStreamStopListener(stream, callback) {
+			    stream.addEventListener('ended', function () {
+			        callback();
+			        callback = function () { };
+			    }, false);
+			    stream.addEventListener('inactive', function () {
+			        callback();
+			        callback = function () { };
+			    }, false);
+			    stream.getTracks().forEach(function (track) {
+			        track.addEventListener('ended', function () {
+			            callback();
+			            callback = function () { };
+			        }, false);
+			        track.addEventListener('inactive', function () {
+			            callback();
+			            callback = function () { };
+			        }, false);
+			    });
+			},
   },
   directives: {
     // 使用局部注册指令的方式
@@ -6808,7 +6916,7 @@ export default {
   display: flex;
   flex-direction: row;
   align-items: center;
-  width: calc(100% - 420px);
+  width: calc(100% - 520px);
 }
 
 .courseIndex>div:nth-child(1) {
@@ -6825,7 +6933,8 @@ export default {
 
 .courseIndex>div:nth-child(2) {
   font-size: 23px;
-  width: 300px;
+  /* width: 300px; */
+  max-width: calc(100% - 180px);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;

+ 113 - 4
src/components/studyStudent.vue

@@ -66,6 +66,8 @@
             <div class="returnBtn" @click="nextOrpreSteps(0)">上一步</div>
             <div class="returnBtn" @click="nextOrpreSteps(1)">下一步</div>
             <div class="returnBtn" @click="allScrell">全屏</div>
+            <div class="returnBtn" @click="startRecording" v-if="(!videoStart && tType == 1 || tType == 4)">开始录制</div>
+            <div class="returnBtn" @click="stopRecording" v-else-if="(tType == 1 || tType == 4)">停止录制</div>
             <div class="returnBtn" @click="juriVisible = true" v-if="tType == 1">
               权限
             </div>
@@ -3181,7 +3183,7 @@
       <div class="upload_send" @click="addCourseWorksTeacher(taskCount)" v-if="!proVisible">提交</div>
     </el-dialog>
     <ImgDraw :drawShow="drawShow" @closeDraw="closeDraw" @addImgDraw="addImgDraw" :bg="bg"></ImgDraw>
-    <el-dialog title="表格" :visible.sync="dialogVisibleTable" :append-to-body="true" width="800px"
+    <el-dialog title="表格" :visible.sync="dialogVisibleTable" :append-to-body="true" width="95%"
       :before-close="handleClose" class="dialog_diy">
       <el-form>
         <div>表格内容</div>
@@ -3222,6 +3224,7 @@ import * as imageConversion from "image-conversion";
 import Audio from "./components/audio.vue";
 import ImgDraw from "./tools/imgDraw/imgDraw";
 import { Empty } from "element-ui";
+import RecordRTC from 'recordrtc';
 
 export default {
   components: {
@@ -3468,6 +3471,8 @@ export default {
       pzType: 1,
       wScore: 0,
       scoreDetail: "",
+      videoStart: false,
+				recorder: null,
     };
   },
   methods: {
@@ -6888,7 +6893,110 @@ export default {
             });
         })
         .catch(() => { });
-    }
+    },
+    /**
+			 * 开始录制
+			 */
+			startRecording(callback){
+				this.captureScreen((screenStream)=>{
+					this.addStreamStopListener(screenStream,()=>{
+						console.log("流停止监听");
+						this.$emit("streamStop",{})
+						// this.stopRecording();
+					});
+					var options = {
+					    type: 'video',
+					    mimeType: 'video/webm',
+					    disableLogs: false,
+					    getNativeBlob: false, // enable it for longer recordings
+						ignoreMutedMedia:false
+					};
+					// this.video.srcObject = screenStream;
+					this.recorder = RecordRTC(screenStream, options);
+					this.recorder.startRecording();
+					this.recorder.screen = screenStream;
+					this.videoStart = true;
+					// callback(true);
+				});
+			},
+			/**
+			 * 停止录制
+			 */
+			stopRecording(callback){
+				this.recorder.stopRecording(()=>{
+					// this.video.src = this.video.srcObject = null;
+					// this.video.src = URL.createObjectURL(this.recorder.getBlob());
+					const url = URL.createObjectURL(this.recorder.getBlob());
+					const a = document.createElement("a");//this.fileName+
+					let videoFile = new File([this.recorder.getBlob()], this.courseDetail.title+"录屏.mp4", {
+						type: 'video/mp4'  
+					})
+					let downloadUrl = URL.createObjectURL(videoFile);
+					document.body.appendChild(a);
+					a.style.display = "none";
+					a.href = url;
+					a.download = this.courseDetail.title+"录屏.mp4";//this.fileName + 
+					a.click();
+					this.recorder.screen.stop();
+					this.recorder.destroy();
+					this.recorder = null;
+					this.videoStart = false;
+					// callback(false);
+				});
+			},
+			//初始化
+			captureScreen(callback) {
+				if (navigator.getDisplayMedia) {
+					//录制结束,文件下载
+				    navigator.getDisplayMedia({
+				        video: true
+				    }).then(screenStream => {
+						navigator.mediaDevices.getUserMedia({audio:true}).then((mic)=>{
+						    screenStream.addTrack(mic.getTracks()[0]);
+							callback(screenStream);
+						});
+				    }).catch(function(error) {
+						console.log('error',error);
+				    });
+				} else if (navigator.mediaDevices.getDisplayMedia) {
+				    navigator.mediaDevices.getDisplayMedia({
+				        video: true
+				    }).then(screenStream => {
+						navigator.mediaDevices.getUserMedia({audio:true}).then((mic)=>{
+						    screenStream.addTrack(mic.getTracks()[0]);
+							callback(screenStream);
+						});
+				    }).catch(function(error) {
+						console.log('error',error);
+				    });
+				} else {
+				    var error = 'getDisplayMedia API are not supported in this browser.';
+				   console.log('error',error);
+				    alert(error);
+				}
+			},
+			
+			//流监听
+			addStreamStopListener(stream, callback) {
+			    stream.addEventListener('ended', function () {
+			        callback();
+			        callback = function () { };
+			    }, false);
+			    stream.addEventListener('inactive', function () {
+			        callback();
+			        callback = function () { };
+			    }, false);
+			    stream.getTracks().forEach(function (track) {
+			        track.addEventListener('ended', function () {
+			            callback();
+			            callback = function () { };
+			        }, false);
+			        track.addEventListener('inactive', function () {
+			            callback();
+			            callback = function () { };
+			        }, false);
+			    });
+			},
   },
   directives: {
     // 使用局部注册指令的方式
@@ -7584,7 +7692,7 @@ export default {
   display: flex;
   flex-direction: row;
   align-items: center;
-  width: calc(100% - 420px);
+  width: calc(100% - 520px);
 }
 
 .courseIndex>div:nth-child(1) {
@@ -7601,7 +7709,8 @@ export default {
 
 .courseIndex>div:nth-child(2) {
   font-size: 23px;
-  width: 300px;
+  /* width: 300px; */
+  max-width: calc(100% - 180px);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;

+ 18 - 1
src/components/tools/table.vue

@@ -189,6 +189,24 @@ export default {
   border: 1px solid #ccc;
   height: 400px;
   overflow: auto;
+
+}
+
+.w-e-toolbar .w-e-menu{
+  display: flex;
+  width: auto;
+  align-items: center;
+  margin-left: 10px;
+  padding: 0 10px;
+}
+
+.w-e-toolbar {
+  background: #f1f1f1;
+}
+
+.w-e-icon-table2::after {
+  content: '插入表格';
+  margin-left: 5px;
 }
 
 
@@ -241,5 +259,4 @@ export default {
 ol {
   margin: 10px 0 10px 20px;
 }
-
 </style>