Selaa lähdekoodia

Merge branch 'beta' into HK

qgt 1 viikko sitten
vanhempi
commit
46c18d2746
35 muutettua tiedostoa jossa 2887 lisäystä ja 291 poistoa
  1. 4 0
      dist/index.html
  2. 0 0
      dist/static/css/app.f044a20c8183a0a01ba12a45c253bd8c.css
  3. 0 0
      dist/static/css/app.f044a20c8183a0a01ba12a45c253bd8c.css.map
  4. 1 0
      dist/static/js/app.52900657b90b9b9abffb.js
  5. 1 0
      dist/static/js/app.52900657b90b9b9abffb.js.map
  6. 1 0
      dist/static/js/app.8295d0bc13b4021732f0.js
  7. 0 0
      dist/static/js/app.8295d0bc13b4021732f0.js.map
  8. 0 0
      dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map
  9. 3 0
      src/assets/icon/course/backPage.svg
  10. BIN
      src/assets/icon/course/icon_return2.png
  11. 3 0
      src/assets/icon/newIcon/afterClass.svg
  12. 3 0
      src/assets/icon/newIcon/return.svg
  13. BIN
      src/assets/icon/secondToolList/ppt.png
  14. 1 1
      src/common/axios.config.js
  15. 19 6
      src/components/components/choseWorksDetailDialog.vue
  16. 32 8
      src/components/components/cocoFlowDia.vue
  17. 224 49
      src/components/courseDetail.vue
  18. 473 0
      src/components/dialog/addClassDialog.vue
  19. 294 0
      src/components/dialog/selectTeachingClassDialog.vue
  20. 1 1
      src/components/easy/studyStudent.vue
  21. 179 35
      src/components/easy2/studyStudent.vue
  22. 207 41
      src/components/easy3/studyStudent.vue
  23. 188 69
      src/components/index.vue
  24. 458 0
      src/components/pptEasyClass/index.vue
  25. 340 0
      src/components/pptEasyClass/index_old.vue
  26. 184 38
      src/components/studyStudent.vue
  27. 1 1
      src/components/studyStudentJiu.vue
  28. 157 37
      src/components/studySutdentClass/studyStudent.vue
  29. 1 1
      src/components/trainCourse/easy2/studyStudent.vue
  30. 1 1
      src/components/trainCourse/easy3/studyStudent.vue
  31. 1 1
      src/components/trainCourse/studyStudent.vue
  32. 2 0
      src/config/config.js
  33. 12 0
      src/main.js
  34. 89 1
      src/mixins/mixin.js
  35. 7 1
      src/router/index.js

+ 4 - 0
dist/index.html

