SanHQin 4 months ago
parent
commit
89e5f47cbe

+ 1 - 1
dist/index.html

@@ -27,7 +27,7 @@
     html,
     body{
       font-family: '黑体';
-    }</style><link href=./static/css/app.f6e4ee2af6d96b04b33720606d5ea10e.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.264e3d6e7c524117db80.js></script><script type=text/javascript src=./static/js/app.923adb607628184bb2ec.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.5798ede8b48e44bf4147cb85fdeffc34.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.264e3d6e7c524117db80.js></script><script type=text/javascript src=./static/js/app.bca0b082b5d20e4bfe57.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.5798ede8b48e44bf4147cb85fdeffc34.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.5798ede8b48e44bf4147cb85fdeffc34.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.f6e4ee2af6d96b04b33720606d5ea10e.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.bca0b082b5d20e4bfe57.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.bca0b082b5d20e4bfe57.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map


+ 331 - 0
src/components/classRoomHelper/component/uploadFile.vue

@@ -0,0 +1,331 @@
+<template>
+	<div class="uploadBox"></div>
+</template>
+
+<script>
+import "../../../common/aws-sdk-2.235.1.min.js";
+export default {
+	props:{
+		index:{
+			type:String,
+			default:"0"
+		},
+	},
+	data() {
+		return {
+			bucket: "", //aws上传接口
+			bucketname: "ccrb", //桶
+			uploadid: "",
+			partsize: 10 * 1024 * 1024, //10MB  分片
+			filestate: {
+				status: "", //有 error(直接报错) 和 fail(上传的时候报错) 和 success(上传成功) 和 processing(上传中)
+				percent: "", //(0-100的进度)
+			},
+			file: null,
+			flag:true,
+		};
+	},
+	watch: {
+		filestate: {
+			handler(newValue) {
+				this.$emit("progressUpdate", {index:this.index,...newValue});
+			},
+			immediate: true,
+			deep: true,
+		},
+	},
+	methods: {
+		//--------------------------分断上传保证稳定性
+		//初始化上传
+		// async init(){
+		// 	const credentials = {
+		// 	    accessKeyId: "AKIATLPEDU37QV5CHLMH",
+		// 	    secretAccessKey: "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",
+		// 	}; //秘钥形式的登录上传
+		// 	window.AWS.config.update(credentials);
+		// 	window.AWS.config.region = "cn-northwest-1"; //设置区域
+		// 	//桶的设置
+		// 	bucket = new window.AWS.S3({
+		// 	    params: {
+		// 	        Bucket: this.bucketname
+		// 	    }
+		// 	});
+		// 	return bucket;
+		// },
+		// 初始化上传入口
+		async initMultipartUpload(key, file) {
+			console.log(file)
+			const params = {
+				Bucket: this.bucketname,
+				Key: key,
+				ContentType: file.type,
+				ACL: "public-read",
+			};
+			//创建一个续传通道
+			const data = await this.bucket.createMultipartUpload(params).promise();
+			return data.UploadId;
+		},
+		// 上传文件的某一部分
+		async uploadPart(file, keyname, uploadid, pn, start, end) {
+			//key可以设置为桶的相对路径,Body为文件, ACL最好要设置
+			if(!this.flag)return;
+			var params = {
+				Bucket: this.bucketname,
+				Key: keyname,
+				// ContentType: file.type,
+				PartNumber: pn,
+				UploadId: uploadid,
+				Body: file.slice(start, end),
+				// "Access-Control-Allow-Credentials": "*",
+				// ACL: "public-read",
+			};
+			const result = await this.bucket.uploadPart(params).promise();
+			return { ETag: result.ETag, PartNumber: pn };
+		},
+		//完成分块上传
+		async completeMultipartUpload(parts, keyname, uploadid) {
+			if(!this.flag)return;
+			const params = {
+				Bucket: this.bucketname,
+				Key: keyname,
+				MultipartUpload: { Parts: parts },
+				UploadId: uploadid,
+			};
+			return await this.bucket.completeMultipartUpload(params).promise();
+		},
+		async abortMultipartUpload(key, uploadid) {
+			const params = {
+				Bucket: this.bucketname,
+				Key: key,
+				UploadId: uploadid,
+			};
+			let data = await this.bucket.abortMultipartUpload(params).promise();
+			this.$emit("delUpload",{index:this.index})
+			
+		},
+		//--------------------------------下面支持断点续传
+
+		//初始化亚马逊参数
+		async init() {
+			//秘钥形式的登录上传
+			const credentials = {
+				accessKeyId: "AKIATLPEDU37QV5CHLMH",
+				secretAccessKey: "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",
+				region: "cn-northwest-1",
+			};
+			window.AWS.config.update(credentials);
+			// window.AWS.config.region = "cn-northwest-1"; //设置区域
+			//桶的设置
+			this.bucket = new window.AWS.S3({
+				params: {
+					Bucket: this.bucketname,
+				},
+			});
+			return this.bucket;
+		},
+
+		//获取当前文件是否有已上传断点信息
+		async getawscheckpoint(key) {
+			let partsinfo;
+			try {
+				const result = await this.bucket
+					.listMultipartUploads({ Bucket: this.bucketname, Prefix: key })
+					.promise();
+				//获取具体分片信息
+				if (result.Uploads.length) {
+					this.uploadid = result.Uploads[result.Uploads.length - 1].UploadId;
+					partsinfo = await this.bucket
+						.listParts({
+							Bucket: this.bucketname,
+							Key: key,
+							UploadId: this.uploadid,
+						})
+						.promise();
+				}
+			} catch (err) {
+				console.log(err);
+			}
+			return { uploadid: this.uploadid, partsinfo };
+		},
+
+		//分段上传
+		async awsuploadpart(filestate, file, uploadid, parts, key) {
+			var partarr = []; //已完成的数组
+			//已完成的分片,转化成提交格式
+			const completeparts = parts.map((_) => {
+				partarr.push(_.PartNumber);
+				return { PartNumber: _.PartNumber, ETag: _.ETag };
+			});
+			// 分块上传文件
+			// parts = [];
+			let uploadpart;
+			let start = 0;
+			let end = 0;
+			let len = Math.ceil(file.size / this.partsize); //循环的长度
+			if (partarr.length) {
+				this.filestate.status = "processing";
+				this.filestate.percent = parseInt((completeparts.length * 100) / len);
+			}
+			//循环上传
+			for (let i = 0; i < len; i++) {
+				if(!this.flag)break;
+				start = i * this.partsize;
+				end = (i + 1) * this.partsize;
+				if (!partarr.includes(i+1)) {
+
+					uploadpart = await this.uploadPart(
+						file,
+						key,
+						uploadid,
+						i + 1,
+						start,
+						end
+					);
+					if (uploadpart.ETag != null) {
+						completeparts.push(uploadpart);
+						partarr.push(uploadpart.PartNumber);
+						this.filestate.status = "processing";
+						this.filestate.percent = parseInt(
+							(completeparts.length * 100) / len
+						);
+					} else {
+						this.filestate.status = "fail";
+						this.stopUpload();
+						return;
+					}
+				}
+			}
+			//提交上传成功信息
+			if(this.flag){
+					let data = await this.completeMultipartUpload(
+					completeparts,
+					key,
+					uploadid
+				);
+				this.filestate.status = "success";
+				return data;
+			}
+		},
+
+		//上传的接口
+		async awsupload({ file = this.file, keyName, folderName }) {
+			if (!file) return this.$message.error("请上传文件");
+			this.init(); //初始化桶
+			// const key = (folderid || uuidv4()) + "/" + file.name; //需要上传的文件名
+			let key = "";
+			if (keyName) {
+				key = keyName;
+			} else {
+				if (folderName) {
+					key = `${folderName}/${file.name}`;
+				} else {
+					key = `default/${file.name.split(".")[0] +
+							new Date().getTime() +
+							"." +
+							file.name.split(".")[file.name.split(".").length - 1]}`;
+				}
+			}
+			console.log(key);
+			// key = key.replace(/\s/g, "");
+			// key = encodeURIComponent(key);
+			this.filestate = {
+				percent: 0,
+				status: "start",
+			};
+			this.filestate.percent = 0;
+			this.filestate.status = "start";
+			this.file = file;
+			//上传的参数
+			var params = {
+				Bucket: this.bucketname,
+				Key: key,
+			};
+			this.flag = true;
+			//设置桶上传文件
+			try {
+				//检查文件是否已上传
+				this.bucket.headObject(params, async (err, data) => {
+					// 没有上传成功,head方法会返回失败
+					if (err) {
+						//检查是否部分上传
+						const { uploadid, partsinfo } = await this.getawscheckpoint(
+							key,
+							this.bucket
+						);
+						//如果已经部分存在,那么直接在节点续传
+						if (uploadid) {
+							//断点续传
+							this.$emit("startUpload", { index:this.index,key, uploadid });
+							this.filestate.key = key;
+							this.filestate.uploadid = uploadid;
+							this.flag = true;
+							let data = await this.awsuploadpart(
+								this.filestate,
+								file,
+								uploadid,
+								partsinfo.Parts,
+								key
+							);
+							if(this.flag || this.filestate.percent==100)return this.$emit("success", {index:this.index, data, key, uploadid });
+							// return {data,key,uploadid}
+						}
+						//不存在,上传新的
+						else {
+							const uploadid = await this.initMultipartUpload(key, file); //初始化文件上传
+							this.$emit("startUpload", { index:this.index,key, uploadid });
+							this.filestate.key = key;
+							this.filestate.uploadid = uploadid;
+							this.flag = true;
+							let data = await this.awsuploadpart(
+								this.filestate,
+								file,
+								uploadid,
+								[],
+								key
+							);
+							if(this.flag || this.filestate.percent==100)return this.$emit("success", {index:this.index, data, key, uploadid });
+							// return {data,key,uploadid}
+						}
+					}
+					//如果已经上传成功了,那么直接返回状态百分百
+					else if (data) {
+						//data存在,上传成功
+						this.filestate.percent = 100;
+						this.filestate.status = "success";
+						let url = `https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/${key}`
+						this.file = null;
+						if(this.flag)return this.$emit("success", { index:this.index,data:{
+							Key:key,
+							Location:url,
+							ETag:data.ETag,
+							size:data.ContentLength,
+							ServerSideEncryption:data.ServerSideEncryption,
+							Bucket:this.bucketname
+							} });
+						// return {data,key,uploadid}
+					}
+				});
+			} catch (err) {
+				this.filestate.status = "error";
+				this.stopUpload();
+				console.log(err);
+			}
+		},
+		// 停止上传
+		stopUpload(){
+			this.filestate.status = "stop";
+			this.flag = false;
+		}
+	},
+	mounted() {
+		this.bucket = "";
+		this.file = null;
+	},
+};
+</script>
+
+<style scoped>
+.uploadBox {
+	display: none;
+}
+</style>

