Procházet zdrojové kódy

Merge branch 'master' of https://git.cocorobo.cn/chao/course_resource

lsc před 3 dny
rodič
revize
4d1e6d556b

+ 15 - 0
src/App.vue

@@ -1,5 +1,6 @@
 <script setup>
 import { onMounted, ref, inject } from 'vue'
+import { courseUrl, registerSetCourseUrl } from '@/composables/useCourseIframe'
 import { RouterLink, RouterView, useRoute } from 'vue-router'
 import Header from './views/header.vue';
 import axios from 'axios';
@@ -20,6 +21,7 @@ const setTimeState = ref(null)
 const topUserInfo = ref({})
 
 onMounted(() => {
+  registerSetCourseUrl()
   // 通过 code 获取登录信息
   let isGrantCode = getUrlParam(window.parent.location.href, 'grant_code')
   let ticket = getUrlParam(window.parent.location.href, 'ticket')
@@ -369,7 +371,20 @@ const getUrlParam = (urlStr, urlKey) => {
   <div v-loading="isShow" style="height: 100vh;">
     <router-view></router-view>
   </div>
+  <iframe :src="courseUrl" allow="camera *; microphone *;display-capture;midi;encrypted-media;clipboard-write;clipboard-read" :webkitallowfullscreen="true" :mozallowfullscreen="true" :allowfullscreen="true"  class="courseIframe" v-if="courseUrl"></iframe>
   <!-- </keep-alive> -->
 </template>
 
 <style scoped></style>
+
+<style>
+.courseIframe {
+  width: 100vw;
+  height: 100vh;
+  position: fixed;
+  z-index: 99999;
+  top: 0;
+  left: 0;
+  border: none;
+}
+</style>

+ 30 - 4
src/components/dialog/addClassDialog.vue

@@ -197,6 +197,8 @@
 
         }
   }
+  const packageArray = ref([]);
+
   // 新增:上课/备课数据实时同步接口
     const syncClassData2 = async (classData) => {
       if (!userInfo.user.userid) return
@@ -209,6 +211,30 @@
         console.log(e);
         return syncClassData2(classData);
       }
+
+      if(!packageArray.value || packageArray.value.length == 0){
+        let res = await axios.get("https://pbl.cocorobo.cn/api/pbl/selectai6AllCourse");
+        packageArray.value = res.data[0].map(item => {
+          let json = JSON.parse(item.package);
+          return json;
+        });
+        console.log(this.packageArray);
+      }
+      console.log(this.packageArray);
+
+      let coursePackageName2 = '';
+      let courseName = '';
+      let courseGrade2 = '';
+
+      for(let item of packageArray.value){
+        if(classData.ctitle.includes(item.courseName)){
+          coursePackageName2 = item.coursePackage;
+          courseName = item.courseName;
+          courseGrade2 = item.grade;
+          break;
+        }
+      }
+
       let courseGrade = classData.courseGrade ? await axios.get("https://pbl.cocorobo.cn/api/pbl/getClassById?id="+classData.courseGrade) : '';
       let coursePackageName = await axios.get("https://pbl.cocorobo.cn/api/pbl/getCopyCourseName?id="+classData.courseId);
       let params = {
@@ -217,13 +243,13 @@
         "teacherName": userInfo.user.username,
         "teacherAccount": userInfo.user.accountNumber,
         "teacherPhone": userInfo.user.phonenumber,
-        "eduId": userInfo.user.sessionid,
+        "eduId": userInfo.user.eduid || userInfo.user.sessionid,
         "schoolName": userInfo.user.schoolName,
         "area": userInfo.user.schooldest,
-        "coursePackageName": coursePackageName[0][0].title,
+        "coursePackageName": coursePackageName2 ? coursePackageName2 : coursePackageName.data[0][0].title,
         "courseId": classData.courseId,
-        "courseName": classData.title,
-        "courseGrade": courseGrade ? courseGrade[0][0].name : '无年级',
+        "courseName": courseName || classData.title,
+        "courseGrade": courseGrade2 ? courseGrade2 : courseGrade.data[0][0].name || '无年级',
         "courseTime": classData.courseTime,
         "startTime": classData.startTime,
         "endTime": classData.endTime

+ 7 - 80
src/components/dialog/selectTeachingClassDialog.vue

@@ -76,7 +76,7 @@
 				</div>
 				<div class="b_bottom">
 					<div @click="close()">{{ lang.ssCancel }}</div>
-          			<div class="b_b_submit" @click="selectClassSuccess()">{{selectId ? lang.ssConfirm : lang.ssEnterDirect}}</div>
+          <div class="b_b_submit" @click="selectClassSuccess()">{{selectId ? lang.ssConfirm : lang.ssEnterDirect}}</div>
 				</div>
 
 		</el-dialog>
@@ -87,14 +87,16 @@
 			:courseDetail="courseDetail"
 			@success="getCourseList"
 		/>
+
 </template>
 
 <script setup>
 import { ref, inject } from "vue";
 import { userInfoStore } from "../../stores/counter";
 import addClassDialog from "./addClassDialog.vue";
-const emit = defineEmits(["success", "changeClassList"]);
+const emit = defineEmits(["success", "changeClassList", "openCourse"]);
 import axios from '@/services/config'
+import { addOp3 } from '@/mixins/mixin'
 const lang = inject('lang')
 const checkStage = ref('0');
 
@@ -340,7 +342,7 @@ const gotoCourse = (id) => {
               "&tType=" +
               userInfo.user.type +
               "&screenType=" +
-              '1' +
+              '2' +
               "&tcid=" +
               id
           );
@@ -361,7 +363,7 @@ const gotoCourse = (id) => {
               "&tType=" +
               userInfo.user.type +
               "&screenType=" +
-              '1'
+              '2'
           );
         }
       }