@@ -27,7 +27,11 @@
     html,
     body{
       font-family: '黑体';
+<<<<<<< HEAD
     }</style><link href=./static/css/app.9d7189a9e7cf4c82f7d016c5e252d170.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.8295d0bc13b4021732f0.js></script></body></html><script>function stopSafari() {
+=======
+    }</style><link href=./static/css/app.f044a20c8183a0a01ba12a45c253bd8c.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.52900657b90b9b9abffb.js></script></body></html><script>function stopSafari() {
+>>>>>>> beta
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/static/css/app.f044a20c8183a0a01ba12a45c253bd8c.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/static/css/app.f044a20c8183a0a01ba12a45c253bd8c.css.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
dist/static/js/app.52900657b90b9b9abffb.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
dist/static/js/app.52900657b90b9b9abffb.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
dist/static/js/app.8295d0bc13b4021732f0.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/static/js/app.8295d0bc13b4021732f0.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/static/js/manifest.3ad1d5771e9b13dbdad2.js.map


+ 3 - 0
src/assets/icon/course/backPage.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.78578 10L13.6783 15.8925L12.4999 17.0709L6.01828 10.5892C5.86205 10.4329 5.77429 10.221 5.77429 10C5.77429 9.77906 5.86205 9.56714 6.01828 9.41087L12.4999 2.9292L13.6783 4.10753L7.78578 10Z" fill="black"/>
+</svg>

BIN
src/assets/icon/course/icon_return2.png


+ 3 - 0
src/assets/icon/newIcon/afterClass.svg

@@ -0,0 +1,3 @@
+<svg width="15" height="16" viewBox="0 0 15 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.3486 2.62793C10.5543 2.26864 11.0127 2.14333 11.3721 2.34863C11.6236 2.49258 11.8664 2.65139 12.0977 2.82324C12.4933 3.11727 12.8575 3.45079 13.1846 3.81738C14.3131 5.08227 15 6.74747 15 8.57031C14.9998 12.5432 11.7462 15.75 7.75 15.75C3.75375 15.75 0.500233 12.5432 0.5 8.57031C0.500015 6.74747 1.18688 5.08227 2.31543 3.81738C2.64253 3.45081 3.00667 3.11726 3.40234 2.82324C3.63359 2.65141 3.87641 2.49257 4.12793 2.34863C4.48735 2.14337 4.94574 2.26863 5.15137 2.62793C5.35668 2.98734 5.23136 3.44571 4.87207 3.65137C4.67266 3.76551 4.4802 3.89112 4.29688 4.02734C3.98291 4.26065 3.69396 4.52572 3.43457 4.81641C2.54061 5.81849 2.00001 7.1318 2 8.57031C2.00023 11.6995 4.56685 14.25 7.75 14.25C10.9331 14.25 13.4998 11.6995 13.5 8.57031C13.5 7.13181 12.9594 5.8185 12.0654 4.81641C11.806 4.52569 11.5171 4.26067 11.2031 4.02734C11.0198 3.8911 10.8274 3.76552 10.6279 3.65137C10.2686 3.44573 10.1433 2.98736 10.3486 2.62793ZM7.80371 0.232422C8.21785 0.232505 8.55371 0.568259 8.55371 0.982422V8.16211C8.55358 8.57616 8.21777 8.91203 7.80371 8.91211C7.38958 8.91211 7.05384 8.57621 7.05371 8.16211V0.982422C7.05371 0.568208 7.3895 0.232422 7.80371 0.232422Z" fill="#F53F3F"/>
+</svg>

+ 3 - 0
src/assets/icon/newIcon/return.svg

@@ -0,0 +1,3 @@
+<svg width="9" height="14" viewBox="0 0 9 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.5 13L1.5 7L7.5 1" stroke="black" stroke-opacity="0.9" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

BIN
src/assets/icon/secondToolList/ppt.png


+ 1 - 1
src/common/axios.config.js

@@ -15,7 +15,7 @@ axios.interceptors.request.use((config) => {
             'Content-Type': 'application/x-www-form-urlencoded'
         }
     }
-    if (config.url === 'https://gpt.cocorobo.cn/chat' || config.url === 'https://gpt4.cocorobo.cn/imageAnalyse' || config.url === 'https://gpt4.cocorobo.cn/create_free_assistants' || config.url === 'https://gpt4.cocorobo.cn/assistants_completion_response') {
+    if (config.url === 'https://gpt.cocorobo.cn/chat' || config.url === 'https://gpt4.cocorobo.cn/imageAnalyse' || config.url === 'https://gpt4.cocorobo.cn/create_free_assistants' || config.url === 'https://gpt4.cocorobo.cn/assistants_completion_response' || config.url.includes('/szdjg/')) {
         config.data = config.data //序列化post 参数
     }else if(config.url.indexOf('https://gpt4.cocorobo.cn/')!=-1 || config.url.indexOf('https://claude3.cocorobo.cn/')!=-1 || config.url.indexOf('https://appapi.cocorobo.cn/')!=-1){
 			config.headers = {

+ 19 - 6
src/components/components/choseWorksDetailDialog.vue

@@ -4,6 +4,7 @@
       :visible.sync="show"
       width="100%"
       height="100%"
+      style="overflow: hidden;"
       fullscreen
       :modal="true"
       :close-on-click-modal="false"
@@ -84,7 +85,7 @@
                         >
                           (多选题)
                         </div>
-                        <div style="display: flex;align-items: center;">题目:<span v-html="renderedFormula(item1.teststitle)"></span></div>
+                        <div style="display: flex;"><span style="flex-shrink: 0;">题目:</span><span v-html="renderedFormula(item1.teststitle)"></span></div>
                       </div>
                       <img
                         v-if="item1.img"
@@ -1182,7 +1183,7 @@
 
                         <template v-if="[45].includes(toolType)">
                           <span v-for="(answer,answerIndex) in worksCheckAnswer(item)" :key="item.userid+'-'+answerIndex+'-'+answer.index">
-                            
+
                             <template v-if="answer.type===1">
                               <span  v-for="(item2,indP) in answer.label" :key="indP +'indP'">
                                 <span :class="`${item2.right?'answerRight':'answerWrong'}`">{{ item2.label }}</span>
@@ -1198,7 +1199,7 @@
 
                           </span>
                         </template>
-												
+
 
                         <div class="answerSelect "  v-if="[57].includes(toolType)">
                           <!-- <img style="width: 300px;" src="../../assets/icon/word2.png" /> -->
@@ -1776,16 +1777,27 @@ export default {
         let answerData = []
         let num = 0
         allData.testJson.testJson.forEach(e=>{
-          answerData.push(e.answer)
+          let _answer = e.answer;
+          if(typeof _answer == 'object'){
+            _answer.sort((a,b)=>a-b)
+          }
+          answerData.push(_answer)
         })
 
+        allData.anwer.forEach(e=>{
+          if(typeof e == 'object'){
+            e.sort((a,b)=>a-b)
+          }
+        })
+
+
         answerData.forEach((e,i)=>{
           if (JSON.stringify(e) == JSON.stringify(allData.anwer[i])) {
             num++
           }
         })
 
-        let et = ((num / answerData.length).toFixed(1)) * 100
+        let et = ((num / answerData.length) * 100).toFixed(1)
 				return  et+'%';
 			}
     }
@@ -4388,9 +4400,10 @@ ol {
 }
 
 .a_add_head >>> .katex {
-  font-size: 16px;
+  font-size: 14px;
   width: 100%;
   white-space: normal;
+  font-family: '黑体' !important;
 }
 .a_add_head >>> .katex .base{
   display: inline !important;

+ 32 - 8
src/components/components/cocoFlowDia.vue

@@ -15,7 +15,7 @@
             </div>
            
             <div class="markDialog">
-                <template v-if="listData.length && listData[0].messages.length">
+                <template v-if="listData.length && showListData(listData)">
                     <div v-for="(item,index) in listData" :key="index">
                         <div class="BodyCon" v-if="item.messages.length"  >
                             <div class="BodyConTit">节点{{ index + 1}}</div>
@@ -62,16 +62,40 @@ import MarkdownIt from "markdown-it";
             }
         },
         computed: {
+            showListData(){
+                return function (val) {
+                   let kk = val.map(e=> e.messages).flat()
+                   console.log('kk',kk);
+                   if (kk.length == 0) {
+                    return false
+                   }
+                   return true
+                };
+            },
             MarkdownT() {
                 return function (c) {
+                    
                     let md = new MarkdownIt({
-  html: true, // 允许渲染 HTML
-  linkify: true, // 自动将URL链接转化为可点击链接
-  typographer: true, // 启用排版规则(如替换 `"` 为 “)
-});
-                    return c
-                    ? md.render(c) : "";
-                };
+                        html: true, // 允许渲染 HTML
+                        linkify: true, // 自动将URL链接转化为可点击链接 
+                        typographer: true, // 启用排版规则(如替换 `"` 为 “)
+                    });
+                    const renderedContent = c ? md.render(c) : "";
+
+                    // 使用正则表达式替换链接
+                    const result = renderedContent.replace(/<a href="([^"]+)">([^<]*)<\/a>/g, (match, url, text) => {
+                        // 判断链接是否为图片格式
+                        if (/\.(png|jpg|jpeg|gif|bmp|svg)$/i.test(url)) {
+                            // 返回<img>标签
+                            return `<img src="${url}" alt="${text}" />`;
+                        } else {
+                            // 返回原来的<a>标签
+                            return match;
+                        }
+                    });
+
+                    return result;
+                }
             }
         },
         methods: {

+ 224 - 49
src/components/courseDetail.vue

@@ -47,8 +47,8 @@
             <div class="right_box">
               <div class="rightT">
                 <div class="right_box_title">{{ courseDetail.title }}</div>
-                <div class="jd">{{ chapInfo.length }}阶段</div>
-                <div class="jd">{{ rw }}任务</div>
+                <div class="jd" v-if="courseDetail.state!=7">{{ chapInfo.length }}阶段</div>
+                <div class="jd" v-if="courseDetail.state!=7">{{ rw }}任务</div>
               </div>
               <div class="cType" v-if="courseType.length">
                 <div
@@ -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="" />
@@ -206,23 +206,23 @@
           <div class="sLeft" v-if="courseDetail.brief">
             <div class="courseT">
               <span>课程详情</span>
-              <div class="r_pub_button_op" v-if="(courseDetail.state == 6 || courseDetail.state == 5) && courseDetail.userid == userid" @click="aiChatContent">优化</div> 
+              <div class="r_pub_button_op" v-if="(courseDetail.state == 6 || courseDetail.state == 5) && courseDetail.userid == userid" @click="aiChatContent">优化</div>
             </div>
             <div v-loading="elLoading" element-loading-text="小可正在努力生成中,请稍等..." ref="chatDialog" class="courseTd vditor-reset" v-html="brief"></div>
           </div>
           <div :class="courseDetail.brief != '' ? 'rightTd' : 'noBRight'">
-            <div v-if="tType == 1 || tType == 4" class="checkBox">
+            <div v-if="(tType == 1 || tType == 4) && courseDetail.state !=7" class="checkBox">
               <span :class="{ active: type == 2 }" @click="type = 2"
                 >阶段选择
                 <div v-show="false">
                   {{
-                    courseDetail.state == 1 
+                    courseDetail.state == 1
                       ? "阶段模式"
                       : courseDetail.state == 2
                       ? "任务模式"
                       : courseDetail.state == 3
-                      ? "极简模式" 
-                      : courseDetail.state == 4 || courseDetail.state == 5 
+                      ? "极简模式"
+                      : courseDetail.state == 4 || courseDetail.state == 5
                       ? "AI模式"
                       : "上课模式"
                   }}
@@ -244,6 +244,7 @@
                 class="courseItem"
                 v-for="(item, index) in chapInfo"
                 :key="index"
+                v-if="courseDetail.state!=7"
                 @click="goToStudyRate(index)"
                 :class="{
                   disabled: isFollow == 2 && tType == 2 && followC != index,
@@ -265,6 +266,20 @@
                 </div>
               </div>
 
+              <div
+                class="courseItem"
+                v-if="courseDetail.state==7"
+                @click="goToStudyRate('')"
+              >
+                <div class="jdAndTask">
+                  <div>进入课程</div>
+                  <div>点击进入课程</div>
+                </div>
+                <div style="font-size: 14px; font-weight: 400; color: 3681FC;opacity: 0;">
+                  0个任务
+                </div>
+              </div>
+
               <!-- <div
                 class="blue_box_one"
                 v-for="(item, index) in chapInfo"
@@ -456,7 +471,7 @@
                               </div>
                               <!-- <div v-if="item3.tool == 5">
                             <img
-                              
+
                               src="../assets/icon/thirdToolList/score.png"
                               alt
                             />
@@ -1041,6 +1056,7 @@
             <div
               class="blue_box"
               v-for="(item, index) in chapInfo"
+              v-if="courseDetail.state!=7"
               :key="index"
               @click="addUserRate(index)"
             >
@@ -1084,6 +1100,7 @@
       </div>
       <div class="cancelDiy" @click="dialogVisibleSk = false">取消</div>
     </el-dialog>
+    <selectTeachingClassDialog :courseDetail="courseDetail" :userId="userid" ref="selectTeachingClassDialogRef" @success="selectClassSuccess" @changeClassList="changeClassList"/>
   </div>
 </template>
 
@@ -1109,6 +1126,8 @@ let converter = OpenCC.Converter({
 		to:'hk'
 })
 
+import selectTeachingClassDialog from "./dialog/selectTeachingClassDialog.vue";
+
 const getFile = (url) => {
   return new Promise((resolve, reject) => {
     var credentials = {
@@ -1140,7 +1159,7 @@ const getFile = (url) => {
           resolve({ data: 1 });
         }else {
           resolve({ data: data.Body });
-          console.log(data); 
+          console.log(data);
         }          // sxuccessful response
 
       });
@@ -1165,7 +1184,8 @@ export default {
   components: {
     Heatmap,
     Group,
-    scoreZong
+    scoreZong,
+    selectTeachingClassDialog
   },
   data() {
     return {
@@ -1394,7 +1414,7 @@ export default {
               this.screenType
           );
         }
-      }else if (this.courseDetail.state == 6) {
+      } else if (this.courseDetail.state == 6) {
         if (this.classList.length) {
           this.goTo(
             "/studySutdentClass?type=" +
@@ -1436,48 +1456,110 @@ export default {
               this.screenType
           );
         }
+      }  else if (this.courseDetail.state == 7) {
+        if(this.classList.length){
+          this.goTo(
+            "/pptEasyClass?type=" +
+              this.checkStage +
+              "&courseId=" +
+              this.id +
+              "&userid=" +
+              this.userid +
+              "&oid=" +
+              this.oid +
+              "&org=" +
+              this.org +
+              "&cid=" +
+              this.classId +
+              "&tType=" +
+              this.tType +
+              "&screenType=" +
+              this.screenType +
+              "&tcid=" +
+              id
+          );
+        }else {
+          this.goTo(
+            "/pptEasyClass?type=" +
+              this.checkStage +
+              "&courseId=" +
+              this.id +
+              "&userid=" +
+              this.userid +
+              "&oid=" +
+              this.oid +
+              "&org=" +
+              this.org +
+              "&cid=" +
+              this.classId +
+              "&tType=" +
+              this.tType +
+              "&screenType=" +
+              this.screenType
+          );
+        }
       }
+
+      let params = [
+        {
+          courseId: this.id,
+        },
+      ];
+      this.ajax
+        .post(this.$store.state.api + "addOpenCoursenum", params)
+        .then((res) => {})
+        .catch((err) => {
+          console.error(err);
+        });
+
+
     },
     goToStudyOrDia(l) {
-      if (l.length > 0) {
-        this.dialogVisibleSk = true;
+      //if (l.length > 0) {
+        // this.dialogVisibleSk = true;
+        this.$refs.selectTeachingClassDialogRef.open({classList:this.classList})
+        this.inviteCodeFn(this.classList)
 				this.insertMemorandum("点击<span class='btn'>以班级授课</span>")
-      } else {
-				this.getCourseDetail1().then(_=>{
-					if(this.classList.length<=0){
-						this.$confirm("该课程尚未指定授课班级,请返回首页,使用修改功能添加授课班级。","提示",{
-							confirmButtonText: '去修改',
-        		  cancelButtonText: '取消',
-							type:"error",
-						}).then(() => {
-							if(this.courseDetail.state == 1 || this.courseDetail.state == 2){
-								window.topU.postMessage({ tools: "openNewCourseUpdate",cid:this.id }, "*");
-							}else if(this.courseDetail.state == 3){
-								window.topU.postMessage({ tools: "openCourseEUpdate",cid:this.id }, "*");
-							}else if(this.courseDetail.state == 4 || this.courseDetail.state == 5){
-								window.topU.postMessage({ tools: "openCourseAiUpdate",cid:this.id }, "*");
-              }else if(this.courseDetail.state == 6){
-								window.topU.postMessage({ tools: "openCourseAiUpdate2",cid:this.id }, "*");
-              }
-
-						})
-					}else{
-						this.dialogVisibleSk = true;
-					}
-        })
+      // } else {
+			// 	this.getCourseDetail1().then(_=>{
+			// 		if(this.classList.length<=0){
+			// 			this.$confirm("该课程尚未指定授课班级,请返回首页,使用修改功能添加授课班级。","提示",{
+			// 				confirmButtonText: '去修改',
+      //   		  cancelButtonText: '取消',
+			// 				type:"error",
+			// 			}).then(() => {
+			// 				if(this.courseDetail.state == 1 || this.courseDetail.state == 2){
+			// 					window.topU.postMessage({ tools: "openNewCourseUpdate",cid:this.id }, "*");
+			// 				}else if(this.courseDetail.state == 3){
+			// 					window.topU.postMessage({ tools: "openCourseEUpdate",cid:this.id }, "*");
+			// 				}else if(this.courseDetail.state == 4 || this.courseDetail.state == 5){
+			// 					window.topU.postMessage({ tools: "openCourseAiUpdate",cid:this.id }, "*");
+      //         }else if(this.courseDetail.state == 6){
+			// 					window.topU.postMessage({ tools: "openCourseAiUpdate2",cid:this.id }, "*");
+      //         }else if(this.courseDetail.state == 7){
+      //           window.topU.postMessage({ tools: "openCoursePptUpdate",cid:this.id }, "*");
+      //         }
+			// 			})
+			// 		}else{
+			// 			this.dialogVisibleSk = true;
+			// 		}
+      //   })
         // this.addUserRate(0);
-      }
+      //}
     },
     goToStudyRate(i) {
       this.checkStage = i;
       if (this.tType == 2) {
         this.addUserRate(i);
       } else {
-        if (this.classList.length > 0) {
-          this.dialogVisibleSk = true;
-        } else {
-          this.addUserRate(i);
-        }
+        this.$refs.selectTeachingClassDialogRef.open({classList:this.classList})
+        this.inviteCodeFn(this.classList)
+        // if (this.classList.length > 0) {
+        //   // this.dialogVisibleSk = true;
+        //   this.$refs.selectTeachingClassDialogRef.open({classList:this.classList})
+        // } else {
+        //   this.addUserRate(i);
+        // }
       }
     },
     addUserRate(i) {
@@ -1508,7 +1590,7 @@ export default {
       //     }
       //   }
       // }
-      if (this.isFollow == 2 && this.tType == 2 && this.followC != i) {
+      if (this.isFollow == 2 && this.tType == 2 && this.followC != i && this.courseDetail.state != 7) {
         return;
       }
       let params = {
@@ -1596,7 +1678,27 @@ export default {
                   "&screenType=" +
                   this.screenType
               );
-            }
+            }else if (this.courseDetail.state == 7) {
+              this.goTo(
+                "/pptEasyClass?type=" +
+                  this.checkStage +
+                  "&courseId=" +
+                  this.id +
+                  "&userid=" +
+                  this.userid +
+                  "&oid=" +
+                  this.oid +
+                  "&org=" +
+                  this.org +
+                  "&cid=" +
+                  this.classId +
+                  "&tType=" +
+                  this.tType +
+                  "&screenType=" +
+                  this.screenType
+              );
+            // this.gotoCourse(this.classId);
+          }
           } else if (this.tType == 2) {
             // this.goTo(
             //   "/studyStudent?type=" +
@@ -1693,7 +1795,27 @@ export default {
                   "&screenType=" +
                   this.screenType
               );
-            }
+            }else if (this.courseDetail.state == 7) {
+              this.goTo(
+            "/pptEasyClass?type=" +
+              this.checkStage +
+              "&courseId=" +
+              this.id +
+              "&userid=" +
+              this.userid +
+              "&oid=" +
+              this.oid +
+              "&org=" +
+              this.org +
+              "&cid=" +
+              this.classId +
+              "&tType=" +
+              this.tType +
+              "&screenType=" +
+              this.screenType
+          );
+            // this.gotoCourse(this.classId);
+          }
             // this.gotoCourse(this.classId);
           } else {
             this.goTo(
@@ -1758,7 +1880,7 @@ export default {
         }
       }
       this.brief = this.sbrief ? this.sbrief : this.MarkdownT(this.courseDetail.brief)
-      
+
       if(this.brief && !this.sbrief && (this.courseDetail.state == 6 || this.courseDetail.state == 5) && this.courseDetail.userid == this.userid){
         this.aiChatContent()
       }
@@ -1804,7 +1926,13 @@ export default {
           ic: res.data[4][i].code,
         });
       }
-      if (res.data[3].length != this.inviteCode.length) {
+
+      let _inviteCodeLength = res.data[3].reduce((pre,cur)=>{
+        this.inviteCode.map(i=>i.cid).includes(cur.id)?pre+=1:'';
+        return pre
+      },0)
+
+      if (_inviteCodeLength != res.data[3].length) {
         let classArray = [];
         let noClassArray = [];
         for (var i = 0; i < res.data[3].length; i++) {
@@ -1843,6 +1971,11 @@ export default {
           }
         }
       }
+
+      if(this.courseDetail.state == 7 && this.tType == 2){
+        this.goToStudyRate('')
+      }
+
       // debugger
     },
     addInviteCode() {
@@ -2400,6 +2533,48 @@ export default {
         }
       };
     },
+    selectClassSuccess(classId){
+      this.gotoCourse(classId);
+      this.$refs.selectTeachingClassDialogRef.close();
+    },
+    async changeClassList(data){
+      this.classList = JSON.parse(JSON.stringify(data))
+      let params = [{
+        cid:this.id,
+        juri:this.classList.map(i=>i.id).join(',')
+      }]
+      this.ajax.post(this.$store.state.api+"update_CourseJuriById",params).then(res=>{
+        if(res.data==1){
+          console.log("修改成功")
+        }
+      })
+
+      this.inviteCodeFn();
+    },
+    // 随机码
+    async inviteCodeFn(){
+      let _inviteCodeLength = this.classList.reduce((pre,cur)=>{this.inviteCode.map(i=>i.cid).includes(cur.id)?pre+=1:'';return pre},0)
+      if (_inviteCodeLength != this.classList.length) {
+        let classArray = [];
+        let noClassArray = [];
+        for (var i = 0; i < this.classList.length; i++) {
+          classArray.push(this.classList[i].id);
+          noClassArray.push(this.classList[i].id);
+        }
+        this.inviteCode = this.inviteCode.filter((el) => {
+          if (classArray.indexOf(el.cid) != -1) {
+            noClassArray.splice(noClassArray.indexOf(el.cid), 1);
+            return el;
+          }
+        });
+        for (var i = 0; i < noClassArray.length; i++) {
+          await this.getInviteCode(noClassArray[i]);
+        }
+        let a = this.inviteCode;
+        console.log(this.inviteCode);
+        this.addInviteCode();
+      }
+    }
   },
   created() {
     // if(this.tType == 1 || this.tType == 4){
@@ -2449,7 +2624,7 @@ export default {
 
 .returnIndexImg > img {
   width: 100%;
-	
+
 }
 
 .wheel {

+ 473 - 0
src/components/dialog/addClassDialog.vue

@@ -0,0 +1,473 @@
+<template>
+  <div>
+    <el-dialog
+      title="选择班级"
+      :visible.sync="show"
+      :append-to-body="true"
+      width="800px"
+      height="80%"
+      class="addNewPP2"
+    >
+      <div class="check_classBox" v-loading="isLoading">
+        <div class="check_class_right">
+          <span>年级</span>
+          <div
+            class="check_class"
+            :class="{ activeX: gradeId == '' }"
+            @click="(gradeId = ''), getClass()"
+          >
+            全部年级
+          </div>
+          <el-tooltip
+            placement="top"
+            :content="item.name"
+            v-for="(item, index) in gradeList"
+            :key="index"
+          >
+            <div
+              class="check_class"
+              :class="{ activeX: gradeId == item.id }"
+              @click="(gradeId = item.id), getClass()"
+            >
+              {{ item.name }}
+            </div>
+          </el-tooltip>
+        </div>
+        <div class="check_class_left">
+          <div class="check_class_all_box">
+            <div class="check_class_left_title">班级</div>
+            <!-- <div style="display:flex;align-items:center;margin-left:auto;">
+              <el-checkbox
+                v-model="checkAll"
+                @change="handleCheckAllChange"
+                class="all_check"
+                >全选</el-checkbox
+              >
+            </div> -->
+          </div>
+          <!-- <div class="class_item" style="position:absolute; margin:0" v-if="grade2.length">
+            <el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
+          </div> -->
+          <!-- <el-checkbox-group
+            v-model="checkboxList2"
+            class="check_class_item"
+            @change="InviteChange"
+            v-if="grade2.length"
+          >
+            <div v-for="item in grade2" :key="item.id" class="class_item">
+              <el-checkbox :label="item.id">
+                {{ item.name }}
+              </el-checkbox>
+            </div>
+          </el-checkbox-group> -->
+          <div class="classItem" @click="classItemClick(item)" :class="{classActiveItem:checkboxList2.map(i=>i.id).includes(item.id)}" v-for="item in grade2" :key="item.id">
+            <div class="ci_left">
+              <div>{{ item.name }}</div>
+              <span v-if="item.studentNum>=0">{{ item.studentNum }}名学生</span>
+            </div>
+            <div class="ci_right">
+
+              <svg v-show="checkboxList2.map(i=>i.id).includes(item.id)" t="1756864121172" class="icon" viewBox="0 0 1098 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4441" width="200" height="200"><path d="M476.808045 0.000043C213.401753 0.106685-0.031993 213.68973 0 477.074693S213.551052 953.98938 476.94668 954.021373s476.957344-213.412417 477.085315-476.808045A477.010665 477.010665 0 0 0 476.808045 0.000043z m273.761252 353.369671L441.861388 661.853674a43.1901 43.1901 0 0 1-62.023117 0L202.214984 484.251715a43.864079 43.864079 0 1 1 62.033781-62.033782l147.21959 147.21959 277.89897-276.86454a43.861946 43.861946 0 1 1 62.023117 62.033781z m0 0" p-id="4442" fill="#4CAF51"></path></svg>
+            </div>
+          </div>
+          <div v-if="!grade2.length">暂无数据</div>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <div class="b_bottom">
+					<div @click="close()">取消</div>
+          <div class="b_b_submit" @click="submit()">确定</div>
+				</div>
+        <!-- <el-button @click="close()">取 消</el-button>
+        <el-button type="primary" @click="submit()">确定</el-button> -->
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import { myMixin } from "@/mixins/mixin.js";
+  export default {
+    mixins: [myMixin],
+    props: {
+      courseDetail: {
+        type: Object,
+        default: () => {}
+      }
+    },
+    data(){
+      return {
+        show:false,
+        gradeId:"",
+        gradeList:[],
+        checkAll:false,
+        checkboxList2:[],
+        grade2:[],
+        grade:[],
+        oid:this.$route.query.oid,
+        classJuri:[],
+        classSearch:"",
+        isLoading:false,
+      }
+    },
+    methods:{
+      open(data){
+        let _classList = data.classList?JSON.parse(JSON.stringify(data.classList)):[];
+        this.checkboxList2 = _classList;
+        this.getClass();
+        this.selectGrage();
+        this.show = true;
+
+      },
+      close(){
+        this.show = false;
+      },
+      init(){
+        this.gradeId = "";
+        this.classSearch = "";
+      },
+      getClass(){
+        let params = {
+          oid: this.oid,
+          gid: this.gradeId,
+          cn: this.classSearch
+        };
+        this.isLoading = true;
+        this.ajax
+        .get(this.$store.state.api + "selectClassBySchoolSearch2", params)
+        .then(res => {
+          this.isLoading = false;
+          if (!this.grade.length) {
+            this.grade = res.data[0];
+          }
+          this.grade2 = res.data[0];
+          this.classJuri = res.data[0];
+          let _check = [];
+          let _check2 = [];
+          for (var i = 0; i < this.grade2.length; i++) {
+            var gid = this.grade2[i].id;
+            _check.push(gid);
+          }
+          for (var i = 0; i < this.checkboxList2.length; i++) {
+            var _id = this.checkboxList2[i];
+            if (_check.indexOf(_id) !== -1) {
+              _check2.push(_id);
+            }
+          }
+          this.checkAll = _check2.length === _check.length;
+        })
+        .catch(err => {
+          this.isLoading = false;
+          console.error(err);
+        });
+      },
+      selectGrage() {
+      let params = {
+        oid: this.oid
+      };
+      this.ajax
+        .get(this.$store.state.api + "selectGrageBySchool", params)
+        .then(res => {
+          this.gradeList = res.data[0];
+        })
+        .catch(err => {
+          this.isLoading = false;
+          console.error(err);
+        });
+    },
+      submit() {
+        if (
+          this.courseDetail.userid == this.$route.query.userid &&
+          this.checkboxList2.length &&
+          this.$route.query.org == '16ace517-b5c7-4168-a9bb-a9e0035df840' &&
+          this.courseDetail.state == '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);
+      },
+      classItemClick(item){
+        if(this.checkboxList2.map(i=>i.id).includes(item.id)){
+          this.checkboxList2 = this.checkboxList2.filter(i => i.id != item.id);
+        }else{
+          this.checkboxList2.push(item)
+        }
+      }
+    }
+
+  }
+</script>
+
+<style  scoped>
+.addNewPP2 >>> .el-dialog__body {
+  padding: 5px 0;
+}
+
+.addNewPP2 >>> .el-dialog {
+  margin-top: 5vh !important;
+  border-radius: 10px !important;
+}
+
+.check_classBox {
+  height: 400px;
+  display: flex;
+  border-top: 1.5px solid #e7ebf1;
+  border-bottom: 1.5px solid #e7ebf1;
+}
+
+.check_class_right {
+  width: 200px;
+  border-right: 1px solid #e7ebf1;
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  height: 100%;
+  overflow: auto;
+  padding: 15px 0;
+  box-sizing: border-box;
+  padding-top: 40px;
+  position: relative;
+}
+
+.check_class_right>span{
+  font-size: 14px;
+  text-align: left;
+  position: absolute;
+  left: 10px;
+  top: 10px;
+  font-weight: 700;
+}
+
+.check_class {
+  width: 85%;
+  border-radius: 5px;
+  height: 50px;
+  min-height: 30px;
+  padding: 0 20px;
+  box-sizing: border-box;
+  cursor: pointer;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  background: #fff;
+  border: solid 1px #E2E9EE;
+}
+
+.check_class.activeX {
+  background: #E8F5E8;
+  color: #4CAF51;
+  font-weight: 700;
+  border-color: #4CAF51;
+}
+
+.check_class + .check_class {
+  margin-top: 15px;
+}
+
+.check_class_left {
+  background: #fafafa;
+  width: calc(100% - 130px);
+  padding: 15px;
+  box-sizing: border-box;
+  overflow: auto;
+}
+
+.check_class_all_box {
+  display: flex;
+  margin-bottom: 10px;
+}
+
+.all_check {
+  display: flex;
+  align-items: center;
+  padding: 2px 0 0;
+  margin-left: 10px;
+}
+
+.all_check >>> .el-checkbox__label {
+  line-height: 18px;
+}
+
+.check_class_left_title {
+  font-size: 14px;
+  font-weight: 700;
+}
+
+.check_class_item {
+  display: flex;
+  flex-wrap: wrap;
+  height: calc(100% - 45px);
+  overflow: auto;
+  justify-content: flex-start;
+  align-items: flex-start;
+  align-content: flex-start;
+}
+
+.class_item:first-child {
+  /* margin: 0 15px 15px 67px; */
+}
+.class_item {
+  margin: 0 15px 15px 0;
+}
+
+.class_item:hover >>> .el-checkbox__label {
+  color: #409eff;
+}
+
+.class_item >>> .el-checkbox__label {
+  color: #0e1e33;
+}
+
+.class_item:hover >>> .el-checkbox__inner {
+  border-color: #409eff;
+}
+
+.class_item >>> .el-checkbox,
+.class_item >>> .el-checkbox__input {
+  display: flex;
+  align-items: center;
+}
+
+.classItem{
+  width: 100%;
+  height: 70px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  background: #fff;
+  box-sizing: border-box;
+  border: solid 1px #E1E8ED;
+  border-radius: 10px;
+  margin-bottom: 15px;
+  padding-left: 30px;
+  position: relative;
+}
+
+.classItem::after{
+  content: "";
+  height: 100%;
+  width: 8px;
+  background: #E1E8ED;
+  position: absolute;
+  left: 0;
+  top: 0;
+  border-radius: 10px 0 0 10px;
+  cursor: pointer;
+}
+
+.ci_left{
+  width: calc(100% - 70px);
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.ci_left>div{
+  color: #000;
+  font-size: 16px;
+  margin-bottom: 4px;
+  font-weight: 700;
+}
+
+.ci_left>span{
+  font-size: 14px;
+  color: #8F8F8F;
+}
+
+.ci_right{
+  width: 70px;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+}
+
+.ci_right>svg{
+  width: 20px;
+  height: 20px;
+}
+
+.classActiveItem{
+  border: solid 1px #4CAF51;
+}
+
+.classActiveItem::after{
+  background: #4CAF51;
+}
+
+.b_bottom {
+	width: 100%;
+	height: 40px;
+	display: flex;
+	align-items: center;
+	justify-content: flex-end;
+	box-sizing: border-box;
+	padding: 0 20px;
+}
+
+.b_bottom>div{
+  padding: 10px 25px;
+  background: #fff;
+  color: #000;
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: solid 1px #EEEEEE;
+  margin-left: 15px;
+  cursor: pointer;
+}
+
+.b_bottom>.b_b_submit{
+  background: #1A1A1A;
+  color: #D4D4D4;
+  border-color: #1A1A1A;
+}
+
+</style>

+ 294 - 0
src/components/dialog/selectTeachingClassDialog.vue

@@ -0,0 +1,294 @@
+<template>
+	<div>
+		<el-dialog
+			:center="true"
+			:visible.sync="show"
+			:close-on-click-modal="true"
+			:modal="true"
+			width="auto"
+			height="auto"
+			:append-to-body="true"
+			class="dialog"
+		>
+			<div class="box">
+				<div class="b_head">
+					<span>选择授课班级</span>
+					<svg
+						@click="close()"
+						t="1748587270371"
+						class="icon"
+						viewBox="0 0 1024 1024"
+						version="1.1"
+						xmlns="http://www.w3.org/2000/svg"
+						p-id="5023"
+						width="200"
+						height="200"
+					>
+						<path
+							d="M0 0h1024v1024H0z"
+							fill="#FF0033"
+							fill-opacity="0"
+							p-id="5024"
+						></path>
+						<path
+							d="M240.448 168l2.346667 2.154667 289.92 289.941333 279.253333-279.253333a42.666667 42.666667 0 0 1 62.506667 58.026666l-2.133334 2.346667-279.296 279.210667 279.274667 279.253333a42.666667 42.666667 0 0 1-58.005333 62.528l-2.346667-2.176-279.253333-279.253333-289.92 289.962666a42.666667 42.666667 0 0 1-62.506667-58.005333l2.154667-2.346667 289.941333-289.962666-289.92-289.92a42.666667 42.666667 0 0 1 57.984-62.506667z"
+							fill="#fff"
+							p-id="5025"
+						></path>
+					</svg>
+				</div>
+				<div class="b_main" v-loading="loading">
+          <template v-for="item in classList">
+            <div class="b_m_classItem" :class="{'b_m_classItem_active':selectId == item.id}" :key="item.id" v-if="item.name" @click="selectId == item.id ? selectId = '' : selectId = item.id" >
+            <div>{{ item.name }}</div>
+            <span v-if="item.studentNum>=0">{{ item.studentNum }}名学生</span>
+          </div>
+          </template>
+
+          <div class="b_m_classItem" @click="editClass" v-if="courseDetail.userid == userId">
+              <div>
+                <span>+</span>
+                <svg t="1756867649445" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10274" width="200" height="200"><path d="M417.664 921.6l317.184-824.32h-63.616L353.152 921.6z" fill="#999999" p-id="10275"></path></svg>
+                <span>-</span>
+              </div>
+            <div>添加/修改班级</div>
+          </div>
+
+          <div class="b_m_noClassMsg" v-if="classList.length<=0 && courseDetail.userid != userId">
+            <span>创建人暂未添加班级</span>
+          </div>
+				</div>
+				<div class="b_bottom">
+					<div @click="close()">取消</div>
+          <div class="b_b_submit" @click="submit()">{{selectId ? '确定' : '直接进入'}}</div>
+				</div>
+			</div>
+		</el-dialog>
+    <addClassDialog ref="addClassDialogRef" @success="addClassSuccess" :courseDetail="courseDetail"/>
+	</div>
+</template>
+
+<script>
+import addClassDialog from './addClassDialog.vue';
+export default {
+  props:{
+    courseDetail:{
+      type:Object,
+      default:()=>{return {}}
+    },
+    userId:{
+      type:String,
+      default:""
+    }
+  },
+  components:{
+    addClassDialog
+  },
+	data() {
+		return {
+			loading: false,
+			show: false,
+			data: null,
+      classList:[],
+      selectId:"",
+		};
+	},
+	computed: {},
+	methods: {
+		open(data) {
+			this.data = JSON.parse(JSON.stringify(data));
+      this.classList = this.data.classList;
+			this.loading = false;
+			this.show = true;
+		},
+		close() {
+			this.show = false;
+			this.init();
+		},
+		init() {
+			this.data = null;
+      this.classList = [];
+      this.selectId = "";
+			this.loading = false;
+		},
+    submit(){
+      // console.log(this.selectId)
+      this.$emit("success",this.selectId)
+    },
+    editClass(){
+      this.$refs.addClassDialogRef.open({classList:this.classList});
+    },
+    addClassSuccess(data){
+      this.classList = data;
+      this.$emit("changeClassList",this.classList);
+      this.$refs.addClassDialogRef.close();
+
+    },
+	},
+};
+</script>
+
+<style scoped>
+.dialog >>> .el-dialog {
+	width: 900px !important;
+	border-radius: 8px;
+	padding: 0;
+	background-color: #fff;
+	overflow: hidden;
+}
+
+.dialog >>> .el-dialog__body {
+	width: 900px !important;
+	height: auto;
+	flex-shrink: 0;
+	padding: 0;
+	box-sizing: border-box;
+	overflow: auto;
+}
+
+.dialog >>> .el-dialog__header {
+	display: none !important;
+}
+
+.box {
+	width: 900px;
+	height: auto;
+	background: #fafafa;
+	border-radius: 15px;
+	box-shadow: 0px 6px 30px 5px rgba(0, 0, 0, 0.05),
+		0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 8px 10px -5px rgba(0, 0, 0, 0.08);
+}
+
+.b_head {
+	width: 100%;
+	height: 50px;
+	/* border-radius: 15px 15px 0 0; */
+	background: #1A1A1A;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	box-sizing: border-box;
+	padding: 0 20px;
+  color: #fff;
+}
+
+.b_head > span {
+	font-size: 18px;
+	font-weight: bold;
+	color: #fff;
+}
+
+.b_head > img {
+	width: 20px;
+	height: 20px;
+	cursor: pointer;
+}
+
+.b_head > svg {
+	width: 20px;
+	height: 20px;
+	cursor: pointer;
+}
+
+.b_main {
+	width: 100%;
+	height: 400px;
+	background: #fafafa;
+	padding: 20px 20px 20px 20px;
+	box-sizing: border-box;
+  overflow: auto;
+}
+
+.b_bottom {
+	width: 100%;
+	height: 70px;
+	display: flex;
+	align-items: center;
+	justify-content: flex-end;
+	box-sizing: border-box;
+	padding: 0 20px;
+}
+
+.b_bottom>div{
+  padding: 10px 25px;
+  background: #fff;
+  color: #000;
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: solid 1px #EEEEEE;
+  margin-left: 15px;
+  cursor: pointer;
+  font-size: 16px;
+}
+
+.b_bottom>.b_b_submit{
+  background: #1A1A1A;
+  color: #D4D4D4;
+  border-color: #1A1A1A;
+}
+
+.b_m_classItem{
+  width: 32%;
+  height: 85px;
+  float: left;
+  margin-bottom: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  background: #fff;
+  box-shadow: 0px 6px 30px 5px rgba(0, 0, 0, 0.05),
+		0px 16px 24px 2px rgba(0, 0, 0, 0.04), 0px 8px 10px -5px rgba(0, 0, 0, 0.08);
+  border-radius: 12px;
+  cursor: pointer;
+  transition: .2s;
+}
+
+.b_m_classItem>div{
+  color: #5F5F5F;
+  font-size: 16px;
+  margin: 4px 0;
+  display: flex;
+  flex-wrap: wrap;
+  align-content: center;
+}
+
+.b_m_classItem>div>span{
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 25px;
+  height: 25px;
+  border-radius: 4px;
+  border: solid 1px #B0B0B0;
+}
+
+.b_m_classItem>div>svg{
+  width: 20px;
+  height: 25px;
+  margin: 0 5px;
+}
+
+.b_m_classItem>span{
+  color: #A3A3A3;
+  font-size: 14px;
+}
+
+.b_main > div:nth-child(3n-1) {
+  margin: 0 2%;
+}
+
+.b_m_classItem_active{
+  box-shadow: 4px 4px 4px 0px rgba(138, 238, 138, 0.555);
+}
+
+.b_m_noClassMsg{
+  width:100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+</style>

+ 1 - 1
src/components/easy/studyStudent.vue

@@ -2854,7 +2854,7 @@ export default {
       isAnswer: false,
       timer: null,
       opertimer: null,
-      showType: 0,
+      showType: '',
       fileType: 0,
       showPDF: false,
       noteName: "",

+ 179 - 35
src/components/easy2/studyStudent.vue

@@ -106,7 +106,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>
@@ -506,6 +506,7 @@
                   flex-direction: column;
                   position: relative;
                 "
+                class="renderedFor"
               >
                 <div
                   style="
@@ -559,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>
@@ -725,12 +726,12 @@
                               <span v-if="vitem.text">{{ vitem.text }}-</span
                               >{{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
 
                           <div class="navListItem" v-if="vitem.type == 6">
@@ -790,12 +791,12 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 12">
                             <div class="navText" @click="downloadFile2(vitem)">
@@ -811,12 +812,12 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 13">
                             <div
@@ -826,12 +827,12 @@
                             >
                               {{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 16">
                             <div
@@ -851,6 +852,24 @@
                               />
                             </div>
                           </div>
+                          <div class="navListItem" v-if="vitem.type == 17">
+                            <div
+                              class="navText"
+                              @click="checkHtml(vitem, vindex)"
+                              :class="isClickNav == vindex ? 'isClickNav' : ''"
+                            >
+                              {{ vitem.name }}
+                            </div>
+                            <div
+                              class="downIcon"
+                              @click="checkFileFull1(vitem.type, vitem)"
+                            >
+                              <img
+                                src="../../assets/icon/newIcon/allScreen.png"
+                                alt
+                              />
+                            </div>
+                          </div>
                         </div>
                         <div
                           class="fileC_box"
@@ -867,7 +886,7 @@
                                 <span v-if="vitem.text">{{ vitem.text }}-</span
                                 >{{ vitem.name }}
                               </div>
-                              <div
+                              <!-- <div
                                 class="downIcon"
                                 @click="downloadFile2(vitem)"
                               >
@@ -875,7 +894,7 @@
                                   src="../../assets/icon/newIcon/down.png"
                                   alt
                                 />
-                              </div>
+                              </div> -->
                             </div>
                           </div>
                         </div>
@@ -1567,7 +1586,7 @@
                       </div>
                     </div>
                     <div
-                      class="tooldetail"
+                      class="tooldetail renderedFor"
                       v-if="tool.toolDetail != ''"
                       :class="{
                         isUpdateToolDetailClass: toolDetailIndex == toolIndex
@@ -5177,7 +5196,7 @@
                       <div
                         v-for="(s, sIndex) in noWorksS[toolIndex]"
                         :key="sIndex"
-                        class="noWorksName"
+                        class="noWorksName2"
                         @click="teacherWorkSubmit(72, toolIndex, taskCount, s)"
                       >
                         <el-tooltip
@@ -6205,6 +6224,7 @@
                               word-break: break-word;
                               cursor: pointer;
                             "
+                            class="renderedFor"
                           >
                             {{ index + 1 + "、"  }} <span v-html="renderedFormula(item.teststitle)"></span>
                           </div>
@@ -13025,21 +13045,21 @@
             :key="index1"
           >
             <div class="a_add_head">
-              <div style="display: flex;align-items: center;">
+              <div style="display: flex;">
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
-                <div>题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
+                <div class="renderedFor">题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
               </div>
               <img
                 v-if="testJson.testJson[index1].img"
@@ -13487,7 +13507,9 @@
               @change="updateLookOpen"
             ></el-switch>
           </div>
-          <div class="switch_box" v-if="courseDetail.userid == userid">
+          <div class="switch_box" v-if="(courseDetail.userid == userid ||
+                (courseDetail.course_teacher &&
+                  courseDetail.course_teacher.indexOf(userid) != -1)) && !splitScreenData.isOpen">
             <span>开启跟随模式</span>
             <el-switch
               v-model="IsFollow"
@@ -16383,6 +16405,7 @@ export default {
   },
   data() {
     return {
+      startTime: "",
       // 是否允许学生查看内容资料 2不可以 1可以
       IsStulook:false,
       homeWorkLoading:false,
@@ -16671,7 +16694,7 @@ export default {
       timer: null,
       timer2: null,
       opertimer: null,
-      showType: 0,
+      showType: '',
       fileType: 0,
       showPDF: false,
       noteName: "",
@@ -16799,7 +16822,14 @@ export default {
       },
       confirmOpenDig:false,
       confirmOpenDigData:'',
-      diffKey:"1"
+      diffKey:"1",
+      getCourseGroupLoading: false,
+      selectSWorksLoading:false,
+      selectStudentLoading:false,
+      selectSLookLoading:false,
+      getPickLoading:false,
+      selectPzLoading:false,
+      getSplitScreenDataLoading:false,
     };
   },
   watch:{
@@ -16821,11 +16851,11 @@ export default {
     },
     worksStudent: {
       handler(newVal, oldVal) {
-          const sum1 = newVal.reduce((total, subArr) => total + subArr.length, 0);
-          const sum2 = oldVal.reduce((total, subArr) => total + subArr.length, 0);
+          // const sum1 = newVal.reduce((total, subArr) => total + subArr.length, 0);
+          // const sum2 = oldVal.reduce((total, subArr) => total + subArr.length, 0);
           // console.log('worksStudent',sum1,sum2);
           
-          if(sum1 != sum2){
+          if(JSON.stringify(newVal) !=  JSON.stringify(oldVal)){
               this.AIloading = [];
               this.loopLoading = [];
 
@@ -17776,6 +17806,8 @@ export default {
         }
       }
 
+      console.log('6666');
+
       this.navList[i].task[j].tool[k].isTool = !this.navList[i].task[j].tool[k]
         .isTool;
       var a = document.scrollingElement;
@@ -17837,6 +17869,12 @@ export default {
           );
         }
       }
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) &&
+          this.IsFollow) {
+        this.setCTask();
+      }
     },
     addTools2(i) {
       if (i == 4) {
@@ -18991,6 +19029,8 @@ export default {
         });
     },
     selectStudent() {
+      if (this.selectStudentLoading) return
+      this.selectStudentLoading = true
       //学生查看自己作业
       let params = {
         uid: this.userid,
@@ -19312,8 +19352,12 @@ export default {
               }
             }
           }
+          this.selectStudentLoading = false
+          
         })
         .catch(err => {
+          this.selectStudentLoading = false
+
           console.error(err);
         });
     },
@@ -19752,6 +19796,8 @@ export default {
       return lang;
     },
     selectSWorks(gindex) {
+      if (this.selectSWorksLoading) return
+      this.selectSWorksLoading = true
       //教师查看全部作业
       let params = {
         cid: this.id,
@@ -20870,8 +20916,12 @@ export default {
               }, 0);
             });
           }
+          this.selectSWorksLoading = false
+
         })
         .catch(err => {
+          this.selectSWorksLoading = false
+
           console.error(err);
         });
     },
@@ -21630,7 +21680,10 @@ export default {
       this.getHomeWork();
       this.getCourseDetail(2);
       this.$forceUpdate();
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) &&
+          this.IsFollow) {
         this.setCTask();
       }
     },