File diff suppressed because it is too large
+ 8 - 15
src/components/classRoomHelper/index.vue


+ 159 - 2
src/components/easy2/studyStudent.vue

@@ -9433,7 +9433,7 @@
       </div>
     </div>
 		<!-- v-show="org == '1973f6c7-1561-11ee-91d8-005056b86db5' || org == '777559d2-7239-11ee-b98c-005056b86db5' || org == '884c5665-a453-46f3-b7b6-01d575290aa9'" -->
-		<classRoomHelper v-if="!['2'].includes(tType)" :videoStart="videoStart" @startRecording="startRecording" @stopRecording="stopRecording" :fileList="vChapterData[taskCount]" :worksStudent="worksStudent" :courseType="parseInt(courseType)" :taskCount="taskCount" :tcid="tcid" :navList="navList" v-show="orgArray.includes(org) || oidArray.includes(oid)" ref="classRoomHelperRef" :courseDetail="courseDetail" :tType="tType" @setWidth="setClassRoomHelperWidth" @refresh="refreshCourse" @goStep="nextOrpreSteps" @authority="juriVisible = true" @review="setPz" @backPage="goTo(
+		<classRoomHelper v-if="!['2'].includes(tType)" @studentFreePreview="studentFreePreview" @OpenJobPreview="OpenJobPreview" :videoStart="videoStart" :IsFollow="IsFollow" :sIsOpen="sIsOpen" :IsLookOpen="IsLookOpen" :splitScreenData="splitScreenData" @splitScreenBehavior="splitScreenBehavior" @startRecording="startRecording" @stopRecording="stopRecording" :fileList="vChapterData[taskCount]" :worksStudent="worksStudent" :courseType="parseInt(courseType)" :taskCount="taskCount" :tcid="tcid" :navList="navList" v-show="orgArray.includes(org) || oidArray.includes(oid)" ref="classRoomHelperRef" :courseDetail="courseDetail" :tType="tType" @setWidth="setClassRoomHelperWidth" @refresh="refreshCourse" @goStep="nextOrpreSteps" @authority="juriVisible = true" @review="setPz" @backPage="goTo(
                     '/courseDetail?userid=' +
                       userid +
                       '&oid=' +
