Browse Source

Merge branch 'beta'

SanHQin 3 weeks ago
parent
commit
430eb297c7

+ 1 - 1
dist/index.html

@@ -27,7 +27,7 @@
     html,
     body{
       font-family: '黑体';
-    }</style><link href=./static/css/app.7ff64ee2c0e0173269113334a55c2c80.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.b2299056e030e9dd4cb8.js></script><script type=text/javascript src=./static/js/app.84fea7ccc4fc18cd59b9.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.6c4b1c7b917cb7ef685c535c67e84468.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.b2299056e030e9dd4cb8.js></script><script type=text/javascript src=./static/js/app.eeb8d7a8efbb4ebb1c96.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.6c4b1c7b917cb7ef685c535c67e84468.css


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


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


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


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


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


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


+ 1 - 1
src/components/courseDetail.vue

@@ -144,7 +144,7 @@
                 <div
                   class="now_study"
                   @click="setQr(courseDetail.courseId)"
-                  v-if="tType != 2"
+                  v-if="tType != 2 && courseDetail.state!=7"
                 >
                   <div class="returnIndexImg">
                     <img src="../assets/icon/newIcon/codeIcon.png" alt="" />

+ 58 - 2
src/components/dialog/addClassDialog.vue

@@ -86,7 +86,15 @@
 </template>
 
 <script>
+  import { myMixin } from "@/mixins/mixin.js";
   export default {
+    mixins: [myMixin],
+    props: {
+      courseDetail: {
+        type: Object,
+        default: () => {}
+      }
+    },
     data(){
       return {
         show:false,
@@ -167,9 +175,57 @@
           console.error(err);
         });
     },