@@ -377,10 +379,8 @@ const gotoCourse = (id) => {
           console.error(err);
         });
 }
-
 const goto = (val) => {
-  console.log('val',val)
-  top.U.MD.D.I.openInApplication('setUrl',{url:val,title:'课程详情',id:new Date().getTime()})
+  emit('openCourse', val)
 }
 
 const insertMemorandum = (_html,tcid="") => {//保存行为操作
@@ -406,79 +406,6 @@ const insertMemorandum = (_html,tcid="") => {//保存行为操作
       console.log(e)
     })
   }
-const detectBrowser = () => {
-  const ua = navigator.userAgent;
-
-  // 按优先级顺序检测
-  if (ua.includes("Edg/") || ua.includes("Edge/")) {
-    return "Microsoft Edge";
-  } else if (ua.includes("Firefox")) {
-    return "Mozilla Firefox";
-  } else if (ua.includes("Trident") || ua.includes("MSIE")) {
-    return "Internet Explorer";
-  } else if (ua.includes("360EE")) {
-    return "360 Browser (极速模式)";
-  } else if (ua.includes("360SE")) {
-    return "360 Browser (安全模式)";
-  } else if (ua.includes("SLBrowser")) {
-    return "QQ Browser";
-  } else if (ua.includes("UCBrowser")) {
-    return "UC Browser";
-  } else if (ua.includes("Opera") || ua.includes("OPR/")) {
-    return "Opera";
-  } else if (ua.includes("Chrome") && !ua.includes("Edg/")) {
-    return "Google Chrome";
-  } else if (ua.includes("Safari/") && !ua.includes("Chrome")) {
-    return "Safari";
-  } else {
-    return "Other Browser";
-  }
-}
-const addOp3 = async (userTime, loadTime, object, status) => {
-  if (!userInfo.user.userid) return
-  // try {
-  //   if(!userInfo.user || !userInfo.user.accountNumber){
-  //     let res = await axios.get("https://pbl.cocorobo.cn/api/pbl/selectUser?userid="+userInfo.user.userid)
-  //     userInfo.user = res[0][0]
-  //   }
-  // } catch (e) {
-  //   console.log(e);
-  //   return addOp3(userTime, loadTime, object, status);
-  // }
-  let _time = new Date()
-    .toLocaleString("zh-CN", { hour12: false, timeZone: "Asia/Shanghai" })
-    .replace(/\//g, "-");
-  let browser = detectBrowser();
-  let params = {
-    userid: userInfo.user.userid,
-    username: userInfo.user.username,
-    accountNumber: userInfo.user.accountNumber,
-    org: userInfo.user.orgName,
-    school: userInfo.user.schoolName,
-    role: userInfo.user.type =='1'?'老师':'学生',
-    browser: browser,
-    userTime: userTime == "1" ? _time : userTime, // 使用时间 1次的就1 其次传秒
-    loadTime: loadTime, //load的时间没有就""
-    object: JSON.stringify(object), //执行信息传json
-    status: status //成功返回success。失败返回error的信息
-  };
-  console.log('params',params);
-  
-  axios
-    .post("https://pbl.cocorobo.cn/api/mongo/updateUserData2", [params])
-    .then(res => {
-      console.log('res',res);
-      if (res.status == 1) {
-        console.log("保存成功");
-      } else {
-        console.log("保存失败");
-      }
-    })
-    .catch(e => {
-      console.log("保存失败");
-      console.log(e);
-    });
-}
 const close = () => {
     show.value = false;
 }

+ 77 - 75
src/components/main/courseSelect.vue

@@ -39,7 +39,7 @@
             <img :src="getImageUrl(item.json.url)" alt="">
             <div class="course_content">
               <div class="div_title">
-                <span v-if="lang.lang != 'hk'">{{ lang.ssTermUp }}</span>
+                <span v-if="lang.lang != 'hk'">{{ activeterm ? lang.ssTermDown : lang.ssTermUp }}</span>
                   <el-tooltip class="item" effect="dark" :content="item.json.title" placement="top">
                     <div class="div_title_text">{{ item.json.title }}</div>
                   </el-tooltip>
@@ -272,10 +272,12 @@
   </el-dialog>
 
   <selectTeachingClassDialog 
-  ref="DialogRef" />
+  ref="DialogRef"
+  @openCourse="openCourseIframe" />
 
 </template>
 <script setup>
+import { addOp3 } from '@/mixins/mixin'
 import { ref, onMounted, watchEffect, inject } from 'vue';
 import { userCurrentRole, userInfoStore, userCurrent,pageGotype } from '../../stores/counter'
 // import JSZip from 'jszip';
@@ -288,6 +290,7 @@ import selectTeachingClassDialog from '../dialog/selectTeachingClassDialog.vue'
 // import { Value } from 'sass';
 // import { dataType } from 'element-plus/es/components/table-v2/src/common';
 import axios from 'axios';
+import { openCourseIframe } from '@/composables/useCourseIframe'
 
 const lang = inject('lang')
 
@@ -477,6 +480,7 @@ const openCourseDetail = (id) => {
   .then(res => {
     console.log('openCourseDetail',res)
     if (res.data[0].length > 0) {
+      return getCourseUrl(res.data[0][0])
       // let isSave = res.value[0].filter(x => {
       //   return x.courseId == id
       // })
@@ -502,52 +506,60 @@ const openCourseDetail = (id) => {
   .catch(err => {
     console.log(err)
   })
-  // 会返回复制得课程
-  // top.U.A.Request("https://pbl.cocorobo.cn/api/pbl/getcopyCourseByUseridSz", [id, user.user.userid], function (res) {
-  //   console.log(res)
-  //   if (res.value[0].length > 0) {
-  //     // let isSave = res.value[0].filter(x => {
-  //     //   return x.courseId == id
-  //     // })
-  //     //这个是打开指定的课程接口
-  //     	let url = '';
-	// 			if (lang.lang == 'hk') {
-	// 				url = "https://pbl.cocorobo.hk"
-	// 			}else if (lang.lang == 'en') {
-	// 				url = "https://pbl.cocorobo.com"
-	// 			}else{
-	// 				url = "https://pbl.cocorobo.cn"
-	// 			}
-  //     // https://pbl.cocorobo.cn/pbl-student-table/dist/#/courseDetail?userid=0c3735c9-a2ef-11ef-9b30-005056b86db5&oid=414f2361-ad04-11ed-b13d-005056b86db5&org=0fec3a8a-ad04-11ed-b13d-005056b86db5&courseId=91886917-2f3b-11f1-bcd9-005056924926&tType=1&cid=&screenType=2
-      
-  //     let url2 = `${url}/pbl-student-table/dist/#/courseDetail?userid=${user.user.userid}&oid=${user.user.organizeid}&org=${user.user.org}&courseId=${res.value[0][0].courseId}&tType=1&cid=&screenType=2`
-  //     // top.U.MD.D.I.openInApplication("studyDetail", res.value[0][0].courseId, 2, user.user.type);
-  //     top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
-  //   } else {
-  //     updateCourseId(id, "studyDetail")
-  //   }
-  // }, [], { "type": "POST", "withCredentials": true });
-
 }
+
+
+const getCourseUrl = (item) => {
+  // return console.log(item);
+  
+      let _str = ""
+      if(item.state == 1){
+        _str = "course_stageMode_open"
+      }if(item.state == 2){
+        _str = "course_taskMode_open"
+      }if(item.state == 3){
+        _str = "course_easyMode_open"
+      }if(item.state == 5){
+        _str = "course_aiMode_open"
+      }if(item.state == 6){
+        _str = "course_aiEasyMode_open"
+      }if(item.state == 7){
+        _str = "course_pptMode_open"
+      }
+      addOp3('1', "", { courseid: item.courseId, type: _str }, "success")
+
+      //  window.topU.postMessage({ cid: item.courseId, screenType: "3" }, "*");
+      // let url = 'https://beta.pbl.cocorobo.cn'
+      // if (window.location.href.includes('beta')) {
+      //   url = url
+      // }else if (lang.lang === 'cn') {
+      //   url = 'https://pbl.cocorobo.cn'
+      // }else if (lang.lang === 'hk') {
+      //   url = 'https://pbl.cocorobo.hk'
+      // }else if (lang.lang === 'en') {
+      //   url = 'https://pbl.cocorobo.com'
+      // }
+      let url = '';
+      if (lang.lang == 'hk') {
+        url = "https://pbl.cocorobo.hk"
+      }else if (lang.lang == 'en') {
+        url = "https://pbl.cocorobo.com"
+      }else{
+        url = "https://pbl.cocorobo.cn"
+      }
+      let url2 = `${url}/pbl-student-table/dist/#/courseDetail?userid=${user.user.userid}&oid=${user.user.organizeid}&org=${user.user.org}&courseId=${item.courseId}&tType=1&cid=&screenType=2`
+
+      openCourseIframe(url2)
+    }
 const getTimeCourse = (id, item) => {
   if (setIntervalNum.value) {
     clearInterval(setIntervalNum.value)
   }
   try {
     setIntervalNum.value = setInterval(() => {
-      axios.post('https://pbl.cocorobo.cn/api/pbl/addOperationTimeT', {userid: user.user.userid, id: id, type: '5', time: 30}, {
-        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-        withCredentials: true
-      })
-      .then(res => {
+      top.U.A.Request("https://pbl.cocorobo.cn/api/pbl/addOperationTimeT", [user.user.userid, id, '5', 30], function (res) {
         console.log(res, "22222222222222222");
-      })
-      .catch(err => {
-        console.log(err)
-      })
-      // top.U.A.Request("https://pbl.cocorobo.cn/api/pbl/addOperationTimeT", [user.user.userid, id, '5', 30], function (res) {
-      //   console.log(res, "22222222222222222");
-      // }, [], { "type": "POST", "withCredentials": true });
+      }, [], { "type": "POST", "withCredentials": true });
 
     }, 30000)
   } catch (e) {
@@ -561,7 +573,7 @@ const getTimeCourse = (id, item) => {
     dataType: 0,
     teacherName: user.user.name,
     teacherAccount: "",
-    eduId: Current.userCurrent.eduId,
+    eduId: user.user.eduid || user.user.sessionid,
     schoolName: user.user.schoolName,
     schoolType: "",
     area: "",
@@ -585,21 +597,6 @@ const getTimeCourse = (id, item) => {
     })
   }, interValtTime);
 }
-// const updateCourse = (id, item) => {
-//   // 会返回courseId和state 两个参数  然后打开
-//   getTimeCourse(id, item)
-//   top.U.A.Request("https://pbl.cocorobo.cn/api/pbl/getcopyCourseByUseridSz", [id, user.user.userid], function (res) {
-//     console.log(res)
-//     if (res.value[0].length > 0) {
-//       // let isSave = res.value[0].filter(x => {
-//       //   return x.courseId == id
-//       // })
-//       top.U.MD.D.I.openInApplication('openCourseNewUpdate', res.value[0][0].courseId); //这个是打开指定的课程接口
-//     } else {
-//       updateCourseId(id, "openCourseNewUpdate")
-//     }
-//   }, [], { "type": "POST", "withCredentials": true });
-// }
 
 const updateCourseId = (id, type) => {
   axios.post('https://pbl.cocorobo.cn/api/pbl/copyCourseSz', {id: id +','+ user.user.userid}, {
@@ -614,6 +611,24 @@ const updateCourseId = (id, type) => {
       if (type == "openCourseNewUpdate") {
         top.U.MD.D.I.openInApplication("openCourseNewUpdate", res.data[0][0].courseId)
       } else {
+
+        let _str = ""
+        if(res.data[0][0].state == 1){
+          _str = "course_stageMode_open"
+        }if(res.data[0][0].state == 2){
+          _str = "course_taskMode_open"
+        }if(res.data[0][0].state == 3){
+          _str = "course_easyMode_open"
+        }if(res.data[0][0].state == 5){
+          _str = "course_aiMode_open"
+        }if(res.data[0][0].state == 6){
+          _str = "course_aiEasyMode_open"
+        }if(res.data[0][0].state == 7){
+          _str = "course_pptMode_open"
+        }
+        addOp3('1', "", { courseid: res.data[0][0].courseId, type: _str }, "success")
+
+
         let url = '';
 				if (lang.lang == 'hk') {
 					url = "https://pbl.cocorobo.hk"
@@ -626,7 +641,8 @@ const updateCourseId = (id, type) => {
         
         let url2 = `${url}/pbl-student-table/dist/#/courseDetail?userid=${user.user.userid}&oid=${user.user.organizeid}&org=${user.user.org}&courseId=${res.data[0][0].courseId}&tType=1&cid=&screenType=2`
         // top.U.MD.D.I.openInApplication("studyDetail", res.value[0][0].courseId, 2, user.user.type);
-        top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
+        openCourseIframe(url2)
+        // top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
         // top.U.MD.D.I.openInApplication("studyDetail", res.value[0][0].courseId, 3, user.user.type);
       }
     }
@@ -776,16 +792,9 @@ const checkedAll = (id) => {
 const downloadOne = async (url, fileName) => {
   try {
     console.log("urls", [user.user.userid, getUpdateCourseId.value, '4', 1])
-    axios.post('https://pbl.cocorobo.cn/api/pbl/addOperationTimeT', {userid: user.user.userid, id: getUpdateCourseId.value, type: '4', time: 1}, {
-      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-      withCredentials: true
-    })
-    .then(res => {
+    top.U.A.Request("https://pbl.cocorobo.cn/api/pbl/addOperationTimeT", [user.user.userid, getUpdateCourseId.value, '4', 1], function (res) {
       console.log(res, '11111111111')
-    })
-    .catch(err => {
-      console.error("Error fetching data:", err);
-    });
+    }, [], { "type": "POST", "withCredentials": true });
   } catch (error) {
     console.log(error);
   }
@@ -845,16 +854,9 @@ const DownloadProcessing = async () => {
 
   try {
     console.log("urls", [user.user.userid, getUpdateCourseId.value, '4', urls.length])
-    axios.post('https://pbl.cocorobo.cn/api/pbl/addOperationTimeT', {userid: user.user.userid, id: getUpdateCourseId.value, type: '4', time: urls.length}, {
-      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
-      withCredentials: true
-    })
-    .then(res => {
+    top.U.A.Request("https://pbl.cocorobo.cn/api/pbl/addOperationTimeT", [user.user.userid, getUpdateCourseId.value, '4', urls.length], function (res) {
       console.log(res, '11111111111')
-    })
-    .catch(err => {
-      console.error("Error fetching data:", err);
-    });
+    }, [], { "type": "POST", "withCredentials": true });
   } catch (error) {
     console.log(error);
   }

+ 6 - 7
src/components/main/opendetail.vue

@@ -31,7 +31,7 @@
 					</div>
 				</div>
 			</template>
-			<div v-loading="pageloading">
+			<div v-loading="pageloading" style="height: 100%;">
 				<div class="fileArea2" @click="openDra" v-if="lang.lang != 'hk'">
 					<!-- <img src="../../assets/icon/filemr.svg" alt=""> -->
 				</div>
@@ -133,6 +133,7 @@
 
 <script setup>
 import { ref, inject } from "vue";
+import { openCourseIframe } from '@/composables/useCourseIframe'
 import "../../common/aws-sdk-2.235.1.min.js";
 import axios from "axios";
 
@@ -153,9 +154,6 @@ const imgPreview = ref({
 	img: "",
 	show: false,
 });
-// onMounted(() => {
-//     requestUser()
-// })
 const showPreviewImg = (e) => {
 
 	if (e.target.nodeName === "IMG") {
@@ -244,7 +242,6 @@ defineExpose({
 const openDra = () => {
 	drawer.value = true;
 };
-
 const openCourseDetail = () => {
 	let id = cid.value;
 	console.log(user.user);
@@ -275,7 +272,8 @@ const openCourseDetail = () => {
 				}
 				let url2 = `${url}/pbl-student-table/dist/#/courseDetail?userid=${user.user.userid}&oid=${user.user.organizeid}&org=${user.user.org}&courseId=${res.data[0][0].courseId}&tType=1&cid=&screenType=2`
 				// top.U.MD.D.I.openInApplication("studyDetail", res.value[0][0].courseId, 2, user.user.type);
-				top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
+				// top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
+				openCourseIframe(url2)
 				
 				// top.U.MD.D.I.openInApplication(
 				// 	"studyDetail",
@@ -320,7 +318,8 @@ const updateCourseId = (id, type) => {
 					}
 					let url2 = `${url}/pbl-student-table/dist/#/courseDetail?userid=${user.user.userid}&oid=${user.user.organizeid}&org=${user.user.org}&courseId=${res.data[0][0].courseId}&tType=${user.user.type}&cid=&screenType=2`
 					// top.U.MD.D.I.openInApplication("studyDetail", res.value[0][0].courseId, 2, user.user.type);
-					top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
+					// top.U.MD.D.I.openInApplication('setUrl',{url:url2,title:'课程详情',id:new Date().getTime()})
+					openCourseIframe(url2)
 
 					// top.U.MD.D.I.openInApplication(
 					// 	"studyDetail",

+ 15 - 0
src/composables/useCourseIframe.js

@@ -0,0 +1,15 @@
+import { ref } from 'vue'
+
+export const courseUrl = ref('')
+
+export function openCourseIframe(url) {
+  courseUrl.value = url
+}
+
+export function closeCourseIframe() {
+  courseUrl.value = ''
+}
+
+export function registerSetCourseUrl() {
+  window.setCourseUrl = closeCourseIframe
+}

+ 109 - 0
src/mixins/mixin.js

@@ -0,0 +1,109 @@
+import { userInfoStore } from '../stores/counter'
+import axios from 'axios'
+import qs from 'qs'
+export const myMixin = {
+  data() {
+    return {
+        userJson: {},
+        new_url: 'https://appapi.cocorobo.cn'
+    };
+  },
+  methods: {
+    detectBrowser() {
+      const ua = navigator.userAgent;
+
+      // 按优先级顺序检测
+      if (ua.includes("Edg/") || ua.includes("Edge/")) {
+        return "Microsoft Edge";
+      } else if (ua.includes("Firefox")) {
+        return "Mozilla Firefox";
+      } else if (ua.includes("Trident") || ua.includes("MSIE")) {
+        return "Internet Explorer";
+      } else if (ua.includes("360EE")) {
+        return "360 Browser (极速模式)";
+      } else if (ua.includes("360SE")) {
+        return "360 Browser (安全模式)";
+      } else if (ua.includes("SLBrowser")) {
+        return "QQ Browser";
+      } else if (ua.includes("UCBrowser")) {
+        return "UC Browser";
+      } else if (ua.includes("Opera") || ua.includes("OPR/")) {
+        return "Opera";
+      } else if (ua.includes("Chrome") && !ua.includes("Edg/")) {
+        return "Google Chrome";
+      } else if (ua.includes("Safari/") && !ua.includes("Chrome")) {
+        return "Safari";
+      } else {
+        return "Other Browser";
+      }
+    },
+    async addOp3(userTime, loadTime, object, status,api = 'selectUser') {
+      const user = userInfoStore()
+      if (!user.user.userid) return
+
+      try {
+        if(!this.userJson || !this.userJson.accountNumber){
+            let res = await axios.get(`https://pbl.cocorobo.cn/api/pbl/${api}?userid=`+user.user.userid)
+            this.userJson = res.data[0][0]
+        }
+      } catch (e) {
+        console.log(e);
+        return this.addOp3(userTime, loadTime, object, status,'selectUser2');
+      }
+      let _time = new Date()
+        .toLocaleString("zh-CN", { hour12: false, timeZone: "Asia/Shanghai" })
+        .replace(/\//g, "-");
+      let browser = this.detectBrowser();
+      const params = {
+        userid: user.user.userid,
+        username: this.userJson.username,
+        accountNumber: this.userJson.accountNumber,
+        org: this.userJson.orgName,
+        school: this.userJson.schoolName,
+        role: this.userJson.type =='1'?'老师':'学生',
+        browser: browser,
+        userTime: userTime == "1" ? _time : userTime, // 使用时间 1次的就1 其次传秒
+        loadTime: loadTime, //load的时间没有就“”
+        object: JSON.stringify(object), //执行信息传json
+        status: status //成功返回success。失败返回error的信息
+      };
+      console.log('params',params);
+     let encoded = {};
+
+      for (const key in params) {
+        if (Object.hasOwnProperty.call(params, key)) {
+          encoded[key] = encodeURIComponent(params[key]);
+        }
+      }
+      console.log('encoded',encoded);
+      // params = qs.stringify([encoded]) //序列化post 参数
+      axios
+        .post("https://pbl.cocorobo.cn/api/mongo/updateUserData2", [encoded], {
+          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+          withCredentials: true
+        })
+        .then(res => {
+          console.log('res',res);
+          if (res.data.status == 1) {
+            console.log("保存成功");
+          } else {
+            console.log("保存失败");
+          }
+        })
+        .catch(e => {
+          console.log("保存失败");
+          console.log(e);
+        });
+    }
+
+  }
+};
+
+export function addOp3(...args) {
+  const ctx = {
+    ...myMixin.data(),
+    detectBrowser: myMixin.methods.detectBrowser,
+    addOp3: myMixin.methods.addOp3,
+  }
+  return myMixin.methods.addOp3.call(ctx, ...args)
+}