@@ -21761,7 +21814,9 @@ export default {
           }</span>`
         );
       }
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
     },
@@ -21887,8 +21942,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then(res => {
-          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
-
+          if ((this.courseDetail.userid == this.userid ||
+              (this.courseDetail.course_teacher && 
+              this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
+            this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+          }
           if (type != 2) {
             loading.close();
             if (
@@ -22087,6 +22145,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;
                 }
               }
             }
@@ -22256,6 +22317,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;
                 }
               }
             }
@@ -22365,7 +22429,7 @@ export default {
             if (this.courseDetail.userid == this.userid) {
             
               // 开局关闭学生查看内容
-              this.StulookMode(false)
+              this.StulookMode(true)
               // 开局打开跟随模式
               this.followingMode(true)
             }
@@ -22456,6 +22520,8 @@ export default {
         });
     },
     getCourseGroup(gindex) {
+      if(this.getCourseGroupLoading) return
+      this.getCourseGroupLoading = true
       let params = {
         cid: this.id,
         classid: this.tcid ? this.tcid : "1"
@@ -22505,8 +22571,10 @@ export default {
             this.selectSWorks(gindex);
             this.isGroup = false;
           }
+          this.getCourseGroupLoading = false
         })
         .catch(err => {
+          this.getCourseGroupLoading = false
           // this.$message.error("网络不佳");
           console.error(err);
         });
@@ -22678,6 +22746,8 @@ export default {
       this.selectPz();
     },
     selectPz() {
+      if(this.selectPzLoading) return
+      this.selectPzLoading = true
       let params = {
         cid: this.id,
         s: this.courseType,
@@ -22700,8 +22770,12 @@ export default {
               }
             }
           }
+          this.selectPzLoading = false
+
         })
         .catch(err => {
+          this.selectPzLoading = false
+
           console.error(err);
         });
     },
@@ -22855,6 +22929,8 @@ export default {
         });
     },
     selectSLook() {
+      if(this.selectSLookLoading) return
+      this.selectSLookLoading = true
       let params = {
         cid: this.id
       };
@@ -22888,8 +22964,12 @@ export default {
               this.getCourseDetail(2);
             }
           }
+          this.selectSLookLoading = false
+
         })
         .catch(err => {
+          this.selectSLookLoading = false
+
           console.error(err);
         });
     },
@@ -23193,6 +23273,8 @@ export default {
       );
     },
     checkHtml(f, i){
+      console.log('checkHtml',f, i);
+      
       this.showType = 16;
       this.pptImgUrl1 = f.url;
       this.isClickNav = i;
@@ -24233,6 +24315,9 @@ export default {
       );
     },
     teacherWorkSubmit(t, i, index, s) {
+      console.log('t',t);
+      if(t == 72) return
+      
       this.sStudent = s;
       this.toolindex = i;
       this.sTool = t;
@@ -25735,6 +25820,8 @@ export default {
         });
     },
     getPick() {
+      if(this.getPickLoading) return
+      this.getPickLoading = true
       let params = {
         cid: this.id
       };
@@ -25772,8 +25859,10 @@ export default {
               })
               .catch(() => {});
           }
+          this.getPickLoading = false
         })
         .catch(err => {
+          this.getPickLoading = false
           this.$message.error("网络不佳");
           console.error(err);
         });
@@ -25970,6 +26059,8 @@ export default {
     getSplitScreenData() {
       // return;
       // if (this.tType != 1) return;
+      if(this.getSplitScreenDataLoading) return
+      this.getSplitScreenDataLoading = true
       let params = {
         cid: this.id
       };
@@ -26037,8 +26128,12 @@ export default {
                 .catch(() => {});
             }
           }
+          this.getSplitScreenDataLoading = false
+          
         })
         .catch(e => {
+          this.getSplitScreenDataLoading = false
+
           console.log("获取分屏数出错:", e);
         });
     },
@@ -26308,6 +26403,22 @@ export default {
     clearInterval(this.opertimer);
     this.opertimer = null;
     this.updateSplitScreenData(1);
+    if(this.courseDetail.userid == this.userid && 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 ? this.tcid2 : '',
+        courseTime: courseTime,
+        startTime: this.startTime,
+        endTime: endTime,
+      })
+      console.log('同步数据')
+    }
   },
   computed: {
     renderedFormula2() {
@@ -26519,7 +26630,10 @@ export default {
     
   },
   mounted() {
-
+    this.startTime = new Date().toLocaleString("zh-CN", { 
+      hour12: false, 
+      timeZone: "Asia/Shanghai" 
+    }).replace(/\//g, "-")
     this.updateSplitScreenData(2);
     this.splitScreenData.myUid = uuidv4();
     document.body.addEventListener("click", e => {
@@ -28361,6 +28475,31 @@ export default {
   white-space: nowrap;
 }
 
+.noWorksName2 {
+  background: #fff;
+  color: #0061ff;
+  width: 90px;
+  height: 25px;
+  text-align: center;
+  line-height: 25px;
+  border-radius: 4px;
+  margin: 10px 15px 10px 0;
+  white-space: nowrap;
+  overflow: hidden;
+  padding: 5px;
+  text-overflow: ellipsis;
+  cursor: pointer;
+  border: 1px solid #0061ff;
+}
+
+.noWorksName2 > span {
+  max-width: 100%;
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
 .isWorksName2 {
   width: 100px;
   height: 40px;
@@ -31081,18 +31220,23 @@ div::-webkit-scrollbar {
   overflow: hidden;
   text-overflow: ellipsis;
 }
-.pb_content >>> .katex {
-  font-size: 16px;
+
+.renderedFor >>> .katex {
+  font-size: 18px;
   width: 100%;
   white-space: normal;
+  font-family: '黑体' !important;
 }
-.pb_content >>> .katex .base{
+.renderedFor >>> .katex .base{
   display: inline !important;
   display: contents !important;
 }
 
-.pb_content >>> .katex .base .cjk_fallback{
+.renderedFor>>> .katex .base .cjk_fallback{
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 207 - 41
src/components/easy3/studyStudent.vue

@@ -103,7 +103,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>
@@ -227,6 +227,7 @@
                       <div v-if="t.tool == 62">交互视频</div>
                       <div v-if="t.tool == 71">AI智能体</div>
                       <div v-if="t.tool == 72">应用中心</div>
+                      <div v-if="t.tool == 73">PPT</div>
                     </div>
                   </div>
                 </div>
@@ -521,6 +522,7 @@
                   flex-direction: column;
                   position: relative;
                 "
+                class="renderedFor"
               >
                 <div
                   style="
@@ -568,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>
@@ -730,12 +732,12 @@
                               <span v-if="vitem.text">{{ vitem.text }}-</span
                               >{{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 6">
                             <div
@@ -794,12 +796,12 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 12">
                             <div class="navText" @click="downloadFile2(vitem)">
@@ -815,12 +817,12 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 13">
                             <div
@@ -830,12 +832,12 @@
                             >
                               {{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 16">
                             <div
@@ -855,6 +857,24 @@
                               />
                             </div>
                           </div>
+                          <div class="navListItem" v-if="vitem.type == 17">
+                            <div
+                              class="navText"
+                              @click="checkHtml(vitem, vindex)"
+                              :class="isClickNav == vindex ? 'isClickNav' : ''"
+                            >
+                              {{ vitem.name }}
+                            </div>
+                            <div
+                              class="downIcon"
+                              @click="checkFileFull1(vitem.type, vitem)"
+                            >
+                              <img
+                                src="../../assets/icon/newIcon/allScreen.png"
+                                alt
+                              />
+                            </div>
+                          </div>
                         </div>
                         <div class="fileC_box" v-if="fileC[0].length > 0">
                           <div class="fileC_title">以下文件不支持预览</div>
@@ -868,7 +888,7 @@
                                 <span v-if="vitem.text">{{ vitem.text }}-</span
                                 >{{ vitem.name }}
                               </div>
-                              <div
+                              <!-- <div
                                 class="downIcon"
                                 @click="downloadFile2(vitem)"
                               >
@@ -876,7 +896,7 @@
                                   src="../../assets/icon/newIcon/down.png"
                                   alt
                                 />
-                              </div>
+                              </div> -->
                             </div>
                           </div>
                         </div>
@@ -1480,6 +1500,14 @@
                               分析
                             </div>
                           </div>
+                          <div v-if="tooC == 73">
+                            <img
+                              src="../../assets/icon/secondToolList/ppt.png"
+                              alt
+                              @click="openChoseWorksDetailDialog(tooC,toolIndex,taskCount,73)"
+                            />
+                            <div style="margin: 5px 0">PPT</div>
+                          </div>
                           <div v-if="tooC == 65">
                             <img
                               @click="addTools(tooC, toolIndex, taskCount)"
@@ -1547,7 +1575,7 @@
                         </div>
                       </div>
                     </div>
-                    <div class="tooldetail" v-if="tool.toolDetail != ''" :class="{isUpdateToolDetailClass:toolDetailIndex == toolIndex}">
+                    <div class="tooldetail renderedFor" v-if="tool.toolDetail != ''" :class="{isUpdateToolDetailClass:toolDetailIndex == toolIndex}">
                       <!-- <div class="toolTitle">工具描述</div> -->
                       <!-- @click.stop="updateToolDetail(toolIndex, 2)" 点击开启修改-->
                       <div style="height:100%;"
@@ -3888,7 +3916,7 @@
                       <div
                         v-for="(s, sIndex) in noWorksS[toolIndex]"
                         :key="sIndex"
-                        class="noWorksName"
+                        class="noWorksName2"
                         @click="teacherWorkSubmit(72, toolIndex, taskCount, s)"
                       >
                         <el-tooltip
@@ -4464,6 +4492,7 @@
                               word-break: break-word;
                               cursor: pointer;
                             "
+                            class="renderedFor"
                           >
                             {{ index + 1 + "、"  }} <span v-html="renderedFormula(item.teststitle)"></span>
                           </div>
@@ -9657,21 +9686,21 @@
             :key="index1"
           >
             <div class="a_add_head">
-              <div style="display: flex;align-items: center;">
+              <div style="display: flex;">
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
-                <div>题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
+                <div class="renderedFor">题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
               </div>
               <img
                 v-if="testJson.testJson[index1].img"
@@ -9790,13 +9819,13 @@
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
@@ -10119,7 +10148,9 @@
               @change="updateLookOpen"
             ></el-switch>
           </div>
-          <div class="switch_box" v-if="courseDetail.userid == userid">
+          <div class="switch_box" v-if="(courseDetail.userid == userid ||
+              (courseDetail.course_teacher &&
+                courseDetail.course_teacher.indexOf(userid) != -1)) && !splitScreenData.isOpen">
             <span>开启跟随模式</span>
             <el-switch
               v-model="IsFollow"
@@ -10595,7 +10626,7 @@
           sandbox="allow-top-navigation allow-same-origin allow-forms allow-scripts allow-popups"
           :src="fullUrl"
         ></iframe>
-       
+
       </div>
       <!-- <div slot="footer">
         <el-button @click="fullDialogVisible = false">关 闭</el-button>
@@ -12727,6 +12758,7 @@ export default {
   },
   data() {
     return {
+      startTime: "",
       // 是否允许学生查看内容资料 2不可以 1可以
       IsStulook:false,
       homeWorkLoading:false,
@@ -13109,7 +13141,14 @@ export default {
       },
       confirmOpenDig:false,
       confirmOpenDigData:'',
-      diffKey:"1"
+      diffKey:"1",
+      getCourseGroupLoading: false,
+      selectSWorksLoading:false,
+      selectStudentLoading:false,
+      selectSLookLoading:false,
+      getPickLoading:false,
+      selectPzLoading:false,
+      getSplitScreenDataLoading:false,
     };
   },
   methods: {
@@ -13448,7 +13487,12 @@ export default {
 					this.insertMemorandum(`选择<span class="variable">阶段${i+1}${this.navList[i].dyName?':'+this.navList[i].dyName:''}</span>→<span class="variable">任务${j+1}${this.navList[i].task[j].taskName?':'+this.navList[i].task[j].taskName:''}</span>→<span class="variable">工具${k+1}:${this.toolsList[this.navList[i].task[j].tool[k].tool]}</span>`)
 				}
       }
-
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) &&
+          this.IsFollow) {
+        this.setCTask();
+      }
       // var b = this.$refs["bz" + k][0];
       // a.scrollTop = b.offsetTop;
     },
@@ -14579,6 +14623,8 @@ export default {
         });
     },
     selectStudent() {
+      if(this.selectStudentLoading) return
+      this.selectStudentLoading = true
       //学生查看自己作业
       let params = {
         uid: this.userid,
@@ -14901,8 +14947,12 @@ export default {
               }
             }
           }
+          this.selectStudentLoading = false
+
         })
         .catch((err) => {
+          this.selectStudentLoading = false
+
           console.error(err);
         });
     },
@@ -15258,6 +15308,8 @@ export default {
         .catch(() => {});
     },
     selectSWorks(gindex) {
+      if(this.selectSWorksLoading) return
+      this.selectSWorksLoading = true
       //教师查看全部作业
       let params = {
         cid: this.id,
@@ -16357,8 +16409,12 @@ export default {
               }, 0)
             })
           }
+          this.selectSWorksLoading = false
+          
         })
         .catch((err) => {
+          this.selectSWorksLoading = false
+
           console.error(err);
         });
     },
@@ -17112,7 +17168,9 @@ export default {
       this.getHomeWork();
       this.getCourseDetail(2);
       this.$forceUpdate();
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
     },
@@ -17224,7 +17282,9 @@ export default {
       this.selectPz();
       this.getHomeWork();
       this.getCourseDetail(2);
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
 			if(flag){
@@ -17355,7 +17415,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then((res) => {
-          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+          if ((this.courseDetail.userid == this.userid ||
+              (this.courseDetail.course_teacher && 
+              this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
+            this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+          }
           if (type != 2) {
             loading.close();
             if (
@@ -17553,6 +17617,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;
                 }
               }
             }
@@ -17723,6 +17790,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;
                 }
               }
             }
@@ -17758,11 +17828,11 @@ export default {
             console.log('this.courseDetail.userid',this.courseDetail.userid);
             console.log('this.userid',this.userid);
 
-            
+
             if (this.courseDetail.userid == this.userid) {
-            
+
               // 开局关闭学生查看内容
-              this.StulookMode(false)
+              this.StulookMode(true)
               // 开局打开跟随模式
               this.followingMode(true)
             }
@@ -17853,6 +17923,8 @@ export default {
         });
     },
     getCourseGroup(gindex) {
+      if(this.getCourseGroupLoading) return
+      this.getCourseGroupLoading = true
       let params = {
         cid: this.id,
         classid: this.tcid ? this.tcid : "1",
@@ -17902,8 +17974,12 @@ export default {
             this.selectSWorks(gindex);
             this.isGroup = false;
           }
+          this.getCourseGroupLoading = false
+
         })
         .catch((err) => {
+          this.getCourseGroupLoading = false
+
           // this.$message.error("网络不佳");
           console.error(err);
         });
@@ -18073,6 +18149,8 @@ export default {
       this.selectPz();
     },
     selectPz() {
+      if(this.selectPzLoading) return
+      this.selectPzLoading = true
       let params = {
         cid: this.id,
         s: this.courseType,
@@ -18095,8 +18173,12 @@ export default {
               }
             }
           }
+          this.selectPzLoading = false
+
         })
         .catch((err) => {
+          this.selectPzLoading = false
+
           console.error(err);
         });
     },
@@ -18160,7 +18242,7 @@ export default {
       this.ajax
         .post(this.$store.state.api + "updateCourseStulook", params)
         .then(res => {
-          
+
           if (this.IsStulook == true) {
             this.$message({
               message: "学生查看内容资料权限已开启",
@@ -18250,6 +18332,8 @@ export default {
         });
     },
     selectSLook() {
+      if(this.selectSLookLoading) return
+      this.selectSLookLoading = true
       let params = {
         cid: this.id,
       };
@@ -18282,8 +18366,12 @@ export default {
               this.getCourseDetail(2);
             }
           }
+          this.selectSLookLoading = false
+
         })
         .catch((err) => {
+          this.selectSLookLoading = false
+
           console.error(err);
         });
     },
@@ -19599,6 +19687,8 @@ export default {
 			this.insertMemorandum(`点击工作区<span class="variable">工具${index+1}:${this.toolsList[t]}</span>`)
     },
     teacherWorkSubmit(t, i, index, s) {
+      console.log('t',t);
+      if(t == 72) return
       this.sStudent = s;
       this.toolindex = i;
       this.sTool = t;
@@ -19977,9 +20067,9 @@ export default {
       if (t == 6) {
         this.fulltype = 1;
         console.log('checkFileFull1',f);
-        
+
         this.fullUrl = JSON.parse(JSON.stringify(f));
-        
+
       } else if (t == 8) {
         this.fulltype = 2;
         this.fullUrl = f.url;
@@ -21072,6 +21162,9 @@ export default {
         });
     },
     getPick() {
+      if(this.getPickLoading) return
+      this.getPickLoading = true
+
       let params = {
         cid: this.id,
       };
@@ -21109,8 +21202,12 @@ export default {
               })
               .catch(() => {});
           }
+          this.getPickLoading = false
+
         })
         .catch((err) => {
+          this.getPickLoading = false
+
           this.$message.error("网络不佳");
           console.error(err);
         });
@@ -21297,6 +21394,8 @@ export default {
     getSplitScreenData() {
       // return;
       // if (this.tType != 1) return;
+      if(this.getSplitScreenDataLoading) return
+      this.getSplitScreenDataLoading = true
       let params = {
         cid: this.id
       };
@@ -21363,8 +21462,12 @@ export default {
                 .catch(() => {});
             }
           }
+          this.getSplitScreenDataLoading = false
+
         })
         .catch(e => {
+          this.getSplitScreenDataLoading = false
+
           console.log("获取分屏数出错:", e);
         });
     },
@@ -21616,6 +21719,22 @@ export default {
     clearInterval(this.opertimer);
     this.opertimer = null;
 		this.updateSplitScreenData(1);
+    if(this.courseDetail.userid == this.userid && 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 ? this.tcid2 : '',
+        courseTime: courseTime,
+        startTime: this.startTime,
+        endTime: endTime,
+      })
+      console.log('同步数据')
+    }
   },
   computed: {
     renderedFormula2() {
@@ -21624,7 +21743,7 @@ export default {
         const normalized = val
           .replace(/&amp;/g, '&')
           .replace(/<br\/?>/g, '\n');
-        
+
         // 匹配行内公式($...$)和块级公式($$...$$)
         return normalized.replace(/(\${1,2})([^$]+)(\${1,2})/g, (_, delim, expr) => {
           try {
@@ -21822,12 +21941,16 @@ export default {
 
   },
   mounted() {
-    if (this.tType == 1) {
-       // 开局关闭学生查看内容
-      this.StulookMode(false)
-      // 开局打开跟随模式
-      this.followingMode(true)
-    }
+    this.startTime = new Date().toLocaleString("zh-CN", { 
+      hour12: false, 
+      timeZone: "Asia/Shanghai" 
+    }).replace(/\//g, "-")
+    // if (this.tType == 1) {
+    //    // 开局关闭学生查看内容
+    //   this.StulookMode(false)
+    //   // 开局打开跟随模式
+    //   this.followingMode(true)
+    // }
     document.body.addEventListener("click", (e) => {
       if (this.isUpdateToolDetail1) {
         this.updateToolDetail(this.toolDetailIndex);
@@ -23638,6 +23761,30 @@ export default {
   text-overflow: ellipsis;
   white-space: nowrap;
 }
+.noWorksName2 {
+  background: #fff;
+  color: #0061ff;
+  width: 90px;
+  height: 25px;
+  text-align: center;
+  line-height: 25px;
+  border-radius: 4px;
+  margin: 10px 15px 10px 0;
+  white-space: nowrap;
+  overflow: hidden;
+  padding: 5px;
+  text-overflow: ellipsis;
+  cursor: pointer;
+  border: 1px solid #0061ff;
+}
+
+.noWorksName2 > span {
+  max-width: 100%;
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
 
 .isWorksName2 {
   width: 100px;
@@ -26328,4 +26475,23 @@ div::-webkit-scrollbar {
   overflow: hidden;
   text-overflow: ellipsis;
 }
+.renderedFor >>> .katex {
+  font-size: 18px;
+  width: 100%;
+  white-space: normal;
+  font-family: '黑体' !important;
+}
+
+.renderedFor >>> .katex .base{
+  display: inline !important;
+  display: contents !important;
+}
+
+.renderedFor >>> .katex .base .cjk_fallback{
+    white-space: normal !important;
+    display: inline !important;
+}
+.notop >>> .vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 188 - 69
src/components/index.vue

@@ -1,10 +1,12 @@
 <template>
   <div class="pb_content">
-    <div class="pb_content_body">
-      <div class="student_head" style="position: relative;">
-        <div v-if="gotype" 
-        class="backBtn"
-        @click.stop="backliyuan">返回</div>
+    <div class="pb_content_body" :style="{marginTop : gotype ? '75px' : 0}">
+      <div v-if="gotype" class="r_pub_button_retrun" @click.stop="backliyuan">
+        <img src="../assets/icon/course/backPage.svg" alt="">
+        AI通识课
+      </div>
+      <div class="student_head" v-else>
+
         <!-- <img src="../assets/banner.png" alt="" /> -->
          <!-- //pbl.cocorobo.cn/pbl-teacher-table/dist -->
         <el-carousel trigger="click" style="width: 100%; height: 100%">
@@ -67,28 +69,27 @@
         <div class="typeCheck">
           <div><el-switch v-model="orderBy"></el-switch><span>按名字排序</span></div>
           <div><el-switch v-model="typeCheck"></el-switch><span>分类显示</span></div>
+          <div v-if="oidArray.indexOf(oid) !== -1"><el-switch v-model="typeCheck2"></el-switch><span>按年级显示</span></div>
         </div>
         <div>
-          <div class="main_box">
-            <div style="display:flex;flex-wrap:wrap" v-if="!typeCheck">
-              <div class="box_course" v-for="(item, index) in zoneClass" :key="index"  @click="
-                  goTo(
-                    '/courseDetail?courseId=' +
-                    item.courseId +
-                    '&userid=' +
-                    userid +
-                    '&oid=' +
-                    oid +
-                    '&org=' +
-                    org +
-                    '&cid=' +
-                    classId +
-                    '&tType=' +
-                    tType +
-                    '&screenType=' +
-                    screenType,item.courseId
-                  )
-                ">
+           <div class="main_box">
+            <div :class="zoneClass.length > 5 ? 'claList' : 'claListFlex'" v-if="!typeCheck && !typeCheck2">
+              <div :class="zoneClass.length > 5 ? 'box_course' : 'box_courseFlex'" v-for="(item, index) in zoneClass" :key="index"  @click="goTo(
+          '/courseDetail?courseId=' +
+          item.courseId +
+          '&userid=' +
+          userid +
+          '&oid=' +
+          oid +
+          '&org=' +
+          org +
+          '&cid=' +
+          classId +
+          '&tType=' +
+          tType +
+          '&screenType=' +
+          screenType,item.courseId
+        )">
                 <div class="wheel">
                   <img :src="
                     item.cover
@@ -101,7 +102,7 @@
                     <el-tooltip effect="light" :content="item.title" placement="top">
                       <span class="utitle">{{ item.title }}</span>
                     </el-tooltip>
-                    <el-tooltip effect="light" :content="item.uname" placement="top">
+                    <el-tooltip effect="light" :content="item.uname" placement="top" v-if="oidArray.indexOf(oid) == -1">
                       <span class="uname">{{ item.uname }}</span>
                     </el-tooltip>
                   </div>
@@ -146,25 +147,23 @@
             <div v-else>
               <div class="FirstTypeBox" v-for="(type, tindex) in CourseType2" :key="tindex">
                 <div class="title">{{ type.name }}</div>
-                <div style="display: flex;flex-flow: wrap;margin-top: 20px;">
-                  <div class="box_course" v-for="(item, index) in type.course" :key="tindex + '-' + index" @click="
-                     goTo(
-                        '/courseDetail?courseId=' +
-                        item.courseId +
-                        '&userid=' +
-                        userid +
-                        '&oid=' +
-                        oid +
-                        '&org=' +
-                        org +
-                        '&cid=' +
-                        classId +
-                        '&tType=' +
-                        tType +
-                        '&screenType=' +
-                        screenType,item.courseId
-                      )
-                    ">
+                <div class="typeCheckFlex" style="margin-top: 20px;">
+                  <div class="box_courseFlex" v-for="(item, index) in type.course" :key="tindex + '-' + index" @click="goTo(
+          '/courseDetail?courseId=' +
+          item.courseId +
+          '&userid=' +
+          userid +
+          '&oid=' +
+          oid +
+          '&org=' +
+          org +
+          '&cid=' +
+          classId +
+          '&tType=' +
+          tType +
+          '&screenType=' +
+          screenType,item.courseId
+        )">
                     <div class="wheel">
                       <img :src="
                         item.cover
@@ -177,7 +176,7 @@
                         <el-tooltip effect="light" :content="item.title" placement="top">
                           <span class="utitle">{{ item.title }}</span>
                         </el-tooltip>
-                        <el-tooltip effect="light" :content="item.uname" placement="top">
+                        <el-tooltip effect="light" :content="item.uname" placement="top" v-if="oidArray.indexOf(oid) == -1">
                           <span class="uname">{{ item.uname }}</span>
                         </el-tooltip>
                       </div>
@@ -226,7 +225,7 @@
             </div>
           </div>
         </div>
-        <div class="student_page" style="margin: 15px 0 0" v-if="zoneClass.length > 0 && !typeCheck">
+        <div class="student_page" style="margin: 15px 0 0" v-if="zoneClass.length > 0 && !typeCheck && !typeCheck2">
           <el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="total" v-if="page"
             @current-change="handleCurrentChange">
           </el-pagination>
@@ -244,7 +243,7 @@ export default {
 
   data() {
     return {
-      gotype:sessionStorage.getItem('gotype'),
+      gotype: sessionStorage.getItem('gotype'),
       zoneList: [],
       zoneClass: [],
       page: 1,
@@ -272,25 +271,59 @@ export default {
       typeE: [],
       loading: "",
       typeCheck: false,
+      typeCheck2: false,
+      isUpdatingChecks: false,
       orderBy: false,
       CourseType3: [],
       pTypeCheck:[],
       pTypeCheckName: [],
+      oidArray: ['91305d49-01ba-11ed-8c78-005056b86db4']
     };
   },
   watch: {
     typeCheck(newValue, oldValue) {
-      this.loading = true
+      if (this.isUpdatingChecks) return;
+      
+      this.isUpdatingChecks = true;
+      this.typeCheck2 = false;
+      
       if (newValue) {
-        this.selectAll()
+        this.loading = true;
+        this.selectAll();
+      } else if (!this.typeCheck2) {
+        this.loading = true;
+        this.page = 1;
+        this.selectAll2();
+      }
+      
+      this.$nextTick(() => {
+        this.isUpdatingChecks = false;
+      });
+    },
+    typeCheck2(newValue, oldValue) {
+      if (this.isUpdatingChecks) return;
+      
+      this.isUpdatingChecks = true;
+      this.typeCheck = false;
+      
+      if (newValue) {
+        this.loading = true;
+        this.selectAll();
+      } else if (!this.typeCheck) {
+        this.page = 1;
+        this.loading = true;
+        this.selectAll2();
       } else {
-        this.page = 1
-        this.selectAll2()
+        this.loading = false;
       }
+      
+      this.$nextTick(() => {
+        this.isUpdatingChecks = false;
+      });
     },
     orderBy(newValue, oldValue) {
       this.loading = true
-      if (this.typeCheck) {
+      if (this.typeCheck || this.typeCheck2) {
         this.selectAll()
       } else {
         this.page = 1
@@ -306,9 +339,15 @@ export default {
       }else{
         window.location.href = `https://pbl.cocorobo.cn/pbl-teacher-table/dist/#/CourseCon?userid=${this.userid}&oid=${this.oid}&org=${this.org}&role=${this.role}&tType=${this.tType}`
       }