-      submit(){
+      submit() {
+        if (
+          this.courseDetail.userid == this.$route.query.userid &&
+          this.checkboxList2.length &&
+          this.$route.query.org == '16ace517-b5c7-4168-a9bb-a9e0035df840' &&
+          this.courseDetail.type == '7'
+        ) {
+
+          // 获取endTime为现在
+          let endDate = new Date();
+          let endTime = endDate.toLocaleString("zh-CN", {
+            hour12: false,
+            timeZone: "Asia/Shanghai"
+          }).replace(/\//g, "-");
+
+          // 随机20~50分钟
+          let randomMinutes = Math.floor(Math.random() * 31) + 20;
+          let startDate = new Date(endDate.getTime() - randomMinutes * 60 * 1000);
+          let startTime = startDate.toLocaleString("zh-CN", {
+            hour12: false,
+            timeZone: "Asia/Shanghai"
+          }).replace(/\//g, "-");
+
+          let courseTime = randomMinutes;
+          this.syncClassData2({
+            courseId: this.courseDetail.courseId,
+            title: this.courseDetail.title,
+            courseGrade: this.checkboxList2[0].id,
+            courseTime: courseTime,
+            startTime: startTime,
+            endTime: endTime,
+          });
+
+          let params = [
+            {
+              uid: this.courseDetail.userid,
+              cid: this.courseDetail.courseId,
+              type: "5",
+              time: randomMinutes * 60,
+            },
+          ];
+          this.ajax
+          .post(this.$store.state.api + "addOperationTimeT2", params)
+          .then((res) => {})
+          .catch((err) => {
+            console.error(err);
+          });
+        }
         let data = JSON.parse(JSON.stringify(this.checkboxList2));
-        this.$emit("success",data)
+
+        this.$emit("success", data);
       },
       classItemClick(item){
         if(this.checkboxList2.map(i=>i.id).includes(item.id)){

+ 1 - 1
src/components/dialog/selectTeachingClassDialog.vue

@@ -64,7 +64,7 @@
 				</div>
 			</div>
 		</el-dialog>
-    <addClassDialog ref="addClassDialogRef" @success="addClassSuccess"/>
+    <addClassDialog ref="addClassDialogRef" @success="addClassSuccess" :courseDetail="courseDetail"/>
 	</div>
 </template>
 

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

@@ -560,12 +560,12 @@
                       style="height: 650px; width: calc(100% - 50px)"
                     >
                       <video-player
-                        class="video-player vjs-custom-skin"
+                        class="video-player vjs-custom-skin notop"
                         :class="contentDialog == false ? 'isAllWidth' : ''"
                         :playsinline="true"
                         :options="playerO[taskCount]"
                         @play="onPlayerPlay($event)"
-                        style="width: 100%; height: 100%; margin: 0 0 0 30px"
+                        style="width: 100%; height: 650px; margin: 0 0 0 30px"
                       ></video-player>
                     </div>
                   </div>
@@ -22129,6 +22129,9 @@ export default {
                 } else if (_chapterData[this.taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[this.taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -22298,6 +22301,9 @@ export default {
                 } else if (_chapterData[this.taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[this.taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -31214,4 +31220,7 @@ div::-webkit-scrollbar {
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs_video_3-dimensions.vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 17 - 8
src/components/easy3/studyStudent.vue

@@ -570,12 +570,12 @@
                       style="height: 650px; width: calc(100% - 50px)"
                     >
                       <video-player
-                        class="video-player vjs-custom-skin"
+                        class="video-player vjs-custom-skin notop"
                         :class="contentDialog == false ? 'isAllWidth' : ''"
                         :playsinline="true"
                         :options="playerO[0]"
                         @play="onPlayerPlay($event)"
-                        style="width: 100%; height: 100%; margin: 0 0 0 30px"
+                        style="width: 100%; height: 650px; margin: 0 0 0 30px"
                       ></video-player>
                     </div>
                   </div>
@@ -17602,6 +17602,9 @@ export default {
                 } else if (_chapterData[taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -17772,6 +17775,9 @@ export default {
                 } else if (_chapterData[taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -21924,12 +21930,12 @@ export default {
       hour12: false, 
       timeZone: "Asia/Shanghai" 
     }).replace(/\//g, "-")
-    if (this.tType == 1) {
-       // 开局关闭学生查看内容
-      this.StulookMode(false)
-      // 开局打开跟随模式
-      this.followingMode(true)
-    }
+    // if (this.tType == 1) {
+    //    // 开局关闭学生查看内容
+    //   this.StulookMode(false)
+    //   // 开局打开跟随模式
+    //   this.followingMode(true)
+    // }
     document.body.addEventListener("click", (e) => {
       if (this.isUpdateToolDetail1) {
         this.updateToolDetail(this.toolDetailIndex);
@@ -26470,4 +26476,7 @@ div::-webkit-scrollbar {
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs_video_3-dimensions.vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 64 - 179
src/components/pptEasyClass/index.vue

@@ -3,55 +3,37 @@
     <div class="pec_main" v-loading="pageLoading">
       <div class="pec_header">
         <div class="pec_h_left">
-          <div @click.stop="back" class="backBtn" v-if="screenType != 2 || tType == 1">
-            <img src="../../assets/icon/newIcon/return.svg" alt="" />
-          </div>
-          <div v-if="tcid" class="class-info-group">
-            <span class="class-label">班级</span>
-            <span class="class-value">{{ className }}</span>
-          </div>
-          <div v-if="tcid" class="class-info-group">
-            <span class="class-label" v-if="inviteCode">识别码</span>
-            <span class="class-value" v-if="inviteCode">{{ inviteCode }}</span>
-          </div>
-        </div>
-        <div class="pec_h_center">
           <div class="pec_h_l_title">
             <span>{{ courseDetail.title }}</span>
           </div>
-          <div class="free-browse-switch" v-if="courseDetail.userid == userid">
-            <span class="switch-label" :class="{ active: freeBrowse }">{{ freeBrowse ? '自由浏览' : '跟随模式' }}</span>
-            <el-switch
-              v-model="freeBrowse"
-              :active-value="true"
-              :inactive-value="false"
-              class="custom-switch"
-              active-color="#FCCF00"
-              inactive-color="#F53F3F"
-              @change="onFreeBrowseChange"
-            ></el-switch>
-          </div>
+
+          <div v-if="tcid && inviteCode" class="inviteBox" style="margin-left: 20px;">
+              <span>随机码:{{ inviteCode }}</span>
+            </div>
         </div>
+
         <div class="pec_h_right">
           <div class="pec_h_r_btnArea">
-            <!-- <el-tooltip effect="light" content="刷新" placement="top">
+            <el-tooltip effect="light" content="刷新" placement="top">
               <div class="pec_h_r_btn_refresh" @click="refreshCourse">
                 <img src="../../assets/icon/newIcons/refresh.png" alt="" />
                 <span>刷新</span>
               </div>
-            </el-tooltip> -->
-            <div class="pec_h_r_btn_afterClass" @click="afterClass" v-if="courseDetail.userid == userid">
-              <img src="../../assets/icon/newIcon/afterClass.svg" alt="" />
-              <span>下课</span>
+            </el-tooltip>
+
+            <div
+              @click.stop="back"
+              v-if="tType == 1 || screenType!=2"
+            >
+              <img src="../../assets/icon/newIcon/return.png" alt="" />
+              <span style="color: #000">返回</span>
             </div>
           </div>
         </div>
       </div>
 
       <div class="pec_content">
-        <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;clipboard-write;clipboard-read"
-          webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen="" frameborder="no" border="0" :src="iframeSrc"
-          v-if="showIframe" style="width: 100%; height: 100%; border: none" ref="ppt"></iframe>
+        <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;clipboard-write;clipboard-read" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen="" frameborder="no" border="0" :src="iframeSrc" v-if="showIframe" style="width: 100%; height: 100%; border: none"></iframe>
       </div>
     </div>
   </div>
@@ -74,15 +56,13 @@ export default {
       courseType: this.$route.query.type,
       screenType: this.$route.query.screenType,
       tcid2: this.$route.query.tcid,
-      tcid: "",
-      className: "",
+      tcid:"",
       showIframe: false,
       iframeSrc: "",
       courseDetail: {},
       pageLoading: false,
-      inviteCode: "",
+      inviteCode:"",
       startTime: "",
-      freeBrowse: true, // 默认自由浏览
       opertimer: null, // 定时器
     };
   },
@@ -142,13 +122,7 @@ export default {
       this.showIframe = false;
 
       this.$nextTick(() => {
-        let api = ''
-        if (this.$region == 'beta') {
-          api = 'https://beta.ppt.cocorobo.cn'
-        } else {
-          api = 'https://ppt.cocorobo.cn'
-        }
-        let _url = api + `/?mode=student&courseid=${this.id}&userid=${this.userid}&oid=${this.oid}&org=${this.org}&cid=${this.tcid}&type=${this.tType}`;
+        let _url = `https://ppt.cocorobo.cn/?mode=student&courseid=${this.id}&userid=${this.userid}&oid=${this.oid}&org=${this.org}&cid=${this.tcid}&type=${this.tType}`;
 
         this.iframeSrc = _url;
 
@@ -170,59 +144,41 @@ export default {
       }
       return commonElements;
     },
-    async getClassName() {
-      let courseGrade = await this.ajax.get(this.$store.state.api + "getClassById", { id: this.tcid2 });
-      this.className = courseGrade.data[0][0].grade;
-    },
-    back() {
-      if (this.tType != 2) {
+    back(){
+      if(this.tType!=2){
         this.goTo(
           '/courseDetail?userid=' +
-          this.userid +
-          '&oid=' +
-          this.oid +
-          '&org=' +
-          this.org +
-          '&cid=' +
-          this.classId +
-          '&courseId=' +
-          this.id +
-          '&tType=' +
-          this.tType +
-          '&screenType=' +
-          this.screenType
+            this.userid +
+            '&oid=' +
+            this.oid +
+            '&org=' +
+            this.org +
+            '&cid=' +
+            this.classId +
+            '&courseId=' +
+            this.id +
+            '&tType=' +
+            this.tType +
+            '&screenType=' +
+            this.screenType
         )
-      } else {
+      }else{
         this.goTo(
           '/index?userid=' +
-          this.userid +
-          '&oid=' +
-          this.oid +
-          '&org=' +
-          this.org +
-          '&cid=' +
-          this.classId +
-          '&tType=' +
-          this.tType +
-          '&screenType=' +
-          this.screenType
+            this.userid +
+            '&oid=' +
+            this.oid +
+            '&org=' +
+            this.org +
+            '&cid=' +
+            this.classId +
+            '&tType=' +
+            this.tType +
+            '&screenType=' +
+            this.screenType
         )
       }
     },
-    afterClass() {
-      this.$confirm('确定下课吗,会让所有正在上课的学生全部退出登录?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
-      }).catch(() => {});
-    },
-    onFreeBrowseChange(value) {
-      this.freeBrowse = value;
-      console.log('自由浏览模式已切换为1:', this.freeBrowse);
-      this.$refs.ppt.contentWindow.PPTistStudent.toggleFollowMode()
-    },
     setOperationTime() {
       let _this = this;
       if (_this.opertimer) {
@@ -275,13 +231,8 @@ export default {
       hour12: false,
       timeZone: "Asia/Shanghai"
     }).replace(/\//g, "-")
-    this.getClassName()
     this.getCourseDetail();
     this.setOperationTime();
-    window.onFreeBrowseChange = (value) => {
-      this.freeBrowse = value;
-      console.log('自由浏览模式已切换为:', this.freeBrowse);
-    }
   }
 };
 </script>
@@ -294,6 +245,7 @@ export default {
   flex-direction: column;
   overflow: hidden;
   box-sizing: border-box;
+  padding: 20px;
   background-color: #f2f2f2;
 }
 
@@ -301,20 +253,18 @@ export default {
   width: 100%;
   height: 100%;
   background-color: #fff;
+  border-radius: 12px;
 }
 
 .pec_header {
   width: 100%;
-  height: 50px;
-  background: #FCCF00;
+  height: 80px;
+  border-radius: 12px 12px 0 0;
   box-sizing: border-box;
+  border-bottom: solid 1px #cad1dc;
   display: flex;
   align-items: center;
   justify-content: space-between;
-  position: relative;
-  box-shadow: 0px 4px 12px 0px #3648601F;
-  padding: 0 10px;
-  box-sizing: border-box;
 }
 
 .pec_h_left {
@@ -322,22 +272,8 @@ export default {
   height: 100%;
   display: flex;
   align-items: center;
-  gap: 25px;
-  /* 保持左侧靠左 */
-}
-
-.pec_h_center {
-  position: absolute;
-  left: 50%;
-  top: 0;
-  height: 100%;
-  display: flex;
-  align-items: center;
-  transform: translateX(-50%);
-  z-index: 1;
-}
-
-.pec_h_l_title {
+  justify-content: center;
+  margin-left: 20px;
   font-weight: bold;
   font-size: 20px;
   color: #0e1e33;
@@ -348,6 +284,8 @@ export default {
   height: 100%;
   display: flex;
   align-items: center;
+  justify-content: center;
+  margin-right: 20px;
 }
 
 .pec_h_r_btnArea {
@@ -356,7 +294,7 @@ export default {
   justify-content: center;
 }
 
-.pec_h_r_btnArea>div {
+.pec_h_r_btnArea > div {
   width: auto;
   height: auto;
   display: flex;
@@ -366,90 +304,37 @@ export default {
   background-color: #f0f4fa;
   border-radius: 4px;
   cursor: pointer;
+  margin-right: 10px;
   font-size: 14px;
   font-weight: 400;
   color: #000;
   border: 1px solid #cad1dc;
 }
 
-.pec_h_r_btnArea>div>img {
+.pec_h_r_btnArea > div > img {
   width: 15px;
   height: 15px;
   margin-right: 5px;
 }
 
-.pec_h_r_btnArea>.pec_h_r_btn_refresh {
+.pec_h_r_btnArea > .pec_h_r_btn_refresh {
   color: #fff;
   background-color: #0061ff;
   border-color: #0061ff;
 }
 
-.pec_h_r_btnArea>.pec_h_r_btn_afterClass {
-  border-color: #F0E1DD;
-  background-color: #FFF7F5;
-  color: #F53F3F;
-}
-
-.backBtn {
-  width: 15px;
-  height: 15px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  cursor: pointer;
-}
-
-.backBtn img {
-  width: 100%;
-  height: 100%;
-}
-
-.class-info-group {
-  display: flex;
-  align-items: center;
-  gap: 10px;
-}
-
-.class-label {
-  font-size: 18px;
-  font-weight: bold;
-  color: #222;
-  margin-right: 5px;
-}
-
-.class-value {
-  font-size: 16px;
-  color: #222;
-  background: #FFFFFF3D;
-  border: 1px solid #00000080;
-  border-radius: 5px;
-  padding: 5px 18px;
-  min-width: 60px;
-  text-align: center;
-  display: inline-block;
-  box-sizing: border-box;
-}
-
 .pec_content {
   width: 100%;
-  height: calc(100% - 50px);
+  height: calc(100% - 80px);
   border-radius: 0 0 12px 12px;
   background-color: #fff;
 }
 
-.free-browse-switch {
-  display: flex;
-  align-items: center;
-  padding: 9px 10px;
-  background: #FFF7F5;
-  border-radius: 26px;
-  margin-left: 15px;
-  gap: 5px;
-}
 
-.switch-label {
-  background: linear-gradient(to right, #F53F3F, #FCCF00);
-  -webkit-background-clip: text;
-  color: transparent;
+.inviteBox {
+  font-size: 14px;
+  /* margin-top: 5px; */
+  color: #00000099;
+  text-align: center;
 }
 </style>

+ 455 - 0
src/components/pptEasyClass/index_new.vue

@@ -0,0 +1,455 @@
+<template>
+  <div class="pptEasyClass">
+    <div class="pec_main" v-loading="pageLoading">
+      <div class="pec_header">
+        <div class="pec_h_left">
+          <div @click.stop="back" class="backBtn" v-if="screenType != 2 || tType == 1">
+            <img src="../../assets/icon/newIcon/return.svg" alt="" />
+          </div>
+          <div v-if="tcid" class="class-info-group">
+            <span class="class-label">班级</span>
+            <span class="class-value">{{ className }}</span>
+          </div>
+          <div v-if="tcid" class="class-info-group">
+            <span class="class-label" v-if="inviteCode">识别码</span>
+            <span class="class-value" v-if="inviteCode">{{ inviteCode }}</span>
+          </div>
+        </div>
+        <div class="pec_h_center">
+          <div class="pec_h_l_title">
+            <span>{{ courseDetail.title }}</span>
+          </div>
+          <div class="free-browse-switch" v-if="courseDetail.userid == userid">
+            <span class="switch-label" :class="{ active: freeBrowse }">{{ freeBrowse ? '自由浏览' : '跟随模式' }}</span>
+            <el-switch
+              v-model="freeBrowse"
+              :active-value="true"
+              :inactive-value="false"
+              class="custom-switch"
+              active-color="#FCCF00"
+              inactive-color="#F53F3F"
+              @change="onFreeBrowseChange"
+            ></el-switch>
+          </div>
+        </div>
+        <div class="pec_h_right">
+          <div class="pec_h_r_btnArea">
+            <!-- <el-tooltip effect="light" content="刷新" placement="top">
+              <div class="pec_h_r_btn_refresh" @click="refreshCourse">
+                <img src="../../assets/icon/newIcons/refresh.png" alt="" />
+                <span>刷新</span>
+              </div>
+            </el-tooltip> -->
+            <div class="pec_h_r_btn_afterClass" @click="afterClass" v-if="courseDetail.userid == userid">
+              <img src="../../assets/icon/newIcon/afterClass.svg" alt="" />
+              <span>下课</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="pec_content">
+        <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;clipboard-write;clipboard-read"
+          webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen="" frameborder="no" border="0" :src="iframeSrc"
+          v-if="showIframe" style="width: 100%; height: 100%; border: none" ref="ppt"></iframe>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { myMixin } from '../../mixins/mixin';
+
+export default {
+  mixins: [myMixin],
+  data() {
+    return {
+      id: this.$route.query.courseId,
+      userid: this.$route.query.userid,
+      classId: this.$route.query.cid,
+      role: this.$route.query.role,
+      oid: this.$route.query.oid,
+      org: this.$route.query.org,
+      tType: this.$route.query.tType,
+      courseType: this.$route.query.type,
+      screenType: this.$route.query.screenType,
+      tcid2: this.$route.query.tcid,
+      tcid: "",
+      className: "",
+      showIframe: false,
+      iframeSrc: "",
+      courseDetail: {},
+      pageLoading: false,
+      inviteCode: "",
+      startTime: "",
+      freeBrowse: true, // 默认自由浏览
+      opertimer: null, // 定时器
+    };
+  },
+  methods: {
+    goTo(path) {
+      this.$router.push(path);
+    },
+    refreshCourse() {
+      this.getCourseDetail();
+    },
+    getCourseDetail() {
+      this.pageLoading = true;
+      let params = {
+        courseId: this.id
+      };
+
+      this.ajax
+        .get(this.$store.state.api + "selectCourseDetail3", params)
+        .then(res => {
+          console.log("getCourseDetail", res);
+          this.courseDetail = res.data[0][0];
+          this.courseDetail.chapters = JSON.parse(this.courseDetail.chapters);
+          this.tcid = this.arrayToArray(
+            this.courseDetail.juri ? this.courseDetail.juri.split(",") : [],
+            this.tcid2 ? this.tcid2.split(",") : []
+          )[0] || "";
+          if (this.tcid && res.data[1].length) {
+            let _inviteA = [];
+            for (var ik = 0; ik < res.data[1].length; ik++) {
+              _inviteA.push({
+                cid: res.data[1][ik].classid,
+                ic: res.data[1][ik].code,
+              });
+            }
+            for (var ik = 0; ik < _inviteA.length; ik++) {
+              if (
+                this.arrayToArray(
+                  _inviteA[ik].cid.split(","),
+                  this.tcid.split(",")
+                ).length
+              ) {
+                this.inviteCode = _inviteA[ik].ic;
+                break;
+              }
+            }
+          }
+          this.setPptIframe()
+          this.pageLoading = false;
+        })
+        .catch(err => {
+          console.log(err);
+          this.$message.error("获取课程数据失败");
+          this.pageLoading = false;
+        });
+    },
+    setPptIframe() {
+      this.showIframe = false;
+
+      this.$nextTick(() => {
+        let api = ''
+        if (this.$region == 'beta') {
+          api = 'https://beta.ppt.cocorobo.cn'
+        } else {
+          api = 'https://ppt.cocorobo.cn'
+        }
+        let _url = api + `/?mode=student&courseid=${this.id}&userid=${this.userid}&oid=${this.oid}&org=${this.org}&cid=${this.tcid}&type=${this.tType}`;
+
+        this.iframeSrc = _url;
+
+        this.showIframe = true;
+      });
+    },
+    arrayToArray(arrayo, arrayt) {
+      let array1 = arrayo;
+      let array2 = arrayt;
+
+      let commonElements = [];
+
+      for (let i = 0; i < array1.length; i++) {
+        for (let j = 0; j < array2.length; j++) {
+          if (array1[i] === array2[j]) {
+            commonElements.push(array1[i]);
+          }
+        }
+      }
+      return commonElements;
+    },
+    async getClassName() {
+      let courseGrade = await this.ajax.get(this.$store.state.api + "getClassById", { id: this.tcid2 });
+      this.className = courseGrade.data[0][0].grade;
+    },
+    back() {
+      if (this.tType != 2) {
+        this.goTo(
+          '/courseDetail?userid=' +
+          this.userid +
+          '&oid=' +
+          this.oid +
+          '&org=' +
+          this.org +
+          '&cid=' +
+          this.classId +
+          '&courseId=' +
+          this.id +
+          '&tType=' +
+          this.tType +
+          '&screenType=' +
+          this.screenType
+        )
+      } else {
+        this.goTo(
+          '/index?userid=' +
+          this.userid +
+          '&oid=' +
+          this.oid +
+          '&org=' +
+          this.org +
+          '&cid=' +
+          this.classId +
+          '&tType=' +
+          this.tType +
+          '&screenType=' +
+          this.screenType
+        )
+      }
+    },
+    afterClass() {
+      this.$confirm('确定下课吗,会让所有正在上课的学生全部退出登录?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.$refs.ppt.contentWindow.PPTistStudent.forceLogout();
+      }).catch(() => {});
+    },
+    onFreeBrowseChange(value) {
+      this.freeBrowse = value;
+      console.log('自由浏览模式已切换为1:', this.freeBrowse);
+      this.$refs.ppt.contentWindow.PPTistStudent.toggleFollowMode()
+    },
+    setOperationTime() {
+      let _this = this;
+      if (_this.opertimer) {
+        clearInterval(_this.opertimer);
+        _this.opertimer = null;
+      }
+      _this.opertimer = setInterval(() => {
+        _this.setoTime("600");
+      }, 600000);
+    },
+    setoTime(time) {
+      let params = [
+        {
+          uid: this.userid,
+          cid: this.id,
+          type: "2",
+          time: time,
+        },
+      ];
+      this.ajax
+        .post(this.$store.state.api + "addOperationTimeT2", params)
+        .then((res) => {})
+        .catch((err) => {
+          console.error(err);
+        });
+    },
+  },
+  destroyed() {
+    clearInterval(this.opertimer);
+    this.opertimer = null;
+    if (this.courseDetail.userid == this.userid && this.tcid2 && this.org == '16ace517-b5c7-4168-a9bb-a9e0035df840') {
+      let endTime = new Date().toLocaleString("zh-CN", {
+        hour12: false,
+        timeZone: "Asia/Shanghai"
+      }).replace(/\//g, "-")
+      let courseTime = Math.floor((new Date(endTime) - new Date(this.startTime)) / (1000 * 60))
+      this.syncClassData({
+        courseId: this.id,
+        title: this.courseDetail.title,
+        courseGrade: this.tcid2,
+        courseTime: courseTime,
+        startTime: this.startTime,
+        endTime: endTime,
+      })
+      console.log('同步数据')
+    }
+  },
+  mounted() {
+    this.startTime = new Date().toLocaleString("zh-CN", {
+      hour12: false,
+      timeZone: "Asia/Shanghai"
+    }).replace(/\//g, "-")
+    this.getClassName()
+    this.getCourseDetail();
+    this.setOperationTime();
+    window.onFreeBrowseChange = (value) => {
+      this.freeBrowse = value;
+      console.log('自由浏览模式已切换为:', this.freeBrowse);
+    }
+  }
+};
+</script>
+
+<style scoped>
+.pptEasyClass {
+  width: 100vw;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  box-sizing: border-box;
+  background-color: #f2f2f2;
+}
+
+.pec_main {
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+}
+
+.pec_header {
+  width: 100%;
+  height: 50px;
+  background: #FCCF00;
+  box-sizing: border-box;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  position: relative;
+  box-shadow: 0px 4px 12px 0px #3648601F;
+  padding: 0 10px;
+  box-sizing: border-box;
+}
+
+.pec_h_left {
+  width: auto;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  gap: 25px;
+  /* 保持左侧靠左 */
+}
+
+.pec_h_center {
+  position: absolute;
+  left: 50%;
+  top: 0;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  transform: translateX(-50%);
+  z-index: 1;
+}
+
+.pec_h_l_title {
+  font-weight: bold;
+  font-size: 20px;
+  color: #0e1e33;
+}
+
+.pec_h_right {
+  width: auto;
+  height: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.pec_h_r_btnArea {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.pec_h_r_btnArea>div {
+  width: auto;
+  height: auto;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 10px 20px;
+  background-color: #f0f4fa;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  font-weight: 400;
+  color: #000;
+  border: 1px solid #cad1dc;
+}
+
+.pec_h_r_btnArea>div>img {
+  width: 15px;
+  height: 15px;
+  margin-right: 5px;
+}
+
+.pec_h_r_btnArea>.pec_h_r_btn_refresh {
+  color: #fff;
+  background-color: #0061ff;
+  border-color: #0061ff;
+}
+
+.pec_h_r_btnArea>.pec_h_r_btn_afterClass {
+  border-color: #F0E1DD;
+  background-color: #FFF7F5;
+  color: #F53F3F;
+}
+
+.backBtn {
+  width: 15px;
+  height: 15px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+
+.backBtn img {
+  width: 100%;
+  height: 100%;
+}
+
+.class-info-group {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.class-label {
+  font-size: 18px;
+  font-weight: bold;
+  color: #222;
+  margin-right: 5px;
+}
+
+.class-value {
+  font-size: 16px;
+  color: #222;
+  background: #FFFFFF3D;
+  border: 1px solid #00000080;
+  border-radius: 5px;
+  padding: 5px 18px;
+  min-width: 60px;
+  text-align: center;
+  display: inline-block;
+  box-sizing: border-box;
+}
+
+.pec_content {
+  width: 100%;
+  height: calc(100% - 50px);
+  border-radius: 0 0 12px 12px;
+  background-color: #fff;
+}
+
+.free-browse-switch {
+  display: flex;
+  align-items: center;
+  padding: 9px 10px;
+  background: #FFF7F5;
+  border-radius: 26px;
+  margin-left: 15px;
+  gap: 5px;
+}
+
+.switch-label {
+  background: linear-gradient(to right, #F53F3F, #FCCF00);
+  -webkit-background-clip: text;
+  color: transparent;
+}
+</style>

+ 0 - 316
src/components/pptEasyClass/index_old.vue

@@ -1,316 +0,0 @@
-<template>
-  <div class="pptEasyClass">
-    <div class="pec_main" v-loading="pageLoading">
-      <div class="pec_header">
-        <div class="pec_h_left">
-          <div class="pec_h_l_title">
-            <span>{{ courseDetail.title }}</span>
-          </div>
-
-          <div v-if="tcid && inviteCode" class="inviteBox" style="margin-left: 20px;">
-              <span>随机码:{{ inviteCode }}</span>
-            </div>
-        </div>
-
-        <div class="pec_h_right">
-          <div class="pec_h_r_btnArea">
-            <el-tooltip effect="light" content="刷新" placement="top">
-              <div class="pec_h_r_btn_refresh" @click="refreshCourse">
-                <img src="../../assets/icon/newIcons/refresh.png" alt="" />
-                <span>刷新</span>
-              </div>
-            </el-tooltip>
-
-            <div
-              @click.stop="back"
-              v-if="screenType!=2"
-            >
-              <img src="../../assets/icon/newIcon/return.png" alt="" />
-              <span style="color: #000">返回</span>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <div class="pec_content">
-        <iframe allow="camera *; microphone *;display-capture;midi;encrypted-media;clipboard-write;clipboard-read" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen="" frameborder="no" border="0" :src="iframeSrc" v-if="showIframe" style="width: 100%; height: 100%; border: none"></iframe>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      id: this.$route.query.courseId,
-      userid: this.$route.query.userid,
-      classId: this.$route.query.cid,
-      role: this.$route.query.role,
-      oid: this.$route.query.oid,
-      org: this.$route.query.org,
-      tType: this.$route.query.tType,
-      courseType: this.$route.query.type,
-      screenType: this.$route.query.screenType,
-      tcid2: this.$route.query.tcid,
-      tcid:"",
-      showIframe: false,
-      iframeSrc: "",
-      courseDetail: {},
-      pageLoading: false,
-      inviteCode:"",
-      opertimer: null, // 定时器
-    };
-  },
-  methods: {
-    goTo(path) {
-      this.$router.push(path);
-    },
-    refreshCourse() {
-      this.getCourseDetail();
-    },
-    getCourseDetail() {
-      this.pageLoading = true;
-      let params = {
-        courseId: this.id
-      };
-
-      this.ajax
-        .get(this.$store.state.api + "selectCourseDetail3", params)
-        .then(res => {
-          console.log("getCourseDetail", res);
-          this.courseDetail = res.data[0][0];
-          this.courseDetail.chapters = JSON.parse(this.courseDetail.chapters);
-          this.tcid = this.arrayToArray(
-            this.courseDetail.juri ? this.courseDetail.juri.split(",") : [],
-            this.tcid2 ? this.tcid2.split(",") : []
-          )[0] || "";
-          if (this.tcid && res.data[1].length) {
-            let _inviteA = [];
-            for (var ik = 0; ik < res.data[1].length; ik++) {
-              _inviteA.push({
-                cid: res.data[1][ik].classid,
-                ic: res.data[1][ik].code,
-              });
-            }
-            for (var ik = 0; ik < _inviteA.length; ik++) {
-              if (
-                this.arrayToArray(
-                  _inviteA[ik].cid.split(","),
-                  this.tcid.split(",")
-                ).length
-              ) {
-                this.inviteCode = _inviteA[ik].ic;
-                break;
-              }
-            }
-          }
-          this.setPptIframe()
-          this.pageLoading = false;
-        })
-        .catch(err => {
-          console.log(err);
-          this.$message.error("获取课程数据失败");
-          this.pageLoading = false;
-        });
-    },
-    setPptIframe() {
-      this.showIframe = false;
-
-      this.$nextTick(() => {
-        let _url = `https://ppt.cocorobo.cn/?mode=student&courseid=${this.id}&userid=${this.userid}&oid=${this.oid}&org=${this.org}&cid=${this.tcid}&type=${this.tType}`;
-
-        this.iframeSrc = _url;
-
-        this.showIframe = true;
-      });
-    },
-    arrayToArray(arrayo, arrayt) {
-      let array1 = arrayo;
-      let array2 = arrayt;
-
-      let commonElements = [];
-
-      for (let i = 0; i < array1.length; i++) {
-        for (let j = 0; j < array2.length; j++) {
-          if (array1[i] === array2[j]) {
-            commonElements.push(array1[i]);
-          }
-        }
-      }
-      return commonElements;
-    },
-    back(){
-      if(this.tType!=2){
-        this.goTo(
-          '/courseDetail?userid=' +
-            this.userid +
-            '&oid=' +
-            this.oid +
-            '&org=' +
-            this.org +
-            '&cid=' +
-            this.classId +
-            '&courseId=' +
-            this.id +
-            '&tType=' +
-            this.tType +
-            '&screenType=' +
-            this.screenType
-        )
-      }else{
-        this.goTo(
-          '/index?userid=' +
-            this.userid +
-            '&oid=' +
-            this.oid +
-            '&org=' +
-            this.org +
-            '&cid=' +
-            this.classId +
-            '&tType=' +
-            this.tType +
-            '&screenType=' +
-            this.screenType
-        )
-      }
-    },
-    setOperationTime() {
-      let _this = this;
-      if (_this.opertimer) {
-        clearInterval(_this.opertimer);
-        _this.opertimer = null;
-      }
-      _this.opertimer = setInterval(() => {
-        _this.setoTime("600");
-      }, 600000);
-    },
-    setoTime(time) {
-      let params = [
-        {
-          uid: this.userid,
-          cid: this.id,
-          type: "2",
-          time: time,
-        },
-      ];
-      this.ajax
-        .post(this.$store.state.api + "addOperationTimeT2", params)
-        .then((res) => {})
-        .catch((err) => {
-          console.error(err);
-        });
-    },
-  },
-  destroyed() {
-    clearInterval(this.opertimer);
-    this.opertimer = null;
-  },
-  mounted() {
-    this.getCourseDetail();
-    this.setOperationTime();
-  }
-};
-</script>
-
-<style scoped>
-.pptEasyClass {
-  width: 100vw;
-  height: 100vh;
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-  box-sizing: border-box;
-  padding: 20px;
-  background-color: #f2f2f2;
-}
-
-.pec_main {
-  width: 100%;
-  height: 100%;
-  background-color: #fff;
-  border-radius: 12px;
-}
-
-.pec_header {
-  width: 100%;
-  height: 80px;
-  border-radius: 12px 12px 0 0;
-  box-sizing: border-box;
-  border-bottom: solid 1px #cad1dc;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-}
-
-.pec_h_left {
-  width: auto;
-  height: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-left: 20px;
-  font-weight: bold;
-  font-size: 20px;
-  color: #0e1e33;
-}
-
-.pec_h_right {
-  width: auto;
-  height: 100%;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  margin-right: 20px;
-}
-
-.pec_h_r_btnArea {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.pec_h_r_btnArea > div {
-  width: auto;
-  height: auto;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  padding: 10px 20px;
-  background-color: #f0f4fa;
-  border-radius: 4px;
-  cursor: pointer;
-  margin-right: 10px;
-  font-size: 14px;
-  font-weight: 400;
-  color: #000;
-  border: 1px solid #cad1dc;
-}
-
-.pec_h_r_btnArea > div > img {
-  width: 15px;
-  height: 15px;
-  margin-right: 5px;
-}
-
-.pec_h_r_btnArea > .pec_h_r_btn_refresh {
-  color: #fff;
-  background-color: #0061ff;
-  border-color: #0061ff;
-}
-
-.pec_content {
-  width: 100%;
-  height: calc(100% - 80px);
-  border-radius: 0 0 12px 12px;
-  background-color: #fff;
-}
-
-
-.inviteBox {
-  font-size: 14px;
-  /* margin-top: 5px; */
-  color: #00000099;
-  text-align: center;
-}
-</style>

+ 18 - 8
src/components/studyStudent.vue

@@ -535,12 +535,12 @@
                       style="height: 650px; width: calc(100% - 50px)"
                     >
                       <video-player
-                        class="video-player vjs-custom-skin"
+                        class="video-player vjs-custom-skin notop"
                         :class="contentDialog == false ? 'isAllWidth' : ''"
                         :playsinline="true"
                         :options="playerO[taskCount]"
                         @play="onPlayerPlay($event)"
-                        style="width: 100%; height: 100%; margin: 0 0 0 30px"
+                        style="width: 100%; height: 650px; margin: 0 0 0 30px"
                       ></video-player>
                     </div>
                   </div>
@@ -17534,6 +17534,9 @@ export default {
                 } else if (_chapterData[this.taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[this.taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -17703,6 +17706,9 @@ export default {
                 } else if (_chapterData[this.taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[this.taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -21856,12 +21862,13 @@ export default {
       hour12: false, 
       timeZone: "Asia/Shanghai" 
     }).replace(/\//g, "-");
-    if (this.tType == 1) {
-       // 开局关闭学生查看内容
-      this.StulookMode(false)
-      // 开局打开跟随模式
-      this.followingMode(true)
-    }
+
+    // if (this.tType == 1) {
+    //    // 开局关闭学生查看内容
+    //   this.StulookMode(false)
+    //   // 开局打开跟随模式
+    //   this.followingMode(true)
+    // }
     document.body.addEventListener("click", (e) => {
       if (this.isUpdateToolDetail1) {
         this.updateToolDetail(this.toolDetailIndex);
@@ -26419,4 +26426,7 @@ div::-webkit-scrollbar {
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs_video_3-dimensions.vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 11 - 2
src/components/studySutdentClass/studyStudent.vue

@@ -569,12 +569,12 @@
                       style="height: 650px; width: calc(100% - 50px)"
                     >
                       <video-player
-                        class="video-player vjs-custom-skin"
+                        class="video-player vjs-custom-skin notop"
                         :class="contentDialog == false ? 'isAllWidth' : ''"
                         :playsinline="true"
                         :options="playerO[0]"
                         @play="onPlayerPlay($event)"
-                        style="width: 100%; height: 100%; margin: 0 0 0 30px"
+                        style="width: 100%; height: 650px; margin: 0 0 0 30px"
                       ></video-player>
                     </div>
                   </div>
@@ -21576,6 +21576,9 @@ export default {
                 } else if (_chapterData[taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -21746,6 +21749,9 @@ export default {
                 } else if (_chapterData[taskCount][0].type == 16) {
                   this.showType = 16;
                   this.pptImgUrl1 = _url;
+                } else if (_chapterData[taskCount][0].type == 17) {
+                  this.showType = 16;
+                  this.pptImgUrl1 = _url;
                 }
               }
             }
@@ -30534,4 +30540,7 @@ div::-webkit-scrollbar {
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs_video_3-dimensions.vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 44 - 0
src/mixins/mixin.js

@@ -122,6 +122,50 @@ export const myMixin = {
         console.error("同步失败:", error);
         return { success: false, msg: error };
       }
+    },
+    // 新增:上课/备课数据实时同步接口
+    async syncClassData2(classData) {
+      if (!this.$route.query.userid) return
+      try {
+        if(!this.userJson || !this.userJson.accountNumber){
+            let res = await this.ajax.get(this.$store.state.api + "selectUser", {
+            userid: this.$route.query.userid
+            });
+            this.userJson = res.data[0][0]
+        }
+      } catch (e) {
+        console.log(e);
+        return this.syncClassData(classData);
+      }
+      let courseGrade = await this.ajax.get(this.$store.state.api + "getClassById", { id: classData.courseGrade });
+      let coursePackageName = await this.ajax.get(this.$store.state.api + "getCopyCourseName", { id: classData.courseId });
+      let params = {
+        "serverName": "深教AI6",
+        "dataType": 0,
+        "teacherName": this.userJson.username,
+        "teacherAccount": this.userJson.accountNumber,
+        "teacherPhone": this.userJson.phonenumber,
+        "eduId": this.userJson.sessionid,
+        "schoolName": this.userJson.schoolName,
+        "area": this.schooldest,
+        "coursePackageName": coursePackageName.data[0][0].title,
+        "courseId": classData.courseId,
+        "courseName": classData.title,
+        "courseGrade": courseGrade.data[0][0].name,
+        "courseTime": classData.courseTime,
+        "startTime": classData.startTime,
+        "endTime": classData.endTime
+      }
+      try {
+        const response = await this.ajax.post(
+          this.$store.state.apiSz + 'sync/class',
+          params
+        );
+        return { success: true, data: response.data };
+      } catch (error) {
+        console.error("同步失败:", error);
+        return { success: false, msg: error };
+      }
     }
   }
 };

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