@@ -13828,7 +13828,15 @@ export default {
       TxtMd :'',
       languageSetting: 0, //0中文 1繁体 2英文
       toolListS:[],
-      commentDetailCopy:''
+      commentDetailCopy:'',
+			splitScreenData:{
+			isOpen:false,
+			userId:"",
+			uid:"",
+			myUid:"",
+			loading:false,
+			behavior:null,
+		}
     };
   },
   methods: {
@@ -18938,6 +18946,7 @@ export default {
             _this.selectStudent();
             _this.selectSLook();
             _this.getPick();
+						_this.getSplitScreenData();
             if (_this.courseDetail.userid == _this.userid && _this.IsFollow) {
               _this.setCTask();
             }
@@ -21425,6 +21434,9 @@ export default {
           }
         );
         let downloadUrl = URL.createObjectURL(videoFile);
+				if(this.$refs.classRoomHelperRef){
+					this.$refs.classRoomHelperRef.checkUploadFile(videoFile)
+				}
         document.body.appendChild(a);
         a.style.display = "none";
         a.href = url;
@@ -22154,6 +22166,139 @@ export default {
 		},
 		statisticalAnalysisRefresh(toolIndex){
 			this.$refs.statisticalAnalysisRef.refreshData({worksStudent:this.worksStudent[toolIndex],tType:this.tType,toolIndex:toolIndex})
+		},
+		async splitScreenBehavior(type=0){
+			if(this.splitScreenData.loading)return this.$message.info("操作过快,请稍等")
+			if(type==0){//关闭分屏
+				this.splitScreenData.isOpen = false;
+				// this.splitScreenData.userId = "";
+				// this.splitScreenData.uid = "";
+				this.splitScreenData.behavior = null;
+				await this.updateSplitScreenData(1);
+				this.$message.success("已关闭分屏模式");
+				this.studentFreePreview(false)
+				this.OpenJobPreview(false)
+				this.followingMode(false)
+			}else if(type==1){//开启分屏
+				this.splitScreenData.isOpen = true;
+				this.splitScreenData.userId = this.userid;
+				this.splitScreenData.uid = this.splitScreenData.myUid;
+				this.splitScreenData.behavior = null;
+				let status = await this.updateSplitScreenData(0);
+				
+				if(status==1){
+					this.$message.success("已开启分屏")
+					this.studentFreePreview(true)
+					this.OpenJobPreview(true)
+					this.followingMode(true)
+				}else{
+					this.splitScreenData.isOpen = false;
+					this.splitScreenData.userId = "";
+					this.splitScreenData.uid = "";
+					this.splitScreenData.behavior = null;
+					this.$message.success("分屏开启失败")
+				}
+				
+			}
+		},
+		getSplitScreenData(){
+			return;
+			console.log("获取分屏数据👇")
+			if(this.tType!=1)return;
+			let params = {
+				cid:this.id
+			}
+			
+			this.ajax.get(this.$store.state.api+"select_courseSplitScreenData",params).then(async res=>{
+				let data = res.data[0][0]["splitScreenData"];
+				console.log("获取了分屏数:",data)
+				if(data){
+					data = JSON.parse(data)
+					if(!this.splitScreenData.isOpen && data.isOpen && this.splitScreenData.myUid == data.uid){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						await this.updateSplitScreenData(1);
+					}else if(!this.splitScreenData.isOpen && data.isOpen){
+						this.splitScreenData.isOpen = true;
+						this.splitScreenData.uid = data.uid;
+						this.splitScreenData.userId = data.userId;
+						this.splitScreenData.behavior = data.behavior;
+						this.$message.success("分屏模式已开启");
+					}else if(this.splitScreenData.isOpen && !data.isOpen){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						this.$message.error("已结束分屏模式");
+					}else if(this.splitScreenData.isOpen && data.isOpen){
+						this.splitScreenData.isOpen = true;
+						this.splitScreenData.uid = data.uid;
+						this.splitScreenData.userId = data.userId;
+						this.splitScreenData.behavior = data.behavior;
+					}
+
+
+				}else{
+					if(this.splitScreenData.isOpen){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						this.$message.error("已结束分屏模式")
+					}
+				};
+			}).catch(e=>{
+				cosnole.log("获取分屏数出错:",e)
+			})
+		},
+		updateSplitScreenData(empty = 0){
+			return;
+			return new Promise((resolve)=>{
+				
+				if(this.splitScreenData.uid == this.splitScreenData.myUid && this.splitScreenData.userId == this.userid){
+				this.splitScreenData.loading = true;
+				let params = [{
+					cid:this.id,
+					nData:empty===1?"":JSON.stringify(this.splitScreenData)
+				}]
+
+				this.ajax.post(this.$store.state.api+"update_courseSplitScreenData",params).then(res=>{
+					this.splitScreenData.loading = false;
+					if(res.data==1){
+						resolve(1);
+						console.log("修改分屏数据成功")
+					}
+				}).catch(e=>{
+					this.splitScreenData.loading = false;
+					console.log("修改分屏数据失败",e)
+					resoleve(0)
+					
+				})
+			}else if(empty==2){
+				let params = [{
+					cid:this.id,
+					nData:""
+				}]
+				
+				return this.ajax.post(this.$store.state.api+"update_courseSplitScreenData",params).then(_=>resolve(1)).catch(_=>resolve(0))
+			}else{
+				return resolve(0);
+			}
+			})
+		},
+		studentFreePreview(flag){
+			this.IsLookOpen = flag;
+			this.updateLookOpen();
+		},
+		OpenJobPreview(flag){
+			this.sIsOpen = flag;
+			this.updateSLook();
+		},
+		followingMode(flag){
+			this.IsFollow = flag;
+			this.updateFollow();
 		}
   },
   directives: {
@@ -22199,6 +22344,7 @@ export default {
     this.timer = null;
     clearInterval(this.opertimer);
     this.opertimer = null;
+		this.updateSplitScreenData(1); 
   },
   computed: {
    
@@ -22342,6 +22488,11 @@ export default {
 		
   },
   mounted() {
+		this.updateSplitScreenData(2);
+		setInterval(()=>{
+			console.log("👉",this.splitScreenData);
+		},2000)
+		this.splitScreenData.myUid = uuidv4();
     document.body.addEventListener("click", (e) => {
       if (this.isUpdateToolDetail1) {
         this.updateToolDetail(this.toolDetailIndex);
@@ -22369,6 +22520,12 @@ export default {
     }
 		// 获取评分列表
 		this.getScoreList()
+
+		
+
+
+
+
     document.scrollingElement.scrollTop = 0;
     window.addEventListener("resize", () => {
       var a = document.getElementsByClassName("box_course")[0].offsetHeight;

+ 154 - 3
src/components/easy3/studyStudent.vue

@@ -8116,7 +8116,7 @@
       </div>
     </div>
 				<!-- v-show="org == '1973f6c7-1561-11ee-91d8-005056b86db5' || org == '777559d2-7239-11ee-b98c-005056b86db5' || org == '884c5665-a453-46f3-b7b6-01d575290aa9'" -->
-		<classRoomHelper v-if="!['2'].includes(tType)" :videoStart="videoStart" @startRecording="startRecording" @stopRecording="stopRecording" :fileList="vChapterData[taskCount]" :worksStudent="worksStudent" :courseType="parseInt(courseType)" :taskCount="taskCount" :tcid="tcid" :navList="navList" v-show="orgArray.includes(org) || oidArray.includes(oid)" ref="classRoomHelperRef" :courseDetail="courseDetail" :tType="tType" @setWidth="setClassRoomHelperWidth" @refresh="refreshCourse" @goStep="nextOrpreSteps" @authority="juriVisible = true" @review="setPz" @backPage="goTo(
+		<classRoomHelper v-if="!['2'].includes(tType)" @studentFreePreview="studentFreePreview" @OpenJobPreview="OpenJobPreview" :videoStart="videoStart" :IsFollow="IsFollow" :sIsOpen="sIsOpen" :IsLookOpen="IsLookOpen" :splitScreenData="splitScreenData" @splitScreenBehavior="splitScreenBehavior" @startRecording="startRecording" @stopRecording="stopRecording" :fileList="vChapterData[taskCount]" :worksStudent="worksStudent" :courseType="parseInt(courseType)" :taskCount="taskCount" :tcid="tcid" :navList="navList" v-show="orgArray.includes(org) || oidArray.includes(oid)" ref="classRoomHelperRef" :courseDetail="courseDetail" :tType="tType" @setWidth="setClassRoomHelperWidth" @refresh="refreshCourse" @goStep="nextOrpreSteps" @authority="juriVisible = true" @review="setPz" @backPage="goTo(
                     '/courseDetail?userid=' +
                       userid +
                       '&oid=' +
@@ -11987,6 +11987,7 @@ import scoreZong from '../scoreZong/index.vue'
 import classRoomHelper from '../classRoomHelper/index.vue'
 import MarkdownIt from "markdown-it";
 import statisticalAnalysis from '../components/statisticalAnalysis.vue'
+import { v4 as uuidv4 } from "uuid";
 
 const getFile = (url) => {
   return new Promise((resolve, reject) => {
@@ -12063,7 +12064,8 @@ export default {
 		scoreItem,
 		classRoomHelper,
     scoreZong,
-		statisticalAnalysis
+		statisticalAnalysis,
+		
   },
   data() {
     return {
@@ -12431,7 +12433,15 @@ export default {
 			},
 			classRoomHelperWidth: '85px',
 			orgArray:[],
-      oidArray:[]
+      oidArray:[],
+			splitScreenData:{
+			isOpen:false,
+			userId:"",
+			uid:"",
+			myUid:"",
+			loading:false,
+			behavior:null,
+		}
     };
   },
   methods: {
@@ -16822,6 +16832,7 @@ export default {
           _this.selectStudent();
           _this.selectSLook();
           _this.getPick();
+					
           if (_this.courseDetail.userid == _this.userid && _this.IsFollow) {
             _this.setCTask();
           }
@@ -16847,6 +16858,7 @@ export default {
             _this.selectStudent();
             _this.selectSLook();
             _this.getPick();
+						_this.getSplitScreenData();//获取分屏数据
             if (_this.courseDetail.userid == _this.userid && _this.IsFollow) {
               _this.setCTask();
             }
@@ -19332,6 +19344,9 @@ export default {
           }
         );
         let downloadUrl = URL.createObjectURL(videoFile);
+				if(this.$refs.classRoomHelperRef){
+					this.$refs.classRoomHelperRef.checkUploadFile(videoFile)
+				}
         document.body.appendChild(a);
         a.style.display = "none";
         a.href = url;
@@ -20072,6 +20087,139 @@ export default {
 		},
 		statisticalAnalysisRefresh(toolIndex){
 			this.$refs.statisticalAnalysisRef.refreshData({worksStudent:this.worksStudent[toolIndex],tType:this.tType,toolIndex:toolIndex})
+		},
+		async splitScreenBehavior(type=0){
+			if(this.splitScreenData.loading)return this.$message.info("操作过快,请稍等")
+			if(type==0){//关闭分屏
+				this.splitScreenData.isOpen = false;
+				// this.splitScreenData.userId = "";
+				// this.splitScreenData.uid = "";
+				this.splitScreenData.behavior = null;
+				await this.updateSplitScreenData(1);
+				this.$message.success("已关闭分屏模式");
+				this.studentFreePreview(false)
+				this.OpenJobPreview(false)
+				this.followingMode(false)
+			}else if(type==1){//开启分屏
+				this.splitScreenData.isOpen = true;
+				this.splitScreenData.userId = this.userid;
+				this.splitScreenData.uid = this.splitScreenData.myUid;
+				this.splitScreenData.behavior = null;
+				let status = await this.updateSplitScreenData(0);
+				
+				if(status==1){
+					this.$message.success("已开启分屏")
+					this.studentFreePreview(true)
+					this.OpenJobPreview(true)
+					this.followingMode(true)
+				}else{
+					this.splitScreenData.isOpen = false;
+					this.splitScreenData.userId = "";
+					this.splitScreenData.uid = "";
+					this.splitScreenData.behavior = null;
+					this.$message.success("分屏开启失败")
+				}
+				
+			}
+		},
+		getSplitScreenData(){
+			return;
+			console.log("获取分屏数据👇")
+			if(this.tType!=1)return;
+			let params = {
+				cid:this.id
+			}
+			
+			this.ajax.get(this.$store.state.api+"select_courseSplitScreenData",params).then(async res=>{
+				let data = res.data[0][0]["splitScreenData"];
+				console.log("获取了分屏数:",data)
+				if(data){
+					data = JSON.parse(data)
+					if(!this.splitScreenData.isOpen && data.isOpen && this.splitScreenData.myUid == data.uid){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						await this.updateSplitScreenData(1);
+					}else if(!this.splitScreenData.isOpen && data.isOpen){
+						this.splitScreenData.isOpen = true;
+						this.splitScreenData.uid = data.uid;
+						this.splitScreenData.userId = data.userId;
+						this.splitScreenData.behavior = data.behavior;
+						this.$message.success("分屏模式已开启");
+					}else if(this.splitScreenData.isOpen && !data.isOpen){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						this.$message.error("已结束分屏模式");
+					}else if(this.splitScreenData.isOpen && data.isOpen){
+						this.splitScreenData.isOpen = true;
+						this.splitScreenData.uid = data.uid;
+						this.splitScreenData.userId = data.userId;
+						this.splitScreenData.behavior = data.behavior;
+					}
+
+
+				}else{
+					if(this.splitScreenData.isOpen){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						this.$message.error("已结束分屏模式")
+					}
+				};
+			}).catch(e=>{
+				cosnole.log("获取分屏数出错:",e)
+			})
+		},
+		updateSplitScreenData(empty = 0){
+			return;
+			return new Promise((resolve)=>{
+				
+				if(this.splitScreenData.uid == this.splitScreenData.myUid && this.splitScreenData.userId == this.userid){
+				this.splitScreenData.loading = true;
+				let params = [{
+					cid:this.id,
+					nData:empty===1?"":JSON.stringify(this.splitScreenData)
+				}]
+
+				this.ajax.post(this.$store.state.api+"update_courseSplitScreenData",params).then(res=>{
+					this.splitScreenData.loading = false;
+					if(res.data==1){
+						resolve(1);
+						console.log("修改分屏数据成功")
+					}
+				}).catch(e=>{
+					this.splitScreenData.loading = false;
+					console.log("修改分屏数据失败",e)
+					resoleve(0)
+					
+				})
+			}else if(empty==2){
+				let params = [{
+					cid:this.id,
+					nData:""
+				}]
+				
+				return this.ajax.post(this.$store.state.api+"update_courseSplitScreenData",params).then(_=>resolve(1)).catch(_=>resolve(0))
+			}else{
+				return resolve(0);
+			}
+			})
+		},
+		studentFreePreview(flag){
+			this.IsLookOpen = flag;
+			this.updateLookOpen();
+		},
+		OpenJobPreview(flag){
+			this.sIsOpen = flag;
+			this.updateSLook();
+		},
+		followingMode(flag){
+			this.IsFollow = flag;
+			this.updateFollow();
 		}
   },
   directives: {
@@ -20116,6 +20264,7 @@ export default {
     this.timer = null;
     clearInterval(this.opertimer);
     this.opertimer = null;
+		this.updateSplitScreenData(1); 
   },
   computed: {
     getHeight(){
@@ -20278,6 +20427,8 @@ export default {
     }
 		// 获取评分列表
 		this.getScoreList()
+		this.updateSplitScreenData(2);
+		this.splitScreenData.myUid = uuidv4();
     document.scrollingElement.scrollTop = 0;
     window.addEventListener("resize", () => {
       var a = document.getElementsByClassName("box_course")[0].offsetHeight;

+ 154 - 2
src/components/studyStudent.vue

@@ -8085,7 +8085,7 @@
         </el-dialog>
       </div>
 			<!-- v-show="org == '1973f6c7-1561-11ee-91d8-005056b86db5' || org == '777559d2-7239-11ee-b98c-005056b86db5' || org == '884c5665-a453-46f3-b7b6-01d575290aa9'" -->
-      <classRoomHelper v-if="!['2'].includes(tType)" :videoStart="videoStart" @startRecording="startRecording" @stopRecording="stopRecording" :fileList="vChapterData[taskCount]" :worksStudent="worksStudent" :courseType="parseInt(courseType)" :taskCount="taskCount" :tcid="tcid" :navList="navList" v-show="orgArray.includes(org) || oidArray.includes(oid)"  ref="classRoomHelperRef" :courseDetail="courseDetail" :tType="tType" @setWidth="setClassRoomHelperWidth" @refresh="refreshCourse" @goStep="nextOrpreSteps" @authority="juriVisible = true" @review="setPz" @backPage="goTo(
+      <classRoomHelper v-if="!['2'].includes(tType)" @studentFreePreview="studentFreePreview" @OpenJobPreview="OpenJobPreview" :videoStart="videoStart" :splitScreenData="splitScreenData" @splitScreenBehavior="splitScreenBehavior" @startRecording="startRecording" @stopRecording="stopRecording" :fileList="vChapterData[taskCount]" :worksStudent="worksStudent" :courseType="parseInt(courseType)" :taskCount="taskCount" :tcid="tcid" :navList="navList" v-show="orgArray.includes(org) || oidArray.includes(oid)"  ref="classRoomHelperRef" :courseDetail="courseDetail" :tType="tType" @setWidth="setClassRoomHelperWidth" @refresh="refreshCourse" @goStep="nextOrpreSteps" @authority="juriVisible = true" @review="setPz" @backPage="goTo(
                     '/courseDetail?userid=' +
                       userid +
                       '&oid=' +
@@ -11928,6 +11928,7 @@ import scoreItem from './scoreList/scoreItem.vue'
 import scoreZong from './scoreZong/index.vue'
 import classRoomHelper from './classRoomHelper/index.vue'
 import statisticalAnalysis from "./components/statisticalAnalysis.vue";
+import { v4 as uuidv4 } from "uuid";
 
 const getFile = (url) => {
   return new Promise((resolve, reject) => {
@@ -12410,7 +12411,15 @@ export default {
     26: "课程设计",
     62: "交互视频",
     71: "AI智能体"
-}
+},
+		splitScreenData:{
+			isOpen:false,
+			userId:"",
+			uid:"",
+			myUid:"",
+			loading:false,
+			behavior:null,
+		}
     };
   },
   methods: {
@@ -16838,6 +16847,8 @@ export default {
             _this.selectStudent();
             _this.selectSLook();
             _this.getPick();
+						_this.getSplitScreenData();
+
             if (_this.courseDetail.userid == _this.userid && _this.IsFollow) {
               _this.setCTask();
             }
@@ -19318,6 +19329,9 @@ export default {
           }
         );
         let downloadUrl = URL.createObjectURL(videoFile);
+				if(this.$refs.classRoomHelperRef){
+					this.$refs.classRoomHelperRef.checkUploadFile(videoFile)
+				}
         document.body.appendChild(a);
         a.style.display = "none";
         a.href = url;
@@ -20059,6 +20073,139 @@ export default {
 		},
 		statisticalAnalysisRefresh(toolIndex){
 			this.$refs.statisticalAnalysisRef.refreshData({worksStudent:this.worksStudent[toolIndex],tType:this.tType,toolIndex:toolIndex})
+		},
+		async splitScreenBehavior(type=0){
+			if(this.splitScreenData.loading)return this.$message.info("操作过快,请稍等")
+			if(type==0){//关闭分屏
+				this.splitScreenData.isOpen = false;
+				// this.splitScreenData.userId = "";
+				// this.splitScreenData.uid = "";
+				this.splitScreenData.behavior = null;
+				await this.updateSplitScreenData(1);
+				this.$message.success("已关闭分屏模式");
+				this.studentFreePreview(false)
+				this.OpenJobPreview(false)
+				this.followingMode(false)
+			}else if(type==1){//开启分屏
+				this.splitScreenData.isOpen = true;
+				this.splitScreenData.userId = this.userid;
+				this.splitScreenData.uid = this.splitScreenData.myUid;
+				this.splitScreenData.behavior = null;
+				let status = await this.updateSplitScreenData(0);
+				
+				if(status==1){
+					this.$message.success("已开启分屏")
+					this.studentFreePreview(true)
+					this.OpenJobPreview(true)
+					this.followingMode(true)
+				}else{
+					this.splitScreenData.isOpen = false;
+					this.splitScreenData.userId = "";
+					this.splitScreenData.uid = "";
+					this.splitScreenData.behavior = null;
+					this.$message.success("分屏开启失败")
+				}
+				
+			}
+		},
+		getSplitScreenData(){
+			return;
+			console.log("获取分屏数据👇")
+			if(this.tType!=1)return;
+			let params = {
+				cid:this.id
+			}
+			
+			this.ajax.get(this.$store.state.api+"select_courseSplitScreenData",params).then(async res=>{
+				let data = res.data[0][0]["splitScreenData"];
+				console.log("获取了分屏数:",data)
+				if(data){
+					data = JSON.parse(data)
+					if(!this.splitScreenData.isOpen && data.isOpen && this.splitScreenData.myUid == data.uid){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						await this.updateSplitScreenData(1);
+					}else if(!this.splitScreenData.isOpen && data.isOpen){
+						this.splitScreenData.isOpen = true;
+						this.splitScreenData.uid = data.uid;
+						this.splitScreenData.userId = data.userId;
+						this.splitScreenData.behavior = data.behavior;
+						this.$message.success("分屏模式已开启");
+					}else if(this.splitScreenData.isOpen && !data.isOpen){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						this.$message.error("已结束分屏模式");
+					}else if(this.splitScreenData.isOpen && data.isOpen){
+						this.splitScreenData.isOpen = true;
+						this.splitScreenData.uid = data.uid;
+						this.splitScreenData.userId = data.userId;
+						this.splitScreenData.behavior = data.behavior;
+					}
+
+
+				}else{
+					if(this.splitScreenData.isOpen){
+						this.splitScreenData.isOpen = false;
+						this.splitScreenData.userId = "";
+						this.splitScreenData.uid = "";
+						this.splitScreenData.behavior = null;
+						this.$message.error("已结束分屏模式")
+					}
+				};
+			}).catch(e=>{
+				cosnole.log("获取分屏数出错:",e)
+			})
+		},
+		updateSplitScreenData(empty = 0){
+			return;
+			return new Promise((resolve)=>{
+				
+				if(this.splitScreenData.uid == this.splitScreenData.myUid && this.splitScreenData.userId == this.userid){
+				this.splitScreenData.loading = true;
+				let params = [{
+					cid:this.id,
+					nData:empty===1?"":JSON.stringify(this.splitScreenData)
+				}]
+
+				this.ajax.post(this.$store.state.api+"update_courseSplitScreenData",params).then(res=>{
+					this.splitScreenData.loading = false;
+					if(res.data==1){
+						resolve(1);
+						console.log("修改分屏数据成功")
+					}
+				}).catch(e=>{
+					this.splitScreenData.loading = false;
+					console.log("修改分屏数据失败",e)
+					resoleve(0)
+					
+				})
+			}else if(empty==2){
+				let params = [{
+					cid:this.id,
+					nData:""
+				}]
+				
+				return this.ajax.post(this.$store.state.api+"update_courseSplitScreenData",params).then(_=>resolve(1)).catch(_=>resolve(0))
+			}else{
+				return resolve(0);
+			}
+			})
+		},
+		studentFreePreview(flag){
+			this.IsLookOpen = flag;
+			this.updateLookOpen();
+		},
+		OpenJobPreview(flag){
+			this.sIsOpen = flag;
+			this.updateSLook();
+		},
+		followingMode(flag){
+			this.IsFollow = flag;
+			this.updateFollow();
 		}
   },
   directives: {
@@ -20103,6 +20250,7 @@ export default {
     this.timer = null;
     clearInterval(this.opertimer);
     this.opertimer = null;
+		this.updateSplitScreenData(1); 
   },
   computed: {
     contentConvent() {
@@ -20246,6 +20394,10 @@ export default {
     this.getHomeWork();
     this.selectUser();
 		this.getAIJ();
+
+		this.updateSplitScreenData(2);
+		this.splitScreenData.myUid = uuidv4();
+
     this.contentDialog = true;
     this.setContent2(true);
     if (this.tType == 4) {

Some files were not shown because too many files changed in this diff