+      try {
+        window.topU.gotype = '' 
+      } catch (error) {
+        console.log(error);
+      }
+      sessionStorage.removeItem('gotype');
     },
     search(){
-      if(this.typeCheck){
+      if(this.typeCheck || this.typeCheck2){
         this.selectAll()
       }else{
         this.page = 1
@@ -509,9 +548,9 @@ export default {
         }
       }
       this.loading = true;
-      if (this.typeCheck) {
+      if (this.typeCheck || this.typeCheck2) {
         this.selectAll();
-      } else {
+      }else {
         this.selectAll2();
       }
     },
@@ -530,14 +569,14 @@ export default {
           }
         }
       }
-      
+
       this.typea = ""
       this.typeb = ""
       this.typed = ""
       this.loading = true;
-      if (this.typeCheck) {
+      if (this.typeCheck || this.typeCheck2) {
         this.selectAll();
-      } else {
+      }else {
         this.selectAll2();
       }
     },
@@ -583,7 +622,16 @@ export default {
           this.isListAjax = false;
           this.zoneClass = res.data[0];
           // this.total = res.data[0].length ? res.data[0][0].num : 0;
-          let CourseType2 = JSON.parse(JSON.stringify(this.CourseType[0]))
+          let CourseType2 = []
+          if(this.typeCheck){
+            CourseType2 = JSON.parse(JSON.stringify(this.CourseType[0]))
+          }else if(this.typeCheck2){
+            CourseType2 = JSON.parse(JSON.stringify(this.CourseType[2].filter(item => {
+              return item.pid == "34628934-d02f-11ec-8c78-005056b86db5"
+            })))
+          }else{
+            CourseType2 = JSON.parse(JSON.stringify(this.CourseType[0]))
+          }
           if(this.oid == "69893dca-1d47-11ed-8c78-005056b86db5"){
             if(this.pTypeCheckName.length){
               CourseType2 = this.CourseType3.filter(el => {
@@ -601,8 +649,14 @@ export default {
               // }
               let pid = CourseType2[i].id
               if(typeof pid != "object") pid = pid.split(",")
-              if(res.data[0][j].pid && this.arrayToArray(pid,res.data[0][j].pid.split(",")).length){
-                CourseType2[i].course.push(res.data[0][j])
+              if(this.typeCheck2){
+                if(res.data[0][j].typeid && this.arrayToArray(pid,res.data[0][j].typeid.split(",")).length){
+                  CourseType2[i].course.push(res.data[0][j])
+                }
+              }else {
+                if(res.data[0][j].pid && this.arrayToArray(pid,res.data[0][j].pid.split(",")).length){
+                  CourseType2[i].course.push(res.data[0][j])
+                }
               }
             }
           }
@@ -819,7 +873,7 @@ export default {
               }
             }
           }
-          if (this.typeCheck) {
+          if (this.typeCheck || this.typeCheck2) {
             this.selectAll();
           } else {
             this.selectAll2();
@@ -916,6 +970,9 @@ export default {
     let typea = this.$route.query.typea
     let typeb = this.$route.query.typeb
     let typed = this.$route.query.typed
+    if(this.oidArray.indexOf(this.oid) !== -1){
+      this.typeCheck2 = true
+    }
     if(typea || typeb || typed){
       this.typea = typea ? typea : ''
       this.typeb = typeb ? typeb : ''
@@ -936,9 +993,16 @@ export default {
 
 <style scoped>
 @media screen and (max-width: 1024px) {
-  .box_course {
-    margin: 0px 5px 20px 5px !important;
-  }
+  /* .box_course {
+    width: 300px !important;
+  } */
+  .typeCheckFlex{
+      display: grid !important;  
+      grid-template-columns: repeat(3, 1fr) !important; 
+   }
+   .claList{
+      grid-template-columns: repeat(3, 1fr) !important; 
+   }
 }
 
 .student_head .imgS {
@@ -1003,9 +1067,10 @@ export default {
   flex-direction: column;
   flex-wrap: nowrap;
   /* margin: 0px 1% 20px; */
-  margin: 0 15px 20px 0;
-  width: 300px;
+  /* margin: 0 15px 20px 0; */
+  /* width: 300px; */
   /* height: 260px; */
+  max-width: 400px;
   /*border: 1px solid #cecece; */
   border-radius: 10px;
   overflow: hidden;
@@ -1334,7 +1399,61 @@ export default {
   cursor: pointer;
   position: absolute;
   top: 20px;
-  right: 20px;
+  left: 20px;
   z-index: 999999;
 }
+.r_pub_button_retrun {
+  font-weight: bold;
+  font-size: 20px;
+  display: flex;align-items: center;
+  gap: 10px;
+  cursor: pointer;
+  /* padding:0px 90px 0; */
+  /* height: 23.8px; */
+  margin-bottom: 15px;
+  width: 90%;
+  margin: auto;
+  transform: translate(0px, -35px);
+
+}
+
+/* .r_pub_button_retrun::before {
+  content: "";
+  width: 14px;
+  height: 14px;
+  min-width: 14px;
+  min-height: 14px;
+  background-size: 100% 100%;
+  display: block;
+  margin-right: 7px;
+  background-image: url(../assets/icon/course/icon_return2.png);
+} */
+ .claList{
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+    gap: 30px;
+ }
+ .claListFlex{
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 30px;
+ }
+ .box_courseFlex{
+    display: flex;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    /* max-width: 400px; */
+    flex: 1;
+    border-radius: 10px;
+    overflow: hidden;
+    box-shadow: 0px 1px 3px 0px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%),
+      0px 2px 1px -1px rgb(0 0 0 / 12%);
+    justify-content: space-between;
+    cursor: pointer;
+ }
+ .typeCheckFlex{
+    display: grid; 
+    grid-template-columns: repeat(4, 1fr); 
+    gap: 30px;
+ }
 </style>

+ 458 - 0
src/components/pptEasyClass/index.vue

@@ -0,0 +1,458 @@
+<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 class="free-browse-switch" v-if="tType == 2">
+            <span class="switch-label" :class="{ active: freeBrowse }">{{ freeBrowse ? '自由浏览' : '跟随模式' }}</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 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.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 ? 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>

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

@@ -0,0 +1,340 @@
+<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="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"></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:"",
+      showIframe: false,
+      iframeSrc: "",
+      courseDetail: {},
+      pageLoading: false,
+      inviteCode:"",
+      startTime: "",
+      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;
+    if (this.courseDetail.userid == this.userid && 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 ? 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.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>

+ 184 - 38
src/components/studyStudent.vue

@@ -75,7 +75,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>
@@ -484,6 +484,7 @@
                   flex-direction: column;
                   position: relative;
                 "
+                class="renderedFor"
               >
                 <div
                   style="
@@ -534,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>
@@ -697,9 +698,9 @@
                               <span v-if="vitem.text">{{ vitem.text }}-</span
                               >{{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img src="../assets/icon/newIcon/down.png" alt />
-                            </div>
+                            </div> -->
                           </div>
 
                           <div class="navListItem" v-if="vitem.type == 6">
@@ -759,9 +760,9 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img src="../assets/icon/newIcon/down.png" alt />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 12">
                             <div class="navText" @click="downloadFile2(vitem)">
@@ -777,9 +778,9 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img src="../assets/icon/newIcon/down.png" alt />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 13">
                             <div
@@ -789,9 +790,9 @@
                             >
                               {{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img src="../assets/icon/newIcon/down.png" alt />
-                            </div>
+                            </div> -->
                           </div>
                             <div class="navListItem" v-if="vitem.type == 16">
                               <div
@@ -811,6 +812,24 @@
                                 />
                               </div>
                           </div>
+                          <div class="navListItem" v-if="vitem.type == 17">
+                              <div
+                                class="navText"
+                                @click="checkHtml(vitem, vindex)"
+                                :class="isClickNav == vindex ? 'isClickNav' : ''"
+                              >
+                                {{ vitem.name }}
+                              </div>
+                              <div
+                                class="downIcon"
+                                @click="checkFileFull1(vitem.type, vitem)"
+                              >
+                                <img
+                                  src="../assets/icon/newIcon/allScreen.png"
+                                  alt
+                                />
+                              </div>
+                          </div>
                         </div>
 
                         <div
@@ -828,7 +847,7 @@
                                 <span v-if="vitem.text">{{ vitem.text }}-</span
                                 >{{ vitem.name }}
                               </div>
-                              <div
+                              <!-- <div
                                 class="downIcon"
                                 @click="downloadFile2(vitem)"
                               >
@@ -836,7 +855,7 @@
                                   src="../assets/icon/newIcon/down.png"
                                   alt
                                 />
-                              </div>
+                              </div> -->
                             </div>
                           </div>
                         </div>
@@ -1507,7 +1526,7 @@
                         </div>
                       </div>
                     </div>
-                    <div class="tooldetail" v-if="tool.toolDetail != ''" :class="{isUpdateToolDetailClass:toolDetailIndex == toolIndex}">
+                    <div class="tooldetail renderedFor" v-if="tool.toolDetail != ''" :class="{isUpdateToolDetailClass:toolDetailIndex == toolIndex}">
                       <!-- <div class="toolTitle">工具描述</div> -->
                         <!-- @click.stop="updateToolDetail(toolIndex, 2)" -->
                       <div style="height:100%;"
@@ -3848,7 +3867,7 @@
                       <div
                         v-for="(s, sIndex) in noWorksS[toolIndex]"
                         :key="sIndex"
-                        class="noWorksName"
+                        class="noWorksName2"
                         @click="teacherWorkSubmit(72, toolIndex, taskCount, s)"
                       >
                         <el-tooltip
@@ -4424,8 +4443,9 @@
                               word-break: break-word;
                               cursor: pointer;
                             "
+                            class="renderedFor"
                           >
-                              {{ index + 1 + "、"  }} <span v-html="renderedFormula(item.teststitle)"></span>
+                              {{ index + 1 + "、"  }} <span  v-html="renderedFormula(item.teststitle)"></span>
                           </div>
                         </el-tooltip>
                       </div>
@@ -9593,21 +9613,21 @@
             :key="index1"
           >
             <div class="a_add_head">
-              <div style="display: flex;align-items: center;">
+              <div style="display: flex;">
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
-                  <div>题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
+                  <div class="renderedFor"><span>题目:</span> <span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
               </div>
               <img
                 v-if="testJson.testJson[index1].img"
@@ -9726,13 +9746,13 @@
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
@@ -10055,7 +10075,9 @@
               @change="updateLookOpen"
             ></el-switch>
           </div>
-          <div class="switch_box" v-if="courseDetail.userid == userid">
+          <div class="switch_box" v-if="(courseDetail.userid == userid ||
+                (courseDetail.course_teacher &&
+                  courseDetail.course_teacher.indexOf(userid) != -1)) && !splitScreenData.isOpen">
             <span>开启跟随模式</span>
             <el-switch
               v-model="IsFollow"
@@ -12664,6 +12686,7 @@ export default {
   },
   data() {
     return {
+      startTime: "",
       // 是否允许学生查看内容资料 2不可以 1可以
       IsStulook:false,
       homeWorkLoading:false,
@@ -12947,7 +12970,7 @@ export default {
       timer: null,
       timer2: null,
       opertimer: null,
-      showType: 0,
+      showType: '',
       fileType: 0,
       showPDF: false,
       noteName: "",
@@ -13046,6 +13069,13 @@ export default {
       confirmOpenDigData:'',
       canUseCourseId: ['bfbe1913-2f87-11ef-bf55-005056b86db5','3a64b199-d2eb-11ef-a2d1-005056b86db5', 'bb0b1995-0207-11ef-b534-005056b86db5', 'f77921c8-d2f1-11ef-a2d1-005056b86db5'],
       diffKey:"1",
+      getCourseGroupLoading: false,
+      selectSWorksLoading:false,
+      selectStudentLoading:false,
+      selectSLookLoading:false,
+      getPickLoading:false,
+      selectPzLoading:false,
+      getSplitScreenDataLoading:false,
     };
   },
   methods: {
@@ -13384,6 +13414,12 @@ export default {
 					this.insertMemorandum(`选择<span class="variable">阶段${i+1}${this.navList[i].dyName?':'+this.navList[i].dyName:''}</span>→<span class="variable">任务${j+1}${this.navList[i].task[j].taskName?':'+this.navList[i].task[j].taskName:''}</span>→<span class="variable">工具${k+1}:${this.toolsList[this.navList[i].task[j].tool[k].tool]}</span>`)
 				}
       }
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) &&
+          this.IsFollow) {
+        this.setCTask();
+      }
 
       // var b = this.$refs["bz" + k][0];
       // a.scrollTop = b.offsetTop;
@@ -14510,6 +14546,8 @@ export default {
         });
     },
     selectStudent() {
+      if(this.selectStudentLoading) return
+      this.selectStudentLoading = true
       //学生查看自己作业
       let params = {
         uid: this.userid,
@@ -14832,8 +14870,12 @@ export default {
               }
             }
           }
+          this.selectStudentLoading = false
+
         })
         .catch((err) => {
+          this.selectStudentLoading = false
+
           console.error(err);
         });
     },
@@ -15192,6 +15234,8 @@ export default {
         .catch(() => {});
     },
     selectSWorks(gindex) {
+      if(this.selectSWorksLoading) return
+      this.selectSWorksLoading = true
       //教师查看全部作业
       let params = {
         cid: this.id,
@@ -16292,8 +16336,12 @@ export default {
               }, 0)
             })
           }
+          this.selectSWorksLoading = false
+
         })
         .catch((err) => {
+          this.selectSWorksLoading = false
+
           console.error(err);
         });
     },
@@ -17046,12 +17094,15 @@ export default {
       this.getHomeWork();
       this.getCourseDetail(2);
       this.$forceUpdate();
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
     },
 
     openTask(s, n, i,ctype) {
+      // 这段代码没用开启了跟随学生侧边栏会隐藏掉
       if (this.IsFollow && this.tType == 2) {
         this.$message.error("已经开启跟随模式,请认真跟堂听讲");
         return;
@@ -17164,7 +17215,9 @@ export default {
       this.selectPz();
       this.getHomeWork();
       this.getCourseDetail(2);
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
 			if(flag){
@@ -17296,7 +17349,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then((res) => {
-          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+          if ((this.courseDetail.userid == this.userid ||
+              (this.courseDetail.course_teacher && 
+              this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
+            this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+          }
 
           if (type != 2) {
             loading.close();
@@ -17494,6 +17551,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;
                 }
               }
             }
@@ -17663,6 +17723,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;
                 }
               }
             }
@@ -17704,7 +17767,7 @@ export default {
             if (this.courseDetail.userid == this.userid) {
             
               // 开局关闭学生查看内容
-              this.StulookMode(false)
+              this.StulookMode(true)
               // 开局打开跟随模式
               this.followingMode(true)
             }
@@ -17795,6 +17858,8 @@ export default {
         });
     },
     getCourseGroup(gindex) {
+      if(this.getCourseGroupLoading) return
+      this.getCourseGroupLoading = true
       let params = {
         cid: this.id,
         classid: this.tcid ? this.tcid : "1",
@@ -17844,8 +17909,12 @@ export default {
             this.selectSWorks(gindex);
             this.isGroup = false;
           }
+          this.getCourseGroupLoading = false
+
         })
         .catch((err) => {
+          this.getCourseGroupLoading = false
+
           // this.$message.error("网络不佳");
           console.error(err);
         });
@@ -18016,6 +18085,8 @@ export default {
       this.selectPz();
     },
     selectPz() {
+      if(this.selectPzLoading) return
+      this.selectPzLoading = true
       let params = {
         cid: this.id,
         s: this.courseType,
@@ -18038,8 +18109,12 @@ export default {
               }
             }
           }
+          this.selectPzLoading = false
+
         })
         .catch((err) => {
+          this.selectPzLoading = false
+
           console.error(err);
         });
     },
@@ -18193,6 +18268,8 @@ export default {
         });
     },
     selectSLook() {
+      if(this.selectSLookLoading) return
+      this.selectSLookLoading = true
       let params = {
         cid: this.id,
       };
@@ -18225,8 +18302,12 @@ export default {
               this.getCourseDetail(2);
             }
           }
+          this.selectSLookLoading = false
+
         })
         .catch((err) => {
+          this.selectSLookLoading = false
+
           console.error(err);
         });
     },
@@ -18353,6 +18434,7 @@ export default {
           state: JSON.stringify(_state),
         },
       ];
+      // 这两个接口是一样的type无所谓了
       this.ajax
         .post(
           this.$store.state.api +
@@ -19541,6 +19623,8 @@ export default {
 			this.insertMemorandum(`点击工作区<span class="variable">工具${index+1}:${this.toolsList[t]}</span>`)
     },
     teacherWorkSubmit(t, i, index, s) {
+      console.log('t',t);
+      if(t == 72) return
       this.sStudent = s;
       this.toolindex = i;
       this.sTool = t;
@@ -21009,6 +21093,8 @@ export default {
         });
     },
     getPick() {
+      if(this.getPickLoading) return
+      this.getPickLoading = true
       let params = {
         cid: this.id,
       };
@@ -21046,8 +21132,12 @@ export default {
               })
               .catch(() => {});
           }
+          this.getPickLoading = false
+
         })
         .catch((err) => {
+          this.getPickLoading = false
+
           this.$message.error("网络不佳");
           console.error(err);
         });
@@ -21234,6 +21324,8 @@ export default {
     getSplitScreenData() {
       // return;
       // if (this.tType != 1) return;
+      if(this.getSplitScreenDataLoading) return
+      this.getSplitScreenDataLoading = true
       let params = {
         cid: this.id
       };
@@ -21300,8 +21392,12 @@ export default {
                 .catch(() => {});
             }
           }
+          this.getSplitScreenDataLoading = false
+
         })
         .catch(e => {
+          this.getSplitScreenDataLoading = false
+
           console.log("获取分屏数出错:", e);
         });
     },
@@ -21569,6 +21665,22 @@ export default {
     clearInterval(this.opertimer);
     this.opertimer = null;
 		this.updateSplitScreenData(1);
+    if(this.courseDetail.userid == this.userid && 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 ? this.tcid2 : '',
+        courseTime: courseTime,
+        startTime: this.startTime,
+        endTime: endTime,
+      })
+      console.log('同步数据')
+    }
   },
   computed: {
     renderedFormula2() {
@@ -21764,12 +21876,17 @@ export default {
 
   },
   mounted() {
-    if (this.tType == 1) {
-       // 开局关闭学生查看内容
-      this.StulookMode(false)
-      // 开局打开跟随模式
-      this.followingMode(true)
-    }
+    this.startTime = new Date().toLocaleString("zh-CN", { 
+      hour12: false, 
+      timeZone: "Asia/Shanghai" 
+    }).replace(/\//g, "-");
+
+    // if (this.tType == 1) {
+    //    // 开局关闭学生查看内容
+    //   this.StulookMode(false)
+    //   // 开局打开跟随模式
+    //   this.followingMode(true)
+    // }
     document.body.addEventListener("click", (e) => {
       if (this.isUpdateToolDetail1) {
         this.updateToolDetail(this.toolDetailIndex);
@@ -23570,6 +23687,30 @@ export default {
   text-overflow: ellipsis;
   white-space: nowrap;
 }
+.noWorksName2 {
+  background: #fff;
+  color: #0061ff;
+  width: 90px;
+  height: 25px;
+  text-align: center;
+  line-height: 25px;
+  border-radius: 4px;
+  margin: 10px 15px 10px 0;
+  white-space: nowrap;
+  overflow: hidden;
+  padding: 5px;
+  text-overflow: ellipsis;
+  cursor: pointer;
+  border: 1px solid #0061ff;
+}
+
+.noWorksName2 > span {
+  max-width: 100%;
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
 
 .isWorksName2 {
   width: 100px;
@@ -26287,18 +26428,23 @@ div::-webkit-scrollbar {
   overflow: hidden;
   text-overflow: ellipsis;
 }
-.pb_content >>> .katex {
-  font-size: 16px;
+
+.renderedFor >>> .katex {
+  font-size: 18px;
   width: 100%;
   white-space: normal;
+  font-family: '黑体' !important;
 }
-.pb_content >>> .katex .base{
+.renderedFor >>> .katex .base{
   display: inline !important;
   display: contents !important;
 }
 
-.pb_content >>> .katex .base .cjk_fallback{
+.renderedFor>>> .katex .base .cjk_fallback{
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 1 - 1
src/components/studyStudentJiu.vue

@@ -73,7 +73,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>

+ 157 - 37
src/components/studySutdentClass/studyStudent.vue

@@ -103,7 +103,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>
@@ -521,6 +521,7 @@
                   flex-direction: column;
                   position: relative;
                 "
+                class="renderedFor"
               >
                 <div
                   style="
@@ -529,7 +530,7 @@
                     font-size: 18px;
                     color: #0e1e33;
                   "
-                  class="cont"
+                   class="cont"
                   v-if="
                     chapInfoList[courseType].chapterInfo[0].taskJson[taskCount]
                       .taskDetail != ''
@@ -568,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>
@@ -729,12 +730,12 @@
                               <span v-if="vitem.text">{{ vitem.text }}-</span
                               >{{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 6">
                             <div
@@ -793,12 +794,12 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 12">
                             <div class="navText" @click="downloadFile2(vitem)">
@@ -814,12 +815,12 @@
                                 alt
                               />
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 13">
                             <div
@@ -829,12 +830,12 @@
                             >
                               {{ vitem.name }}
                             </div>
-                            <div class="downIcon" @click="downloadFile2(vitem)">
+                            <!-- <div class="downIcon" @click="downloadFile2(vitem)">
                               <img
                                 src="../../assets/icon/newIcon/down.png"
                                 alt
                               />
-                            </div>
+                            </div> -->
                           </div>
                           <div class="navListItem" v-if="vitem.type == 16">
                             <div
@@ -854,6 +855,24 @@
                               />
                             </div>
                           </div>
+                          <div class="navListItem" v-if="vitem.type == 17">
+                            <div
+                              class="navText"
+                              @click="checkHtml(vitem, vindex)"
+                              :class="isClickNav == vindex ? 'isClickNav' : ''"
+                            >
+                              {{ vitem.name }}
+                            </div>
+                            <div
+                              class="downIcon"
+                              @click="checkFileFull1(vitem.type, vitem)"
+                            >
+                              <img
+                                src="../../assets/icon/newIcon/allScreen.png"
+                                alt
+                              />
+                            </div>
+                          </div>
                         </div>
                         <div class="fileC_box" v-if="fileC[0].length > 0">
                           <div class="fileC_title">以下文件不支持预览</div>
@@ -867,7 +886,7 @@
                                 <span v-if="vitem.text">{{ vitem.text }}-</span
                                 >{{ vitem.name }}
                               </div>
-                              <div
+                              <!-- <div
                                 class="downIcon"
                                 @click="downloadFile2(vitem)"
                               >
@@ -875,7 +894,7 @@
                                   src="../../assets/icon/newIcon/down.png"
                                   alt
                                 />
-                              </div>
+                              </div> -->
                             </div>
                           </div>
                         </div>
@@ -1563,7 +1582,7 @@
                       </div>
                     </div>
                     <div
-                      class="tooldetail"
+                      class="tooldetail renderedFor"
                       v-if="tool.toolDetail != ''"
                       :class="{
                         isUpdateToolDetailClass: toolDetailIndex == toolIndex
@@ -5173,7 +5192,7 @@
                       <div
                         v-for="(s, sIndex) in noWorksS[toolIndex]"
                         :key="sIndex"
-                        class="noWorksName"
+                        class="noWorksName2"
                         @click="teacherWorkSubmit(72, toolIndex, taskCount, s)"
                       >
                         <el-tooltip
@@ -6201,6 +6220,7 @@
                               word-break: break-word;
                               cursor: pointer;
                             "
+                            class="renderedFor"
                           >
                             {{ index + 1 + "、"  }} <span v-html="renderedFormula(item.teststitle)"></span>
                           </div>
@@ -12838,21 +12858,21 @@
             :key="index1"
           >
             <div class="a_add_head">
-              <div style="display: flex;align-items: center;">
+              <div style="display: flex;">
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
-                <div>题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
+                <div class="renderedFor">题目:<span v-html="renderedFormula(testJson.testJson[index1].teststitle)"></span></div>
               </div>
               <img
                 v-if="testJson.testJson[index1].img"
@@ -12971,13 +12991,13 @@
                 <span class="askIndex">{{ index1 + 1 }}</span>
                 <div
                   v-if="testJson.testJson[index1].type == '1'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (单选题)
                 </div>
                 <div
                   v-if="testJson.testJson[index1].type == '2'"
-                  style="margin-right: 5px; min-width: 70px"
+                  style="margin-right: 5px; min-width: 70px;flex-shrink: 0;"
                 >
                   (多选题)
                 </div>
@@ -13300,7 +13320,9 @@
               @change="updateLookOpen"
             ></el-switch>
           </div>
-          <div class="switch_box" v-if="courseDetail.userid == userid">
+          <div class="switch_box" v-if=" (courseDetail.userid == userid ||
+              (courseDetail.course_teacher &&
+                courseDetail.course_teacher.indexOf(userid) != -1)) && !splitScreenData.isOpen">
             <span>开启跟随模式</span>
             <el-switch
               v-model="IsFollow"
@@ -16379,7 +16401,14 @@ export default {
       languageSetting: 0, //0中文 1繁体 2英文
       toolListS: [],
       commentDetailCopy: "",
-      diffKey:"1"
+      diffKey:"1",
+      getCourseGroupLoading: false,
+      selectSWorksLoading:false,
+      selectStudentLoading:false,
+      selectSLookLoading:false,
+      getPickLoading:false,
+      selectPzLoading:false,
+      getSplitScreenDataLoading:false,
     };
   },
   watch:{
@@ -16401,11 +16430,11 @@ export default {
     },
     worksStudent: {
       handler(newVal, oldVal) {
-          const sum1 = newVal.reduce((total, subArr) => total + subArr.length, 0);
-          const sum2 = oldVal.reduce((total, subArr) => total + subArr.length, 0);
+          // const sum1 = newVal.reduce((total, subArr) => total + subArr.length, 0);
+          // const sum2 = oldVal.reduce((total, subArr) => total + subArr.length, 0);
           // console.log('worksStudent',sum1,sum2);
           
-          if(sum1 != sum2){
+          if(JSON.stringify(newVal) !=  JSON.stringify(oldVal)){
               this.AIloading = [];
               this.loopLoading = [];
 
@@ -17388,7 +17417,12 @@ export default {
 					this.insertMemorandum(`选择<span class="variable">阶段${i+1}${this.navList[i].dyName?':'+this.navList[i].dyName:''}</span>→<span class="variable">任务${j+1}${this.navList[i].task[j].taskName?':'+this.navList[i].task[j].taskName:''}</span>→<span class="variable">工具${k+1}:${this.toolsList[this.navList[i].task[j].tool[k].tool]}</span>`)
 				}
       }
-
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) &&
+          this.IsFollow) {
+        this.setCTask();
+      }
       // var b = this.$refs["bz" + k][0];
       // a.scrollTop = b.offsetTop;
     },
@@ -18537,6 +18571,8 @@ export default {
         });
     },
     selectStudent() {
+      if(this.selectStudentLoading) return
+      this.selectStudentLoading = true
       //学生查看自己作业
       let params = {
         uid: this.userid,
@@ -18859,8 +18895,12 @@ export default {
               }
             }
           }
+          this.selectStudentLoading = false
+
         })
         .catch((err) => {
+          this.selectStudentLoading = false
+
           console.error(err);
         });
     },
@@ -19230,6 +19270,8 @@ export default {
       return lang;
     },
     selectSWorks(gindex) {
+      if(this.selectSWorksLoading) return
+      this.selectSWorksLoading = true
       //教师查看全部作业
       let params = {
         cid: this.id,
@@ -20341,8 +20383,12 @@ export default {
               }, 0);
             });
           }
+          this.selectSWorksLoading = false
+
         })
         .catch(err => {
+          this.selectSWorksLoading = false
+
           console.error(err);
         });
     },
@@ -21096,7 +21142,9 @@ export default {
       this.getHomeWork();
       this.getCourseDetail(2);
       this.$forceUpdate();
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
     },
@@ -21213,7 +21261,9 @@ export default {
 			}else{
 				this.insertMemorandum(`进入<span class="variable">阶段${s+1}${this.navList[s].dyName?':'+this.navList[s].dyName:''}</span>→<span class="variable">任务${n+1}${this.navList[s].task[n].taskName?':'+this.navList[s].task[n].taskName:''}</span>`)
 			}
-      if (this.courseDetail.userid == this.userid && this.IsFollow) {
+      if ((this.courseDetail.userid == this.userid ||
+          (this.courseDetail.course_teacher && 
+          this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
         this.setCTask();
       }
     },
@@ -21338,8 +21388,11 @@ export default {
       this.ajax
         .get(this.$store.state.api + "selectCourseDetail3", params)
         .then((res) => {
-          this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
-
+          if ((this.courseDetail.userid == this.userid ||
+              (this.courseDetail.course_teacher && 
+              this.courseDetail.course_teacher.indexOf(this.userid) != -1)) && this.IsFollow) {
+            this.addCourseState(1, JSON.parse(res.data[0][0].chapters));
+          }
           if (type != 2) {
             loading.close();
             if (
@@ -21537,6 +21590,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;
                 }
               }
             }
@@ -21707,6 +21763,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;
                 }
               }
             }
@@ -21812,7 +21871,7 @@ export default {
             if (this.courseDetail.userid == this.userid) {
             
               // 开局关闭学生查看内容
-              this.StulookMode(false)
+              this.StulookMode(true)
               // 开局打开跟随模式
               this.followingMode(true)
             }
@@ -21914,6 +21973,8 @@ export default {
         });
     },
     getCourseGroup(gindex) {
+      if(this.getCourseGroupLoading) return
+      this.getCourseGroupLoading = true
       let params = {
         cid: this.id,
         classid: this.tcid ? this.tcid : "1",
@@ -21963,8 +22024,12 @@ export default {
             this.selectSWorks(gindex);
             this.isGroup = false;
           }
+          this.getCourseGroupLoading = false
+
         })
         .catch((err) => {
+          this.getCourseGroupLoading = false
+
           // this.$message.error("网络不佳");
           console.error(err);
         });
@@ -22134,6 +22199,8 @@ export default {
       this.selectPz();
     },
     selectPz() {
+      if(this.selectPzLoading) return
+      this.selectPzLoading = true
       let params = {
         cid: this.id,
         s: this.courseType,
@@ -22156,8 +22223,12 @@ export default {
               }
             }
           }
+          this.selectPzLoading = false
+
         })
         .catch((err) => {
+          this.selectPzLoading = false
+
           console.error(err);
         });
     },
@@ -22311,6 +22382,8 @@ export default {
         });
     },
     selectSLook() {
+      if(this.selectSLookLoading) return
+      this.selectSLookLoading = true
       let params = {
         cid: this.id,
       };
@@ -22343,8 +22416,12 @@ export default {
               this.getCourseDetail(2);
             }
           }
+          this.selectSLookLoading = false
+
         })
         .catch((err) => {
+          this.selectSLookLoading = false
+
           console.error(err);
         });
     },
@@ -23659,6 +23736,8 @@ export default {
 			this.insertMemorandum(`点击工作区<span class="variable">工具${index+1}:${this.toolsList[t]}</span>`)
     },
     teacherWorkSubmit(t, i, index, s) {
+      console.log('t',t);
+      if(t == 72) return
       this.sStudent = s;
       this.toolindex = i;
       this.sTool = t;
@@ -25134,6 +25213,9 @@ export default {
         });
     },
     getPick() {
+      if(this.getPickLoading) return
+      this.getPickLoading = true
+
       let params = {
         cid: this.id,
       };
@@ -25171,8 +25253,12 @@ export default {
               })
               .catch(() => {});
           }
+          this.getPickLoading = false
+
         })
         .catch((err) => {
+          this.getPickLoading = false
+
           this.$message.error("网络不佳");
           console.error(err);
         });
@@ -25359,6 +25445,8 @@ export default {
     getSplitScreenData() {
       // return;
       // if (this.tType != 1) return;
+      if(this.getSplitScreenDataLoading) return
+      this.getSplitScreenDataLoading = true
       let params = {
         cid: this.id
       };
@@ -25425,8 +25513,12 @@ export default {
                 .catch(() => {});
             }
           }
+          this.getSplitScreenDataLoading = false
+
         })
         .catch(e => {
+          this.getSplitScreenDataLoading = false
+
           console.log("获取分屏数出错:", e);
         });
     },
@@ -27703,6 +27795,30 @@ export default {
   text-overflow: ellipsis;
   white-space: nowrap;
 }
+.noWorksName2 {
+  background: #fff;
+  color: #0061ff;
+  width: 90px;
+  height: 25px;
+  text-align: center;
+  line-height: 25px;
+  border-radius: 4px;
+  margin: 10px 15px 10px 0;
+  white-space: nowrap;
+  overflow: hidden;
+  padding: 5px;
+  text-overflow: ellipsis;
+  cursor: pointer;
+  border: 1px solid #0061ff;
+}
+
+.noWorksName2 > span {
+  max-width: 100%;
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
 
 .isWorksName2 {
   width: 100px;
@@ -30423,18 +30539,22 @@ div::-webkit-scrollbar {
 
   text-overflow: ellipsis;
 }
-.pb_content >>> .katex {
-  font-size: 16px;
+.renderedFor >>> .katex {
+  font-size: 18px;
   width: 100%;
   white-space: normal;
+  font-family: '黑体' !important;
 }
-.pb_content >>> .katex .base{
+.renderedFor >>> .katex .base{
   display: inline !important;
   display: contents !important;
 }
 
-.pb_content >>> .katex .base .cjk_fallback{
+.renderedFor>>> .katex .base .cjk_fallback{
     white-space: normal !important;
     display: inline !important;
 }
+.notop >>> .vjs-fluid{
+  padding-top: 0 !important;
+}
 </style>

+ 1 - 1
src/components/trainCourse/easy2/studyStudent.vue

@@ -102,7 +102,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>

+ 1 - 1
src/components/trainCourse/easy3/studyStudent.vue

@@ -102,7 +102,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>

+ 1 - 1
src/components/trainCourse/studyStudent.vue

@@ -73,7 +73,7 @@
             style="padding: 0 0 8px 0"
           >
             <div>
-              <span>随机码:{{ inviteCode }}</span>
+              <span>识别码:{{ inviteCode }}</span>
             </div>
           </div>
         </div>

+ 2 - 0
src/config/config.js

@@ -11,8 +11,10 @@ const store = new Vuex.Store({
         nCount: 0,
 		apiM: 'https://pbl.cocorobo.cn/api/mongo/',
         api: 'https://pbl.cocorobo.cn/api/pbl/',
+        apiSz: 'https://pbl.cocorobo.cn/api/szdjg/',
         socket: "https://poll.cocorobo.cn",
         // api: 'http://localhost:7003/api/pbl/',
+        // apiSz: 'http://localhost:7003/api/szdjg/',
     },
 
     mutations: {

+ 12 - 0
src/main.js

@@ -45,6 +45,18 @@ Vue.prototype.openLoading = function(target) {
 }
 Vue.prototype.$qs = qs
 
+let region = 'cn'
+if (window.location.href.includes('beta') || window.location.href.includes('localhost')) {
+  region = 'beta'
+} else if (window.location.href.includes('cn')) {
+  region = 'cn'
+} else if (window.location.href.includes('hk')) {
+  region = 'hk'
+} else if (window.location.href.includes('com')) {
+  region = 'com'
+} 
+Vue.prototype.$region = region
+
 /* eslint-disable no-new */
 new Vue({
     el: '#app',

+ 89 - 1
src/mixins/mixin.js

@@ -59,7 +59,7 @@ export const myMixin = {
         role: this.userJson.type =='1'?'老师':'学生',
         browser: browser,
         userTime: userTime == "1" ? _time : userTime, // 使用时间 1次的就1 其次传秒
-        loadTime: loadTime, //load的时间没有就“”
+        loadTime: loadTime, //load的时间没有就""
         object: JSON.stringify(object), //执行信息传json
         status: status //成功返回success。失败返回error的信息
       };
@@ -78,6 +78,94 @@ export const myMixin = {
           console.log("保存失败");
           console.log(e);
         });
+    },
+    // 新增:上课/备课数据实时同步接口
+    async syncClassData(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 = classData.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": 1,
+        "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 ? 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 };
+      }
+    },
+    // 新增:上课/备课数据实时同步接口
+    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 = classData.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 ? 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 };
+      }
     }
   }
 };

+ 7 - 1
src/router/index.js

@@ -38,6 +38,7 @@ import courseDetailTrain from '@/components/trainCourse/courseDetail'
 import studyStudentTrain from '@/components/trainCourse/studyStudent'
 import studyStudentE2Train from '@/components/trainCourse/easy2/studyStudent'
 import studyStudentE3Train from '@/components/trainCourse/easy3/studyStudent'
+import pptEasyClass from '@/components/pptEasyClass'
 // 全局修改默认配置,点击空白处不能关闭弹窗
 ElementUI.Dialog.props.closeOnClickModal.default = false
 Vue.use(Router).use(ElementUI)
@@ -247,6 +248,11 @@ export default new Router({
             name: 'studyStudentE3Train',
             component: studyStudentE3Train,
             requireAuth: ''
+        },{
+            path: '/pptEasyClass',
+            name: 'pptEasyClass',
+            component: pptEasyClass,
+            requireAuth: ''
         }
     ]
-})
+})

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä