Procházet zdrojové kódy

update:完整代码

En route před 1 rokem
rodič
revize
e80347e1a3

+ 10 - 1
src/App.vue

@@ -9,10 +9,19 @@ export default {
   name: "App",
   data() {
     return {
+      // isDesktop: false
     };
   },
+  mounted() {
+    // this.$store.dispatch("getCommonBaseHomeList");
+    // if (!this.$store.state.isDesktop) {
+    //   this.$request.getWeAppLink().then(res => {
+    //     res.msg && (window.location.href = res.msg);
+    //   });
+    // }
+  },
 };
 </script>
 
-<style>
+<style lang="scss" scoped>
 </style>

+ 61 - 6
src/axios.js

@@ -1,20 +1,37 @@
 import axios from 'axios'
 import store from './store'
-import { Notification, Message } from 'element-ui'
-export const BASE_URL = process.env.BASE_URL
+import { Notification, Message,MessageBox } from 'element-ui'
+export const BASE_URL = process.env.BASE_URL    //测试-外网
+// export const BASE_URL = "https://api.xyyxt.net"    //测试-外网
 export const BASE_IMG_URL = process.env.BASE_IMG_URL
+// export const BASE_IMG_URL = "https://file.xyyxt.net/"
 export const tenantId = process.env.TENANT_ID
 import tools from './common/tools'
 import router from './router'
+
+// 创建 axios 实例
 const request = axios.create({
   baseURL: BASE_URL,
-  timeout: 30000
+  timeout: 30000 // 请求超时时间
 })
+
+// 错误处理函数
 const err = (error) => {
   let { message } = error;
   if (axios.isCancel(error)) {
+    console.log('Request canceled', error.message);
   } else {
-    if (message == "Network Error") {
+    // 处理错误
+    if (error.response) {
+      const data = error.response.data
+      // const token = Vue.ls.get(ACCESS_TOKEN)
+      if (error.response.status === 403) {
+
+      }
+      if (error.response.status === 401) {
+
+      }
+    } else if (message == "Network Error") {
       message = "系统升级中";
       Message({
         message: message,
@@ -34,15 +51,17 @@ const err = (error) => {
   }
 }
 
+// request interceptor(请求拦截器)
 request.interceptors.request.use(config => {
   const token = tools.getToken()
   if (token && !config.noToken) {
-    config.headers['AuthorizationToken'] = 'WX ' + token
+    config.headers['AuthorizationToken'] = 'WX ' + token // 让每个请求携带自定义 token 请根据实际情况自行修改
   }
   config.headers['TenantId'] = store.state && store.state.TENANT_NANE ? store.state.TENANT_NANE : ""
   return config
 }, err)
 
+// response interceptor(接收拦截器)
 request.interceptors.response.use(async (response) => {
   const res = response.data
   const code = res.code || 200;
@@ -52,13 +71,21 @@ request.interceptors.response.use(async (response) => {
       let userAccount = tools.getUserAccount();
 
       if (!userAccount) {
+        // Message({
+        //   message: `登录失效,重新登录`,
+        //   type: "error",
+        // });
+
+        // setTimeout(() => {
         store.commit('setCurrentRouter', router.currentRoute)
         localStorage.removeItem('user_account')
         localStorage.removeItem('token')
         router.push({
           path: '/login'
         })
+
         return Promise.reject(res)
+        // }, 1000);
       } else {
         let res = await refreshToken(response.config)
         return res
@@ -78,6 +105,26 @@ request.interceptors.response.use(async (response) => {
       window.open(res.msg)
       return Promise.reject("自动跳转前往祥粤云学堂")
     } else if (code == 500) {
+      if (res.msg !== '无其他端在操作') {
+        // Message({
+        //   message: res.msg,
+        //   type: "error",
+        // });
+      }
+      // localStorage.removeItem('user_account')
+      // localStorage.removeItem('token')
+      // router.push({
+      //   path: '/login'
+      // })
+      return Promise.reject(res)
+    } else if (code == 601) {
+      MessageBox.confirm(res.msg, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        showCancelButton: false,
+        type: 'warning'
+      }).then(() => { }).catch(() => {
+      });
       return Promise.reject(res)
     } else {
       return Promise.reject(res)
@@ -103,7 +150,7 @@ async function refreshToken(response) {
     var userInfo = {
       url: '/app/user/getInfo',
       method: 'get',
-      params: { fromPlat: 2 },
+      params: { fromPlat: 2 }, // 来源平台 1小程序 2PC网站
     }
     const resUser = await request(userInfo)
     if (resUser.data.code === 200) {
@@ -114,12 +161,20 @@ async function refreshToken(response) {
     let onset = await request(response)
     return onset
   } else {
+    // Message({
+    //   message: `登录失效,重新登录`,
+    //   type: "error",
+    // });
+
+    // setTimeout(() => {
+
     localStorage.removeItem('user_account')
     localStorage.removeItem('token')
     store.commit('setCurrentRouter', router.currentRoute)
     router.push({
       path: '/login'
     })
+    // }, 1000);
   }
 }
 

+ 16 - 0
src/common/compress.js

@@ -1,8 +1,10 @@
+// 压缩前将file转换成img对象
 export const readImg = (file) => {
   return new Promise((resolve, reject) => {
     const img = new Image()
     const reader = new FileReader()
     reader.onload = function (e) {
+      console.log("源大小:",file.size)
       img.src = e.target.result
     }
     reader.onerror = function (e) {
@@ -17,20 +19,33 @@ export const readImg = (file) => {
     }
   })
 }
+
+/**
+ * 压缩图片
+ *@param img 被压缩的img对象
+* @param type 压缩后转换的文件类型
+* @param mx 触发压缩的图片最大宽度限制
+* @param mh 触发压缩的图片最大高度限制
+*/
 export const compressImg = (img, type, mx, mh) => {
+  console.log('压缩逻辑')
   return new Promise((resolve, reject) => {
     const canvas = document.createElement('canvas')
     const context = canvas.getContext('2d')
     const { width: originWidth, height: originHeight } = img
+    // 最大尺寸限制
     const maxWidth = mx
     const maxHeight = mh
+    // 目标尺寸
     let targetWidth = originWidth
     let targetHeight = originHeight
     if (originWidth > maxWidth || originHeight > maxHeight) {
       if (originWidth / originHeight > 1) {
+        // 宽图片
         targetWidth = maxWidth
         targetHeight = Math.round(maxWidth * (originHeight / originWidth))
       } else {
+        // 高图片
         targetHeight = maxHeight
         targetWidth = Math.round(maxHeight * (originWidth / originHeight))
       }
@@ -38,6 +53,7 @@ export const compressImg = (img, type, mx, mh) => {
     canvas.width = targetWidth
     canvas.height = targetHeight
     context.clearRect(0, 0, targetWidth, targetHeight)
+    // 图片绘制
     context.drawImage(img, 0, 0, targetWidth, targetHeight)
     canvas.toBlob(function (blob) {
       resolve(blob)

+ 112 - 13
src/common/tools.js

@@ -1,5 +1,7 @@
 import store from '@/store/index.js'
 import router from '@/router/index.js'
+import {BASE_IMG_URL} from '@/axios.js'
+
 import { JSEncrypt } from "jsencrypt";
 
 let publicKey = "-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4qkbwIKErstK1sFESPEhOShpRpj4+sOVpJHxl5r/2xLBfA/MrXcAEra5Ro9cXNQSqmLLt8wecoLk/glfa5IdhXV0hRVQplIVs5z3MxcUa9ptKPHUTgh8xMCBvl8sUJKwkmn4vYWeDfHT22EL7Hr1pTMwUhF6WiNlWfQTVoF1rhwIDAQAB-----END PUBLIC KEY-----"
@@ -13,13 +15,14 @@ export default {
 		return localStorage.getItem('user_account')
 	},
 
+	//图片路径填补
 	splitImgHost(url, scale = false, width = 250) {
 		if (!url) {
 			return ''
 		} else if (url.indexOf("http") != -1 || url.indexOf("https") != -1 || url.indexOf("wxfile") != -1) {
 
 		} else {
-			url = process.env.BASE_IMG_URL + url
+			url = BASE_IMG_URL + url
 		}
 		if (scale) {
 			url = url + "?x-oss-process=image/resize,w_" + width
@@ -28,6 +31,22 @@ export default {
 
 	},
 
+	exportData(msg) {
+		if (!msg) {
+			this.$message.warning("地址获取错误,请联系开发人员处理")
+			return
+		}
+		var baseUrl = BASE_IMG_URL + '/'
+		let url =
+			baseUrl + msg;
+		let link = document.createElement("a");
+		let fileName = "导入模板" + ".xlsx";
+		document.body.appendChild(link);
+		link.href = url;
+		link.download = fileName;
+		link.click();
+		link.remove();
+	},
 	isLogin() {
 		if (localStorage.getItem('user_account')) {
 			return true;
@@ -45,29 +64,36 @@ export default {
 	},
 
 	exit(isJ = true) {
+
 		localStorage.removeItem('user_account')
 		localStorage.removeItem('token')
 		sessionStorage.removeItem('uuid')
 		store.state.userInfo = null
-		if (router.currentRoute.path != '/home'&&isJ) {
+
+		if (router.currentRoute.path != '/home' && isJ) {
 			router.replace({
 				path: '/home'
 			})
 		}
+
 	},
+
+	//当前时间距离目标时间还有多久
 	GetRTime(EndTime, isDay = true) {
-		var EndTime = EndTime
-		var NowTime = new Date();
+		var EndTime = EndTime //结束时间
+		var NowTime = new Date(); //当前时间
+		//后台给我的是10位 精确到秒的 所有下面我就除以了1000,不要小数点后面的
 		var t = EndTime - (NowTime.getTime() / 1000).toFixed(0);
 		if (t <= 0) {
 			return '已结束'
 		}
-		var d = Math.floor(t / 60 / 60 / 24);
-		var h = Math.floor(t / 60 / 60 % 24);
-		var m = Math.floor(t / 60 % 60);
-		var s = Math.floor(t % 60);
+		//如果后台给的是毫秒 上面不用除以1000 下面的计算时间也都要除以1000 这里我去掉1000了
+		var d = Math.floor(t / 60 / 60 / 24); //天 var d=Math.floor(t/1000/60/60/24)
+		var h = Math.floor(t / 60 / 60 % 24); //时 var h=Math.floor(t/1000/60/60%24)
+		var m = Math.floor(t / 60 % 60); //分 var m=Math.floor(t/1000/60%60)
+		var s = Math.floor(t % 60); //秒 var s=Math.floor(t/1000%60)
 		if (parseInt(d) < 10) {
-			d = "0" + d;
+			// d = "0" + d;
 		}
 		if (parseInt(h) < 10) {
 			h = "0" + h;
@@ -93,6 +119,13 @@ export default {
 		tmp = tmp.substr(0, 10);
 		return tmp;
 	},
+
+	/**
+	* 
+   * @param {int} result 
+   * @returns {string}
+   * @remard 单位S转小时分钟秒
+   */
 	secondToTime(result, Diszing = true) {
 		var h = Math.floor(result / 3600) < 10 ? '0' + Math.floor(result / 3600) : Math.floor(result / 3600);
 		var m = Math.floor((result / 60 % 60)) < 10 ? '0' + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60));
@@ -104,11 +137,16 @@ export default {
 		}
 		return result;
 	},
+
+	/* 时间戳转换成日期
+	   * @param timestamp
+	   * @returns {*}
+	   */
 	timestampToTime(timestamp, isDay = true, hasChinese) {
 		if (!timestamp) {
 			return ''
 		}
-		var date = new Date(timestamp * 1000);
+		var date = new Date(timestamp * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
 		var Y = date.getFullYear() + (hasChinese ? '' : '-');
 		var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + (hasChinese ? '' : '-');
 		var D = date.getDate() < 10 ? '0' + date.getDate() + (hasChinese ? '' : ' ') : date.getDate() + (hasChinese ? '' : ' ');
@@ -116,18 +154,22 @@ export default {
 		var m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';
 		var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
 		if (isDay) {
+
 			if (hasChinese) {
 				return Y + '年' + M + '月' + D + '日';
 			} else {
 				return Y + M + D;
 			}
+
 		}
+
 		if (hasChinese) {
-			return Y + '年' + M + '月' + D + '日' + h + m + s;
+			return Y + '年' + M + '月' + D + '日 ' + h + m + s;
 		} else {
 			return Y + M + D + h + m + s;
 		}
 	},
+
 	secondToDate(result) {
 		var h = Math.floor(result / 3600) < 10 ? '0' + Math.floor(result / 3600) : Math.floor(result / 3600);
 		var m = Math.floor((result / 60 % 60)) < 10 ? '0' + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60));
@@ -139,9 +181,17 @@ export default {
 		}
 		return result;
 	},
+
 	getZeroTime() {
 		return Number(new Date(new Date().toLocaleDateString()).getTime() / 1000)
 	},
+
+	/**
+	 * 
+	 * @param {*} urlData 
+	 * @returns 
+	 * base64转formdata格式文件
+	 */
 	convertBase64UrlToBlob(urlData) {
 		var bytes = window.atob(urlData.split(",")[1]);
 		var ab = new ArrayBuffer(bytes.length);
@@ -151,9 +201,13 @@ export default {
 		}
 		return new Blob([ab], { type: "image/jpeg" });
 	},
+
+
 	imageToBase64(url, quality = 0.8) {
-		return new Promise(resolve => {
+		console.log(url, '1')
+		return new Promise((resolve, reject) => {
 			var image = new Image();
+			// 解决跨域 Canvas 污染问题,
 			image.setAttribute("crossorigin", "anonymous");
 			image.onload = function () {
 				var canvas = document.createElement("canvas");
@@ -161,12 +215,57 @@ export default {
 				canvas.height = image.height;
 				var context = canvas.getContext("2d");
 				context.drawImage(image, 0, 0, image.width, image.height);
-				var url = canvas.toDataURL("image/jpeg", quality);
+				var url = canvas.toDataURL("image/jpeg", quality); //将图片格式转为base64
+				console.log(url, '2')
+				console.log("success")
 				resolve(url)
 			};
+			image.onerror = function () {
+				console.log("error")
+				resolve(false)
+			};
 			image.src = url + "?time=" + Date.now();
 		})
+
+	},
+
+	//计算两个时间之间的时间差 多少天时分秒
+	intervalTime(startTime, endTime) {
+		// var timestamp=new Date().getTime(); //计算当前时间戳
+		var timestamp = (Date.parse(new Date())) / 1000;//计算当前时间戳 (毫秒级)
+		var date1 = ""; //开始时间
+		if (timestamp < startTime) {
+			date1 = startTime;
+		} else {
+			date1 = timestamp; //开始时间
+		}
+		var date2 = endTime; //结束时间
+		// var date3 = date2.getTime() - date1.getTime(); //时间差的毫秒数
+		var date3 = (date2 - date1) * 1000; //时间差的毫秒数
+		//计算出相差天数
+		var days = Math.floor(date3 / (24 * 3600 * 1000));
+		//计算出小时数
+		//2021-11-15 10:48:07 2021-11-15 17:34:39 406分钟
+		var leave1 = date3 % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
+		var hours = Math.floor(leave1 / (3600 * 1000));
+		//计算相差分钟数
+		var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
+		var minutes = Math.floor(leave2 / (60 * 1000));
+
+		//计算相差秒数
+
+		var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
+		var seconds = Math.round(leave3 / 1000);
+		console.log(days + "天 " + hours + "小时 ")
+		// return   days + "天 " + hours + "小时 " + minutes + " 分钟" + seconds + " 秒"
+		return days + "天 " + hours + "小时 "
 	},
+	/**
+	 * 
+	 * @param {*} data 
+	 * @returns 
+	 * 加密
+	 */
 	encryptor(data) {
 		let encryptor = new JSEncrypt();
 		encryptor.setPublicKey(publicKey);

+ 34 - 14
src/common/uploadFile.js

@@ -1,33 +1,53 @@
 import request from '@/request'
+// import { readImg, compressImg } from "./compress"
+import {compressAccurately} from 'image-conversion'
 export default {
-    upload: function (file, int) {
-        return new Promise((resolve, reject) => {
-            if(typeof file != 'object') {
-              resolve(file)
-              return;
+    // 上传图片标识 0头像 1身份证 2题库 3指南指引图片 4广告图片 5身份证或学信网图片 6文件excel,word,zip等
+    //file: 类似this.$refs.file.files[0]
+    upload: function (file, int, data,compressImgStatus = true) {
+        return new Promise(async (resolve, reject) => {
+            if (typeof file != 'object') {
+                resolve(file)
+                return;
             }
             var datas = {
-                imageStatus: int
+                imageStatus: int || 0,
+                ...data
+            }
+            //图片压缩
+            if (file.type.indexOf("image") !== -1 && compressImgStatus) {
+                file = await compressAccurately(file, 30)
+                // const img = await readImg(file)
+                // file = await compressImg(img, file.type, 256, 256) 
             }
             request.getPolicy(datas).then(res => {
                 var ossToken = res.data.resultContent
+                // const filename = file.name;
+                // const fileExtension = filename.split('.').pop().toLowerCase()
                 let formData = new FormData()
-                formData.append('key', ossToken.dir);
-                formData.append('OSSAccessKeyId', ossToken.accessid);
-                formData.append('policy', ossToken.policy);
-                formData.append('Signature', ossToken.signature);
-                formData.append('callback', ossToken.callback);
-                formData.append('success_action_status', 200);
+                // formData.append('key', ossToken.dir + "." + fileExtension); //存储在oss的文件路径
+                formData.append('key', ossToken.dir); //存储在oss的文件路径
+                formData.append('OSSAccessKeyId', ossToken.accessid); //accessKeyId
+                formData.append('policy', ossToken.policy); //policy
+                formData.append('Signature', ossToken.signature); //签名
+                formData.append('callback', ossToken.callback); //回调
+                formData.append('success_action_status', 200); //成功后返回的操作码
+                //如果是base64文件,那么直接把base64字符串转成blob对象进行上传就可以了
                 formData.append("file", file);
                 request.uploadFile(ossToken.host, formData).then(resp => {
-                    resolve(ossToken.dir)
+                    if (resp.resultContent && Number(resp.resultContent.size) > 0) {
+                        resolve(ossToken.dir)
+                    } else {
+                        reject("上传回调失败")
+                    }
                 }).catch(error => {
                     reject(error)
                 })
+
             }).catch(err => {
                 reject(err)
             })
         })
 
     },
-}
+}

+ 4 - 0
src/components/BaseDialog.vue

@@ -103,8 +103,12 @@ export default {
 
   watch: {
     visible(val) {
+      // 在此做显示与隐藏的交互
       if (val === false) {
         this.fullscreen = false;
+        // 重置操作
+      } else {
+        // 展示时操作
       }
     }
   }

+ 20 - 3
src/components/buyCourseModal/index.vue

@@ -83,7 +83,7 @@ export default {
   data() {
     return {
       selectClassModal: false,
-      copyDetail: [],
+      copyDetail: [], //备份
       provinceList: [],
       gradeList: [],
       gradeMap: new Map(),
@@ -91,7 +91,7 @@ export default {
       examineList: [],
       examArea: [],
       educationId: "",
-      sign: 0,
+      sign: 0, //是否继教七大员商品
       props: {
         lazy: true,
         lazyLoad: this.lazyLoad
@@ -127,6 +127,7 @@ export default {
     },
     selectClick(goodsDetail, type, status) {
       if (type == "class") {
+        //选择班级
         if (!goodsDetail.gradeList.length) {
           this.$request
             .goodsGradeList({ goodsId: goodsDetail.goodsId })
@@ -143,6 +144,7 @@ export default {
                   item =>
                     item.studentNum > 0 && item.studentNum == item.studentUpper
                 );
+                //所有班级都满了
                 if (isGradeFull) {
                   let item = {
                     className: "系统分班",
@@ -158,7 +160,9 @@ export default {
             });
         }
       } else if (type == "apply") {
+        //选择考试地点
       } else if (type == "exam") {
+        //选择考期
         this.$request
           .getExamineList({ projectId: goodsDetail.projectId })
           .then(res => {
@@ -218,6 +222,9 @@ export default {
         });
       }
     },
+    /**
+     * 获取所有省份
+     */
     getProvinceList() {
       this.$request.getProvinceList().then(res => {
         this.provinceList = res.rows.map(item => ({
@@ -228,7 +235,8 @@ export default {
       });
     },
     areaChange(row, index) {
-      let node = this.$refs["cascader" + index][0].getCheckedNodes()[0];
+      let node = this.$refs["cascader" + index][0].getCheckedNodes()[0]; //选中的根节点
+      console.log(node);
       row.applyAreas = {
         areaName: node.parent.label,
         areaId: node.parent.value,
@@ -239,6 +247,14 @@ export default {
     lazyLoad(node, resolve) {
       const { level } = node;
       if (level == 0) {
+        // this.$request.getProvinceList().then((res) => {
+        //   const nodes = res.rows.map((item) => ({
+        //     value: item.areaId,
+        //     label: `${item.areaName}`,
+        //     leaf: level >= 1,
+        //   }));
+        //   resolve(nodes);
+        // });
       } else if (level == 1) {
         this.$request.getCityList({ parentId: node.value }).then(res => {
           const nodes = res.rows.map(item => ({
@@ -264,6 +280,7 @@ export default {
 };
 </script>
 
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .select-class {
   &__content {

+ 68 - 20
src/components/dataReview/index.vue

@@ -206,8 +206,8 @@ export default {
       options: {},
       infoForm: {},
       rules: {},
-      historyData: {},
-      cacheIdCardData: {},
+      historyData: {}, //历史数据
+      cacheIdCardData: {}, //身份证数据
       nameDisabledStatus: false,
       idcardDisabledStatus: false,
       telphoneDisabledStatus: false,
@@ -216,8 +216,8 @@ export default {
       activeData: {},
       idcard_face_photo_old: "",
       recent_photos_old: "",
-      checkStatus: 0,
-      STATUS: false
+      checkStatus: 0, //是否审核通过才允许学习 1是0否
+      STATUS: false //区分个人中心入口操作
     };
   },
   computed: {
@@ -255,11 +255,23 @@ export default {
   methods: {
     async init(item, status = false) {
       this.STATUS = status;
+      console.log(item, "item");
       this.activeData = item;
+      //获取初始数据
+      try {
         await this.getInitData();
+        console.log("1");
+        //获取历史数据
         await this.getHistoricalRecord();
+        console.log("2");
         this.isShow = true;
+        //回填数据
         this.backFillData();
+        console.log("3");
+      } catch (error) {
+        console.log("4");
+        console.log("抛出:", error);
+      }
     },
     getInitData() {
       return new Promise((resolve, reject) => {
@@ -271,9 +283,10 @@ export default {
         };
         this.$request.getbaseprofiletpId(this.activeData.goodsId).then(res => {
           if (!res.data) {
+            //不需要填写
             this.isShow = false;
             this.$emit("callbackDataReview");
-            return reject("");
+            return reject("不需要填写");
           }
           let Ary = [
             ...JSON.parse(res.data.keyValue),
@@ -326,6 +339,7 @@ export default {
         });
       });
     },
+    //获取历史记录
     getHistoricalRecord() {
       return new Promise((resolve, reject) => {
         this.$request
@@ -335,6 +349,7 @@ export default {
           })
           .then(res => {
             if (!res.data) {
+              //提示填写规则
               this.$confirm(`请填写资料`, "温馨提示", {
                 confirmButtonText: "确定",
                 cancelButtonText: "取消",
@@ -366,13 +381,16 @@ export default {
                       resolve();
                     })
                     .catch(_ => {
+                      //停止执行-退出页面
                       this.$router.back(-1);
                     });
                 })
                 .catch(_ => {
+                  //停止执行-退出页面
                   this.$router.back(-1);
                 });
             } else if (res.data.status === 3 && res.data.changeStatus === 1) {
+              //资料审核不通过,请前往重新填写
               this.$confirm(`资料审核不通过,请前往重新填写`, "提示", {
                 confirmButtonText: "确定",
                 cancelButtonText: "返回",
@@ -385,28 +403,32 @@ export default {
                   this.historyData = Object.assign(
                     { id: res.data.id, text: res.data.text },
                     JSON.parse(res.data.keyValue)
-                  );
+                  ); //历史数据
                   resolve();
                 })
                 .catch(_ => {
+                  //停止执行-退出页面
                   this.$router.back(-1);
                 });
             } else if (this.STATUS) {
               this.historyData = Object.assign(
                 { id: res.data.id },
                 JSON.parse(res.data.keyValue)
-              );
+              ); //历史数据
               resolve();
             } else if (this.checkStatus == 1 && res.data.status !== 1) {
+              //后台设置需要审核通过才允许学习
               this.checkFunc();
             } else {
               this.isShow = false;
+              //不需要填写
               this.$emit("callbackDataReview");
-              return reject("");
+              return reject("不需要填写");
             }
           });
       });
     },
+    //回填数据
     backFillData() {
       if (Object.keys(this.historyData).length > 0 || this.historyData.id) {
         for (let i in this.historyData) {
@@ -532,8 +554,11 @@ export default {
         }
       }
     },
+    //审核通过才允许学习
     checkFunc() {
+      //后台设置需要审核通过才允许学习
       this.$confirm(
+        // `资料正在审核中,暂无法学习,请耐心等待!如需加急审核,请联系客服人员`,
         `您的资料预计2个工作日内完成审核,请耐心等待,审核通过再进入学习!`,
         "提示",
         {
@@ -546,15 +571,18 @@ export default {
         }
       )
         .then(_ => {
+          //停止执行-退出页面
           this.$router.back(-1);
         })
         .catch(_ => {
+          //停止执行-退出页面
           this.$router.back(-1);
         });
     },
+    //照片处理逻辑
     async uploadImg(e, item) {
       try {
-        let A = ["idcard_face_photo","idcard_national_photo"].indexOf(item);
+        let A = ["idcard_face_photo"].indexOf(item); //["idcard_face_photo","idcard_national_photo"]
         let file = await this.uploadRules(e.target.files[0]);
         if (A !== -1) {
           const res = await this.faceCertificationIDCardOCR(A + 1, file);
@@ -562,6 +590,7 @@ export default {
             this.$message.error(res.msg);
           } else {
             this.cacheIdCardData = res.data;
+            //身份证姓名身份证比对
             await this.idCardDataComparison();
             this.$set(this.infoForm, item, res.data.IdImgPath);
           }
@@ -578,12 +607,14 @@ export default {
         e.target.value = "";
       }
     },
+    //清空签名板
     retDraw() {
       this.$set(this.infoForm, "commitment_electr_signature", "");
       this.$nextTick(() => {
         this.$refs.esign[0].reset();
       });
     },
+    //校验及压缩
     uploadRules(file) {
       return new Promise((resolve, reject) => {
         const fileType = file.type;
@@ -609,16 +640,19 @@ export default {
         }
       });
     },
+    //身份证校验
     faceCertificationIDCardOCR(cardSide, file) {
       return new Promise(resolve => {
         var reader = new FileReader();
+        // 将文件加载进入
         reader.readAsDataURL(file);
         reader.onload = e => {
+          // 转换完成输出该文件base64编码
           let base64 = e.target.result;
 
           this.$request
             .faceCertificationIDCardOCR({
-              cardSide: cardSide,
+              cardSide: cardSide, //1人像  2 国徽
               cardImageBase64: base64,
               gradeId: this.activeData.gradeId
             })
@@ -631,6 +665,7 @@ export default {
         };
       });
     },
+    //身份证姓名身份证比对
     idCardDataComparison() {
       return new Promise((resolve, reject) => {
         if (
@@ -665,6 +700,7 @@ export default {
           let url = this.$tools.splitImgHost(res.msg);
           let name = res.msg.substring(res.msg.lastIndexOf("/") + 1);
           let image = new Image();
+          // 解决跨域 Canvas 污染问题,
           image.setAttribute("crossorigin", "anonymous");
           image.onload = function() {
             var canvas = document.createElement("canvas");
@@ -672,16 +708,18 @@ export default {
             canvas.height = image.height;
             var context = canvas.getContext("2d");
             context.drawImage(image, 0, 0, image.width, image.height);
-            var base64 = canvas.toDataURL("image/jpg");
-            var a = document.createElement("a");
-            var event = new MouseEvent("click");
-            a.download = name;
-            a.href = base64;
-            a.dispatchEvent(event);
+            var base64 = canvas.toDataURL("image/jpg"); //将图片格式转为base64
+            var a = document.createElement("a"); // 生成一个a元素
+            var event = new MouseEvent("click"); // 创建一个单击事件
+            a.download = name; // 设置图片名称
+            console.log(base64);
+            a.href = base64; // 将生成的URL设置为a.href属性
+            a.dispatchEvent(event); // 触发a的单击事件
           };
-          image.src = url
+          image.src = url + "?time=" + Date.now(); //注意,这里是灵魂,否则依旧会产生跨域问题
         });
     },
+    //将canvas签名生产oss地址
     subCanvas() {
       return new Promise((resolve, reject) => {
         const STATUS = this.listData.findIndex(
@@ -689,7 +727,7 @@ export default {
         );
         if (!this.infoForm["commitment_electr_signature"] && STATUS !== -1) {
           this.$refs.esign[0]
-            .generate()
+            .generate() // 使用生成器调用把签字的图片转换成为base64图片格式
             .then(async res => {
               let url = await this.$upload.upload(
                 this.convertBase64UrlToBlob(res),
@@ -702,6 +740,7 @@ export default {
               resolve();
             })
             .catch(err => {
+              console.log(err, "err");
               resolve();
             });
         } else {
@@ -709,9 +748,10 @@ export default {
         }
       });
     },
+    //canvas转file
     convertBase64UrlToBlob(urlData) {
-      var localData = urlData;
-      let base = atob(localData.substring(localData.indexOf(",") + 1));
+      var localData = urlData; //dataUrl为base64位
+      let base = atob(localData.substring(localData.indexOf(",") + 1)); // base是将base64编码解码,去掉data:image/png;base64部分
       let length = base.length;
       let url = new Uint8Array(length);
       while (length--) {
@@ -720,8 +760,10 @@ export default {
       let file = new File([url], "a.jpg", {
         type: "image/jpg"
       });
+      //最后将file,通过ajax请求做为参数传给服务器就可以了
       return file;
     },
+    //证件照与身份证匹配
     IdCardCompareFace() {
       return new Promise(async (resolve, reject) => {
         if (
@@ -781,9 +823,11 @@ export default {
       return JSON.stringify(Object.fromEntries(map));
     },
     async submitForm() {
+      //签名需在表单验证前执行完毕 否则会导致表单验证不通过
       await this.subCanvas();
       this.$refs["infoForm"].validate(async valid => {
         if (valid) {
+          //独立操作上传承诺书
           if (this.STATUS) {
             this.uploading = true;
             if (this.infoForm["commitment_seal"]) {
@@ -809,6 +853,7 @@ export default {
             }
             return;
           }
+          //end
           try {
             this.uploading = true;
             await this.idCardDataComparison();
@@ -827,6 +872,7 @@ export default {
                   this.$message.success("提交成功");
                   this.isShow = false;
                   if (this.checkStatus == 1) {
+                    //后台设置需要审核通过才允许学习
                     this.checkFunc();
                     return;
                   }
@@ -851,6 +897,7 @@ export default {
                   this.$message.success("提交成功");
                   this.isShow = false;
                   if (this.checkStatus == 1) {
+                    //后台设置需要审核通过才允许学习
                     this.checkFunc();
                     return;
                   }
@@ -867,6 +914,7 @@ export default {
             this.uploading = false;
           }
         } else {
+          console.log("error submit!!");
           return false;
         }
       });

+ 1 - 0
src/components/exam/HeaderTabBox.vue

@@ -35,6 +35,7 @@ export default {
       this.$request
         .bankExam(this.examId || this.$route.query.examId)
         .then((res) => {
+          console.log(res,666)
           this.examInfo = res.data;
         });
     }

+ 1 - 0
src/components/exercisesModal/index.vue

@@ -54,6 +54,7 @@ export default {
 };
 </script>
 
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .exercises-modal {
   &__content {

+ 3 - 1
src/components/footer1/index.vue

@@ -7,7 +7,8 @@
           <a
             v-for="(item, index) in showList(links)"
             :key="index"
-            :href="item.url"
+            :href="item.url ? item.url : 'javascript:;'"
+            target="_blank"
             >{{ item.name }}</a
           >
         </div>
@@ -21,6 +22,7 @@
         <a style="color:#e1e1e1;" target="_blank" :href="footer.miit">{{footer.icp}}</a>
         <p v-if="footer.technologyStatus == 1">技术支持:{{ footer.technology }}</p>
         <p v-if="footer.copyrightStatus == 1">版权所有:{{ footer.copyright }}</p>
+        <div v-html="footer.otherHtml"></div>
       </div>
     </div>
   </div>

+ 3 - 1
src/components/footer2/index.vue

@@ -49,7 +49,8 @@
         <a
           v-for="(item, index) in showList(links)"
           :key="index"
-          :href="item.url"
+          :href="item.url ? item.url : 'javascript:;'"
+          target="_blank"
           >{{ item.name }}</a
         >
         <div style="clear:both"></div>
@@ -66,6 +67,7 @@
         <a style="color:#e1e1e1;" target="_blank" :href="footer.miit">{{footer.icp}}</a>
         <p v-if="footer.technologyStatus == 1">技术支持:{{ footer.technology }}</p>
         <p v-if="footer.copyrightStatus == 1">版权所有:{{ footer.copyright }}</p>
+        <div v-html="footer.otherHtml"></div>
       </div>
     </div>
   </div>

+ 3 - 0
src/components/goodsItem-new/index.vue

@@ -46,6 +46,9 @@ export default {
     return {};
   },
   methods: {
+    /**
+     * 查看商品详情
+     */
     goodsDetail(res) {
       if (res.goodsType === 1) {
         this.$router.push({

+ 22 - 1
src/components/goodsItem/index.vue

@@ -2,6 +2,13 @@
   <div>
     <div class="course-item" @click="goodsDetail(item)">
       <div class="course-item__img">
+        <!-- <div
+          class="note"
+          :class="{ note__yellow: item.goodsType == 6 }"
+          v-if="item.year"
+        >
+          {{ item.year }}
+        </div> -->
         <img
           v-if="item.coverUrl"
           :src="$tools.splitImgHost(item.coverUrl)"
@@ -70,13 +77,17 @@ export default {
     return {
       selectClassModal: false,
       skuModal: false,
-      isCarOrBuy: 1
+      isCarOrBuy: 1 // 1加入购物车 2立即购买
     };
   },
   mounted() {},
   methods: {
     ...mapMutations(["setCurrentRouter", "getCartCount"]),
+    /**
+     * 查看商品详情
+     */
     goodsDetail(item) {
+      console.log(item, "items");
       this.getGoodsDetail(item.goodsId).then(res => {
         if (res.goodsType === 1) {
           this.$router.push({
@@ -110,14 +121,17 @@ export default {
         });
         return;
       }
+      // 判断有没有规格选择
       if (this.item.specTemplateId) {
         this.isCarOrBuy = 2;
         this.getSpecDetail();
+        // this.skuModal = true
         return;
       }
       this.toPayment(this.item.goodsId);
     },
     togoBuy(goodList) {
+      console.log();
       if (goodList.length == 1) {
         return this.toPayment(goodList[0].goodsId);
       }
@@ -125,6 +139,7 @@ export default {
     },
     toPayment(goodsId) {
       this.getGoodsDetail(goodsId).then(res => {
+        console.log(res, "res");
         if ((res.goodsType === 1 && res.templateType) || res.sevenYear) {
           this.$refs.selectClassModal.showModal(res);
         } else {
@@ -145,7 +160,11 @@ export default {
         path: "/payment"
       });
     },
+    /**
+     * 加入购物车
+     */
     addCart(item) {
+      // 判断有没有规格选择
       if (this.item.specTemplateId) {
         this.isCarOrBuy = 1;
         this.getSpecDetail();
@@ -207,6 +226,8 @@ export default {
   }
 };
 </script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .course-item {
   cursor: pointer;

+ 12 - 1
src/components/handoutItem/index.vue

@@ -2,6 +2,13 @@
   <div>
     <div class="course-item" @click="goodsDetail(item)">
       <div class="course-item__img">
+        <!-- <div
+          class="note"
+          :class="{ note__yellow: item.goodsType == 6 }"
+          v-if="item.year"
+        >
+          {{ item.year }}
+        </div> -->
         <img
           v-if="item.coverUrl"
           :src="$tools.splitImgHost(item.coverUrl)"
@@ -22,11 +29,14 @@ export default {
     return {
       selectClassModal: false,
       skuModal: false,
-      isCarOrBuy: 1
+      isCarOrBuy: 1 // 1加入购物车 2立即购买
     };
   },
   mounted() {},
   methods: {
+    /**
+     * 查看商品详情
+     */
     goodsDetail(item) {
       window.open(
         `/my-handout-detail/${item.goodsId}?orderGoodsId=${item.orderGoodsId}`,
@@ -37,6 +47,7 @@ export default {
 };
 </script>
 
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .course-item {
   cursor: pointer;

+ 101 - 0
src/components/header1/index.vue

@@ -39,6 +39,25 @@
         >
       </div>
       <div class="userinfo" v-if="userInfo">
+        <!-- <a class="msg" @click="go('/person-center/my-message')">
+          <i class="pi" v-if="msgCount > 0"></i>
+          <i class="el-icon-message-solid icon"></i>
+          <div @click.stop="" class="popover_style">
+            {{ msgData.text }} <el-button style="float:right;" type="text">立即学习</el-button>
+          </div>
+        </a> -->
+
+        <!-- <el-tooltip placement="bottom-end" v-model="msgShow" :hide-after="0" manual popper-class="tooltipStyle">
+          <el-badge :is-dot="msgCount > 0 ? true : false" class="item" style="vertical-align: baseline">
+            <el-button style="font-size: 20px; padding: 0px" icon="el-icon-message-solid" type="text"
+              @click="go('/person-center/my-message')"></el-button>
+          </el-badge>
+          <div slot="content" class="dis_plays">
+            <p style="max-width: 247px">{{ msgData.text }}</p>
+            <div class="toolbth" @click="newGoToStudy">立即学习</div>
+            <i style="font-size: 18px; cursor: pointer" class="el-icon-close" @click="clearMsg"></i>
+          </div>
+        </el-tooltip> -->
         <el-badge
           :is-dot="msgCount > 0 ? true : false"
           class="item"
@@ -128,6 +147,24 @@ export default {
   },
   mounted() {
     if (this.$tools.isLogin()) {
+      // this.$request.informUserselectLastUnStudyMsg().then((res) => {
+      //   if (res.data && res.data.id) {
+      //     let today = new Date(new Date().toLocaleDateString()).getTime();
+      //     if (localStorage.getItem("msg")) {
+      //       let ary = JSON.parse(localStorage.getItem("msg"));
+      //       if (ary.updateTime === today) {
+      //         this.msgShow = false;
+      //         return;
+      //       }
+      //     }
+      //     this.$nextTick(() => {
+      //       this.msgData = res.data;
+      //       this.msgShow = true;
+      //     });
+      //   } else {
+      //     this.msgShow = false;
+      //   }
+      // });
       this.getMsgCount();
     }
   },
@@ -150,6 +187,9 @@ export default {
         });
       });
     },
+    /**
+     * 关闭消息
+     */
     clearMsg() {
       let ary = {
         userId: this.msgData.userId,
@@ -159,6 +199,9 @@ export default {
       localStorage.setItem("msg", JSON.stringify(ary));
       this.msgShow = false;
     },
+    /**
+     * 前往学习
+     */
     async newGoToStudy() {
       let item = await this.getGoodsData();
       if (item.goodsType == 1) {
@@ -175,6 +218,10 @@ export default {
             }
           });
         });
+
+        // arsty = '立刻学习';
+
+        //题库
       } else if (item.goodsType == 2) {
         this.clearMsg();
         this.$router.push({
@@ -195,7 +242,11 @@ export default {
             let items = res.data;
             let currentTime = this.$tools.timest();
             if (items.interfaceAccountId > 0) {
+              //学习账号已开通
+
               if (items.learnStatus == 1) {
+                //跳转第三方h5
+
                 const confirmText = [
                   "您的学习账号已经开通,请按照步骤操作,进行学习。",
                   "1.点击【跳转学习网址】按钮",
@@ -231,6 +282,15 @@ export default {
                 return;
               }
             }
+            // //内部系统
+            // if (items.interfacePushId > 0 && items.officialStatus != 1) {
+            //   this.$message({
+            //     type: "warning",
+            //     message:
+            //       "机构正在为您报名中,请耐心等待,有疑问请联系020-87085982!",
+            //   });
+            //   return;
+            // }
             if (items.goodsType !== 6) {
               if (
                 this.sysTime <= items.serviceStartTime ||
@@ -291,17 +351,20 @@ export default {
                 return;
               }
             }
+            // if (item.educationName == "继续教育") {
             this.$request
               .lockLockStatus({
                 action: "jxjy"
               })
               .then(res => {
+                //有其他端在操作,不能学习
                 this.$message({
                   type: "warning",
                   message: res.msg
                 });
               })
               .catch(err => {
+                //可以学习
                 this.$request
                   .courseCourseList({
                     pageNum: 1,
@@ -320,9 +383,34 @@ export default {
                     }
                   });
               });
+
+            // } else {
+            //   this.$request
+            //     .courseCourseList({
+            //       pageNum: 1,
+            //       pageSize: 1,
+            //       goodsId: items.goodsId,
+            //       gradeId: items.gradeId,
+            //     })
+            //     .then((res) => {
+            //       if (res.rows.length) {
+            //         resolve(res);
+            //       } else {
+            //         this.$message({
+            //           type: "warning",
+            //           message: "课程内暂无可以学习的科目",
+            //         });
+            //       }
+            //     });
+            // }
           });
       });
     },
+
+    /**
+     * @param {Object} goodsId 商品id
+     * 查询商品重修状态
+     */
     courseGoodsRebuildStatus(goodsId, gradeId) {
       return new Promise(resolve => {
         this.$request
@@ -355,6 +443,12 @@ export default {
       }
     },
     go(path, query) {
+      // if (path === this.$route.path) {
+      //   this.$router.push({
+      //     path: "refresh" //refresh路由地址和当前要刷新路由地址同级即可
+      //   });
+      //   return;
+      // }
       this.$router.push({
         path,
         query
@@ -375,6 +469,7 @@ export default {
       let path = this.$route.path;
 
       if (path == "/bank-list") {
+        //在题库列表页面直接传参
         if (type == "2") {
           this.$emit("search", this.searchKey);
         } else if (type == "6") {
@@ -393,6 +488,7 @@ export default {
           });
         }
       } else if (path == "/course-list") {
+        //在课程列表页面直接传参
         if (type == "1") {
           this.$emit("search", this.searchKey);
         } else if (type == "6") {
@@ -411,6 +507,7 @@ export default {
           });
         }
       } else if (path == "/live-list") {
+        //在课程列表页面直接传参
         if (type == "6") {
           this.$emit("search", this.searchKey);
         } else if (type == "1") {
@@ -429,6 +526,8 @@ export default {
           });
         }
       } else {
+        //根据类型跳转题库或者列表页面
+        console.log(type);
         if (type == "1") {
           this.$router.push({
             path: "/course-list",
@@ -469,6 +568,8 @@ export default {
   }
 };
 </script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .header {
   position: relative;

+ 11 - 0
src/components/header2/index.vue

@@ -207,6 +207,7 @@ export default {
       let path = this.$route.path;
       let type = this.searchSelect;
       if (path == "/bank-list") {
+        //在题库列表页面直接传参
         if (type == "2") {
           this.$emit("search", this.searchKey);
         } else if (type == "6") {
@@ -225,6 +226,7 @@ export default {
           });
         }
       } else if (path == "/course-list") {
+        //在课程列表页面直接传参
         if (type == "1") {
           this.$emit("search", this.searchKey);
         } else if (type == "6") {
@@ -243,6 +245,7 @@ export default {
           });
         }
       } else if (path == "/live-list") {
+        //在课程列表页面直接传参
         if (type == "6") {
           this.$emit("search", this.searchKey);
         } else if (type == "1") {
@@ -261,6 +264,8 @@ export default {
           });
         }
       } else {
+        //根据类型跳转题库或者列表页面
+        console.log(type);
         if (type == "1") {
           this.$router.push({
             path: "/course-list",
@@ -306,6 +311,12 @@ export default {
       }
     },
     go(path, query) {
+      // if (path === this.$route.path) {
+      //   this.$router.push({
+      //     path: "refresh" //refresh路由地址和当前要刷新路由地址同级即可
+      //   });
+      //   return;
+      // }
       this.$router.push({
         path,
         query

+ 18 - 0
src/components/listOption1/index.vue

@@ -184,6 +184,7 @@ export default {
     }
   },
   methods: {
+    //获得商品类型
     computedName(type) {
       let name = "";
       switch (type) {
@@ -205,6 +206,7 @@ export default {
       }
       return name;
     },
+    //重置
     init() {
       this.params = {
         goodsName: "",
@@ -221,6 +223,7 @@ export default {
         pageSize: 15
       };
     },
+    //搜索
     search() {
       this.loading = true;
       this.$router.replace({ path: this.$route.path, query: this.params });
@@ -237,13 +240,18 @@ export default {
           this.loading = false;
         });
     },
+    //分页
     currentChange(e) {
       this.formData.pageNum = e;
       this.search();
     },
+    //排序
     activeSort(id) {
       this.params.sortType = id;
     },
+    /**
+     * 获取教育类型
+     */
     getEducationTypeList() {
       return new Promise(resolve => {
         this.$request
@@ -264,6 +272,7 @@ export default {
           });
       });
     },
+    //选中教育类型
     async activeEdu(id) {
       this.params.educationId = id;
       this.params.projectId = "";
@@ -276,6 +285,9 @@ export default {
         }
       }
     },
+    /**
+     * 获取业务层级
+     */
     getBusinessList() {
       return new Promise(resolve => {
         this.$request
@@ -284,12 +296,14 @@ export default {
             this.businessList = [
               { id: "", projectId: "", aliasName: "全部" }
             ].concat(res.rows);
+            console.log(this.businessList, "aa");
           })
           .finally(() => {
             resolve();
           });
       });
     },
+    //选中业务层级
     async activeBusiness(projectId, id) {
       this.params.projectId = projectId;
       this.params.businessId = id;
@@ -298,6 +312,9 @@ export default {
         await this.getSubjectList();
       }
     },
+    /**
+     * 获取科目分类
+     */
     getSubjectList() {
       return new Promise(resolve => {
         this.$request
@@ -317,6 +334,7 @@ export default {
           });
       });
     },
+    //选中科目分类
     activeSubject(id) {
       this.params.subjectId = id;
     }

+ 17 - 0
src/components/listOption2/index.vue

@@ -193,6 +193,7 @@ export default {
     }
   },
   methods: {
+    //获得商品类型
     computedName(type) {
       let name = "";
       switch (type) {
@@ -214,6 +215,7 @@ export default {
       }
       return name;
     },
+    //重置
     init() {
       this.params = {
         goodsName: "",
@@ -230,6 +232,7 @@ export default {
         pageSize: 12
       };
     },
+    //搜索
     search() {
       this.loading = true;
       this.$router.replace({ path: this.$route.path, query: this.params });
@@ -246,15 +249,20 @@ export default {
           this.loading = false;
         });
     },
+    //分页
     currentChange(e) {
       document.body.scrollTop = 300;
       document.documentElement.scrollTop = 300;
       this.formData.pageNum = e;
       this.search();
     },
+    //排序
     activeSort(id) {
       this.params.sortType = id;
     },
+    /**
+     * 获取教育类型
+     */
     getEducationTypeList() {
       return new Promise(resolve => {
         this.$request
@@ -275,6 +283,7 @@ export default {
           });
       });
     },
+    //选中教育类型
     async activeEdu(id) {
       this.params.educationId = id;
       this.params.projectId = "";
@@ -287,6 +296,9 @@ export default {
         }
       }
     },
+    /**
+     * 获取业务层级
+     */
     getBusinessList() {
       return new Promise(resolve => {
         this.$request
@@ -301,6 +313,7 @@ export default {
           });
       });
     },
+    //选中业务层级
     async activeBusiness(projectId, id) {
       this.params.projectId = projectId;
       this.params.businessId = id;
@@ -309,6 +322,9 @@ export default {
         await this.getSubjectList();
       }
     },
+    /**
+     * 获取科目分类
+     */
     getSubjectList() {
       return new Promise(resolve => {
         this.$request
@@ -328,6 +344,7 @@ export default {
           });
       });
     },
+    //选中科目分类
     activeSubject(id) {
       this.params.subjectId = id;
     }

+ 62 - 8
src/components/login/index.vue

@@ -127,6 +127,27 @@
                     ></div>
                   </template>
                 </el-tab-pane>
+                <!-- <el-tab-pane label="微信登录" name="wxLogin">
+                <div class="dis_flex">
+                  <img
+                    :src="
+                      imgUrl && !scanningStatus
+                        ? imgUrl
+                        : require('@/assets/qrcode.png')
+                    "
+                    alt=""
+                  />
+                  <p v-if="scanningStatus" style="color: red">小程序已扫码</p>
+                  <p class="headerTitle">使用微信扫一扫快捷登录</p>
+                  <p class="clickFuncStyle">
+                    扫描即表示同意<br /><span @click="innerVisibleOpenFunc(1)"
+                      >《用户使用协议》</span
+                    >及<span @click="innerVisibleOpenFunc(2)"
+                      >《个人信息保护政策》</span
+                    >
+                  </p>
+                </div>
+              </el-tab-pane> -->
               </el-tabs></el-form
             >
             <el-form
@@ -401,21 +422,23 @@ export default {
     const validateRegisAccept = (rule, value, callback) => {
       let _IDRe18 =
         /^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
-      if (!_IDRe18.test(value)) {
+      let _IDre15 =
+        /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/;
+      if (!_IDRe18.test(value) && !_IDre15.test(value)) {
         return callback(new Error("请输入正确身份证号码"));
       } else {
         callback();
       }
     };
     return {
-      checkTwoClassList: {},
-      checkDialogVisible: false,
-      showHk: false,
-      isPassing: false,
+      checkTwoClassList: {}, // 检查是否有二建班级10天过期
+      checkDialogVisible: false, // 检查是否有二建班级10天过期
+      showHk: false, // 是否展示滑块  点击登录按钮是 设置为true 同时隐藏登录按钮
+      isPassing: false, // 滑块状态
       checked: false,
       islogin: false,
       imgUrl: "",
-      scanningStatus: false,
+      scanningStatus: false, //扫码状态
       interValTime: null,
       interValupdate: null,
       scanCode: "",
@@ -466,6 +489,7 @@ export default {
   },
   beforeDestroy() {
     this.closeFunc();
+    console.log("销毁");
   },
   computed: {
     ...mapGetters(["userInfo"])
@@ -505,6 +529,9 @@ export default {
       });
     },
 
+    /**
+     * 注册
+     */
     registerFunc() {
       this.$refs.bindForm.validate((valid) => {
         if (valid) {
@@ -513,6 +540,7 @@ export default {
           this.$request
             .registerUser({ tel, code, pwd, idcard })
             .then((res) => {
+              //自动登录
               this.autoLogin();
             })
             .catch((err) => {
@@ -522,7 +550,9 @@ export default {
         }
       });
     },
-
+    /**
+     * 注册后自动登录并跳转绑定身份信息
+     */
     autoLogin() {
       let loginForm = JSON.parse(JSON.stringify(this.bindForm));
       var account = loginForm.tel;
@@ -547,6 +577,7 @@ export default {
           });
         });
     },
+    //注册
     signIn() {
       this.activeName = "signIn";
     },
@@ -609,9 +640,15 @@ export default {
         }
       });
     },
+    /**
+     * 查看协议
+     */
     innerVisibleOpenFunc(int) {
       this.$refs.agree.openBox(int, true);
     },
+    /**
+     * 更新二维码
+     */
     updateQRcode() {
       this.$request.pc_login_url().then((res) => {
         if (res.code === 200) {
@@ -622,6 +659,9 @@ export default {
         }
       });
     },
+    /**
+     * 获取用户登录信息
+     */
     getInfo() {
       this.$request
         .getInfo({ fromPlat: 2 })
@@ -629,7 +669,7 @@ export default {
           this.$store.commit("setUserInfo", res.data);
           this.$message.success("登录成功");
           this.closeFunc();
-          this.checkTenClassGradeUser();
+          this.checkTenClassGradeUser(); // 登陆成功后检查二建剩余时间
           this.dialogVisible = false;
         })
         .catch((err) => {
@@ -640,6 +680,9 @@ export default {
           });
         });
     },
+    /**
+     * 更新登入状态
+     */
     updateBackApi() {
       this.$request
         .check_login_url({
@@ -662,12 +705,18 @@ export default {
           }
         });
     },
+    /**
+     * 组件返回数据
+     */
     async backData(res) {
       localStorage.setItem("user_account", res.data.user_account);
       localStorage.setItem("token", res.data.token);
       this.$tools.setUuid(new Date().valueOf() + "");
       this.getInfo();
     },
+    /**
+     * 关闭方法合集
+     */
     closeFunc() {
       clearInterval(this.interValTime);
       clearInterval(this.interValupdate);
@@ -727,6 +776,7 @@ export default {
         }
       });
     },
+    // 滑块完成函数
     passcallback() {
       this.$message.success("校验成功");
       setTimeout(() => {
@@ -735,6 +785,9 @@ export default {
         this.loginSmsFormBack();
       }, 500);
     },
+    /**
+     * 获取验证码
+     */
     loginSmsFormBack() {
       var self = this;
       this.getRegisterCodeLock = true;
@@ -775,6 +828,7 @@ export default {
       this.activeName = "generalLogin";
       this.dialogVisible = true;
     },
+    // 检查是否有二建班级15天过期
     checkTenClassGradeUser() {
       this.$request
         .checkTenClassGradeUser()

+ 7 - 5
src/components/preference/index.vue

@@ -57,9 +57,9 @@ export default {
     return {
       dialogVisible: false,
       firstChoiceStatusBtn: false,
-      courseList: [],
-      courseMenu: [],
-      chapterIdList: []
+      courseList: [], //课程列表
+      courseMenu: [], //课程内容列表
+      chapterIdList: [] //选择的章内容
     };
   },
   inject: ["getGoodsData"],
@@ -88,6 +88,7 @@ export default {
     chapterClassHours(num) {
       return num ? (parseInt(num) / 60 / 45).toFixed(1) : 0;
     },
+    //一键选课
     quickGet() {
       let array = [];
       this.courseMenu.forEach(i => {
@@ -140,7 +141,7 @@ export default {
       });
     },
     async init() {
-      await this.getGoodsCourseList();
+      await this.getGoodsCourseList(); //获取商品课程列表
       this.$request
         .reMenuList({
           courseId: this.courseList[0].courseId,
@@ -156,8 +157,9 @@ export default {
             }
           });
           this.courseMenu = res.rows;
-        });
+        }); //获取课程内容
     },
+    //获取商品课程列表
     getGoodsCourseList() {
       return new Promise((resolve, reject) => {
         this.$request

+ 62 - 0
src/components/rebuildModal/index.vue

@@ -46,6 +46,18 @@
                     {{ index + 1 }}、{{ item.name }}
                   </div>
                   <div class="desc">
+                    <!-- <div class="imgs">
+                      <div
+                        class="img"
+                        v-for="(items, indexs) in item.userStudyRecordPhoto"
+                        :key="indexs"
+                      >
+                        <img :src="$tools.splitImgHost(items.photo)" />
+                        <div class="note">
+                          {{ $tools.timestampToTime(items.createTime, false) }}
+                        </div>
+                      </div>
+                    </div> -->
                   </div>
                   <div class="desc">
                     原因:
@@ -97,18 +109,29 @@ export default {
           this.showRebuildDetailModal = true;
 
           let sysTime = this.$tools.timest();
+          //学习服务期没过
           if (item.serviceEndTime && item.serviceEndTime > +sysTime) {
+            console.log(1);
             this.rebuildShow = true;
           } else {
+            //已过学习服务期
+            console.log(2);
             this.rebuildShow = false;
             this.showRebuildDetailModal = true;
             return;
           }
+          console.log(item.classEndTime, "item.classEndTime");
+          console.log(sysTime, "sysTime");
+          //有班级有效期
           if (item.classEndTime) {
+            //班级有效期没过
             if (item.classEndTime > +sysTime) {
+              console.log(3);
               this.rebuildShow = true;
             } else {
+              //已过班级有效期
               this.rebuildShow = false;
+              console.log(4);
               this.showRebuildDetailModal = true;
               return;
             }
@@ -133,12 +156,51 @@ export default {
           }
           this.showRebuildDetailModal = false;
           this.$emit("rebuildSubmit", this.rebuildItem);
+          // this.$router.push({
+          //   path: `/my-course-detail/${this.rebuildItem.goodsId}`,
+          //   query: {
+          //     gradeId: this.rebuildItem.gradeId,
+          //     orderGoodsId: this.rebuildItem.orderGoodsId,
+          //   },
+          // });
         });
+      // this.$confirm(
+      //   "如对审核结果有异议,请勿点击确认重学。致电020-87085982咨询",
+      //   "注意",
+      //   {
+      //     confirmButtonText: "确认重学",
+      //     cancelButtonText: "取消",
+      //     closeOnClickModal: false,
+      //     closeOnPressEscape: false,
+      //     distinguishCancelAndClose: false,
+      //     showClose: false,
+      //   }
+      // )
+      //   .then((_) => {
+      //     this.$request
+      //       .courseperiodrebuild({
+      //         goodsId: this.rebuildItem.goodsId,
+      //         gradeId: this.rebuildItem.gradeId,
+      //       })
+      //       .then((res) => {
+      //         this.showRebuildDetailModal = false;
+      //         this.$emit("rebuildSubmit", this.rebuildItem);
+      //         // this.$router.push({
+      //         //   path: `/my-course-detail/${this.rebuildItem.goodsId}`,
+      //         //   query: {
+      //         //     gradeId: this.rebuildItem.gradeId,
+      //         //     orderGoodsId: this.rebuildItem.orderGoodsId,
+      //         //   },
+      //         // });
+      //       });
+      //   })
+      //   .catch((_) => {});
     },
   },
 };
 </script>
 
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .rebuild {
   /deep/ .el-dialog__header {

+ 48 - 45
src/components/selectClassModal/index.vue

@@ -9,29 +9,31 @@
       <div>
         <el-radio-group v-model="gradeValue">
           <el-radio
-            v-for="(item, index) in gradeList"
-            :key="index"
-            class="radio"
-            :label="item.gradeId"
-            :disabled="
-              item.studentNumAll > 0 && item.studentNumAll == item.studentUpper
-            "
-          >
-            <div>
-              {{ item.className }}
-              <span v-if="item.classEndTime">
-                有效期至:{{
-                  $tools.timestampToTime(item.classEndTime, true, true)
-                }}</span
-              >
-              <span v-if="item.classEndTime"
-                >本班还剩{{
-                  $tools.GetRTime(item.classEndTime)
-                }}天将结束学习</span
-              >
-            </div></el-radio
-          >
+          v-for="(item, index) in gradeList"
+          :key="index"
+          class="radio"
+          :label="item.gradeId"
+          :disabled="
+            item.studentNumAll > 0 && item.studentNumAll == item.studentUpper
+          "
+        >
+          <div>
+            {{ item.className }}
+            <span v-if="item.classEndTime">
+              有效期至:{{
+                $tools.timestampToTime(item.classEndTime, true, true)
+              }}</span
+            >
+            <span v-if="item.classEndTime"
+              >本班还剩{{
+                $tools.GetRTime(item.classEndTime)
+              }}天将结束学习</span
+            >
+          </div>
+          <div></div
+        ></el-radio>
         </el-radio-group>
+        
       </div>
       <span slot="footer" class="dialog-footer">
         <el-button type="primary" @click="selectClassOk">确 定</el-button>
@@ -45,14 +47,14 @@ import { mapGetters } from "vuex";
 export default {
   name: "selectClassModal",
   computed: {
-    ...mapGetters(["userInfo"]),
+    ...mapGetters(["userInfo"])
   },
   data() {
     return {
       selectClassModal: false,
       gradeList: [],
       gradeValue: -1,
-      selectItem: {},
+      selectItem: {}
     };
   },
   mounted() {},
@@ -67,7 +69,7 @@ export default {
       if (this.gradeValue == -1) {
         this.$message({
           type: "success",
-          message: "请选择班级",
+          message: "请选择班级"
         });
         return;
       }
@@ -77,21 +79,21 @@ export default {
           gradeId: this.gradeValue,
           oldGradeId: this.selectItem.gradeId,
           orderGoodsId: this.selectItem.orderGoodsId,
-          userId: this.selectItem.userId,
+          userId: this.selectItem.userId
         })
-        .then((res) => {
+        .then(res => {
           this.selectClassModal = false;
           this.$message({
             type: "success",
-            message: "选班成功",
+            message: "选班成功"
           });
 
           this.$emit("selectClassOk");
         })
-        .catch((err) => {
+        .catch(err => {
           this.$message({
             type: "warning",
-            message: err.msg,
+            message: err.msg
           });
         });
     },
@@ -99,43 +101,44 @@ export default {
       let self = this;
       this.$request
         .goodsGradeList({
-          goodsId: id,
+          goodsId: id
         })
-        .then((res) => {
-          if (res.rows && res.rows.length > 0) {
-            res.rows = res.rows.filter((i) => {
-              return !(
-                i.studentNumAll > 0 && i.studentNumAll == i.studentUpper
-              );
-            });
+        .then(res => {
+          if(res.rows && res.rows.length > 0){
+            res.rows = res.rows.filter(i => {
+             return !(i.studentNumAll > 0 && i.studentNumAll == i.studentUpper)
+            })
           }
           self.gradeList = res.rows;
           if (self.gradeList.length == 0) {
             let item = {
               className: "系统分班",
-              gradeId: 0,
+              gradeId: 0
             };
             self.gradeList.push(item);
           } else {
             let isGradeFull = self.gradeList.every(
-              (item) =>
-                item.studentNumAll > 0 &&
-                item.studentNumAll == item.studentUpper
+              item =>
+                item.studentNumAll > 0 && item.studentNumAll == item.studentUpper
             );
+            //所有班级都满了
             if (isGradeFull) {
               let item = {
                 className: "系统分班",
-                gradeId: 0,
+                gradeId: 0
               };
               self.gradeList.unshift(item);
             }
           }
+          //自动选中第一个
           self.gradeValue = self.gradeList[0].gradeId;
         });
-    },
-  },
+    }
+  }
 };
 </script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped lang="scss">
 .select-modal {
   .radio {

+ 21 - 4
src/components/takePicture/index.vue

@@ -68,12 +68,12 @@
 export default {
   data() {
     return {
-      successOpen:false,
+      successOpen:false,//是否授权拍照
       takePhotoModal: false,
       isTaking: true,
       loading: false,
       faceUrl: "",
-      photoBadStatus:false,
+      photoBadStatus:false,//摄像头无法使用触发true
     };
   },
   methods: {
@@ -96,6 +96,7 @@ export default {
           window.navigator.webkitGetUserMedia ||
           window.navigator.mozGetUserMedia
         ) {
+          // 调用用户媒体设备, 访问摄像头
           this.getUserMedia(
             {
               video: {
@@ -111,17 +112,22 @@ export default {
         }
       });
     },
+    //成功读取摄像头
     photographSuccess(stream) {
+      // 兼容webkit核心浏览器
+      // --虚拟摄像头
       if (this.isVirtualCamera(stream)) {
         return;
       }
       this.successOpen = true
       this.$nextTick(() => {
         const video = document.getElementById("video");
+        // 将视频流设置为video元素的源
         video.srcObject = stream;
         video.play().catch(() => {});
       });
     },
+    //未读取到摄像头 兼容webkit核心浏览器
     isVirtualCamera(stream) {
       const list = [
         "VCam",
@@ -135,7 +141,7 @@ export default {
         return stream.getTracks()[0].label.indexOf(e) != -1;
       });
       if (isT) {
-        this.photoBadStatus = true;
+        this.photoBadStatus = true; //摄像头无法使用触发true
         this.$confirm("检测到你使用虚拟摄像头,无法继续学习。", "提示", {
           confirmButtonText: "返回",
           showConfirmButton: true,
@@ -150,8 +156,9 @@ export default {
       }
       return isT;
     },
+    //未读取到摄像头
     photographError(err) {
-      this.photoBadStatus = true;
+      this.photoBadStatus = true; //摄像头无法使用触发true
       this.$confirm(
         "课程学习需要开启摄像头进行拍照,经检测您的设备无摄像头可使用,请检测环境是否支持。",
         "提示",
@@ -168,21 +175,27 @@ export default {
         this.$router.back(-1);
       });
     },
+    // 调用用户媒体设备, 访问摄像头
     getUserMedia(constraints, success, error) {
       if (window.navigator.mediaDevices.getUserMedia) {
+        // 最新的标准API
         window.navigator.mediaDevices
           .getUserMedia(constraints)
           .then(success)
           .catch(error);
       } else if (window.navigator.webkitGetUserMedia) {
+        // webkit核心浏览器
         window.navigator.webkitGetUserMedia(constraints, success, error);
       } else if (window.navigator.mozGetUserMedia) {
+        // firfox浏览器
         window.navigator.mozGetUserMedia(constraints, success, error);
       } else if (window.navigator.getUserMedia) {
+        // 旧版API
         window.navigator.getUserMedia(constraints, success, error);
       }
     },
 
+    //判断是全屏则退出全屏
     isFullScreen() {
       if (!!(document.webkitIsFullScreen || this.fullele())) {
         try {
@@ -206,6 +219,7 @@ export default {
         null
       );
     },
+    //拍照
     onPhoto() {
       const canvas = document.createElement("canvas");
       canvas.width = 400;
@@ -216,6 +230,7 @@ export default {
       this.faceUrl = canvas.toDataURL("image/png");
       this.isTaking = false;
     },
+    //重拍-重置拍照
     reTake() {
       this.faceUrl = "";
       this.isTaking = true;
@@ -226,6 +241,7 @@ export default {
         }
       });
     },
+    //确认拍照
     async takeOk() {
       this.loading = true;
       this.$emit("returnParameter", this.faceUrl);
@@ -272,6 +288,7 @@ export default {
   }
 
   &__body {
+    // height: 400px;
     padding: 40px 24px;
 
     .left-box {

+ 206 - 90
src/components/videoCy/index.vue

@@ -33,29 +33,29 @@ export default {
       type: Object,
       default: () => {
         return {};
-      },
+      }, //当前节数据
     },
   },
   data() {
     return {
       vodPlayerJs: "https://player.polyv.net/script/player.js",
       player: null,
-      HideVideo: false,
-      photoList: [],
-      photoHistoryList: [],
-      photoIndex: 0,
-      showRecordStatus: false,
-      showRecordSetTimeOut: null,
-      openPhotoStatus: 0,
-      commitTime: null,
-      commitTimePhoto: null,
-      timeEventStatus: false,
-      timeEventStatusTimeout: null,
-      videoPauseSetTimeout: null,
-      failToRegister: false,
+      HideVideo: false, //是否隐藏播放器
+      photoList: [], //抓拍时间拍照数组
+      photoHistoryList: [], //历史和已拍照数据
+      photoIndex: 0, //当前拍照对应索引
+      showRecordStatus: false, //是否显示从头播放提示
+      showRecordSetTimeOut: null, //从头播放提示计时器函数
+      openPhotoStatus: 0, //暂存学习状态
+      commitTime: null, //暂存时间-节流
+      commitTimePhoto: null, //判断拍照时刻-节流
+      timeEventStatus: false, //双重保障状态
+      timeEventStatusTimeout: null, //双重保障定时器
+      videoPauseSetTimeout: null, //定时器停留太久触发
+      failToRegister: false, //报名推送不通过
       videoPauseSetTimeStatus: false,
       player_tencent: null,
-      firstPlay: true,
+      firstPlay: true, //是否初次播放
       viewSign: null,
     };
   },
@@ -65,9 +65,17 @@ export default {
     },
   },
   watch: {
+    // HideVideo: function(newVal, oldVal) {
+    //   if (newVal) {
+    //     document.getElementById("player-tencent").setAttribute("style","visibility:hidden");
+    //   } else {
+    //     document.getElementById("player-tencent").setAttribute("style","visibility:visible");
+    //   }
+    // },
+    //因为刚开始获取不到goodsData的数据 所以需要监听
     goodsData: function (newVal, oldVal) {
       if (newVal) {
-        this.getBeforeWork();
+        this.getBeforeWork(); //处理前置任务
       }
     },
   },
@@ -75,7 +83,9 @@ export default {
     if (!window.polyvPlayer) {
       const myScript = document.createElement("script");
       myScript.setAttribute("src", this.vodPlayerJs);
-      myScript.onload = () => {};
+      myScript.onload = () => {
+        console.log("加载成功");
+      };
       document.body.appendChild(myScript);
     }
   },
@@ -87,20 +97,20 @@ export default {
           this.player.HTML5.video.removeEventListener(
             "timeupdate",
             this.timeEvent
-          );
-        this.player.destroy();
+          ); //监听器
+        this.player.destroy(); //初始化播放器
       }
       if (this.player_tencent) {
-        this.player_tencent.dispose();
+        this.player_tencent.dispose(); //初始化播放器
       }
-      this.initData();
-      await this.getRecordHistoryPhoto();
-      await this.getRecordLast();
+      this.initData(); //初始化参数
+      await this.getRecordHistoryPhoto(); //获取拍照历史记录
+      await this.getRecordLast(); //获取播放记录
       let viewSign = this.viewSign || 1;
       if (viewSign == 2) {
-        await this.loadPlayer_tencent();
+        await this.loadPlayer_tencent(); //加载播放内容
       } else {
-        await this.loadPlayer();
+        await this.loadPlayer(); //加载播放内容
       }
       this[viewSign == 2 ? "player_tencent" : "player"].on(
         viewSign == 2 ? "loadstart" : "s2j_onPlayerInitOver",
@@ -108,23 +118,38 @@ export default {
           this[viewSign == 2 ? "player_tencent" : "player"].on(
             viewSign == 2 ? "pause" : "s2j_onVideoPause",
             this.onVideoPause
-          );
+          ); //视频暂停时触发
+          // this[viewSign == 2 ? "player_tencent" : "player"].on(
+          //   viewSign == 2 ? "playing" : "s2j_onVideoPlay",
+          //   this.onVideoPlay
+          // );
           if (viewSign == 2) {
             this.player_tencent.on("playing", this.onVideoPlay);
           } else {
             this.player.on("s2j_onPlayStart", this.onVideoPlay);
             this.player.on("s2j_onVideoPlay", this.onVideoPlay);
           }
+          //视频播放或由暂停恢复播放时触发
           this[viewSign == 2 ? "player_tencent" : "player"].on(
             viewSign == 2 ? "ended" : "s2j_onPlayOver",
             this.onPlayOver
-          );
+          ); //当前视频播放完毕时触发
+
+          // this[viewSign == 2 ? "player_tencent" : "player"].on(
+          //   viewSign == 2 ? "error" : "s2j_onPlayerError",
+          //   this.onPlayerError
+          // ); //播放出现错误时触发
+          if (viewSign != 2) {
+            this.player.on("serverError", this.serverError); //发生业务逻辑错误时触发,比如授权验证失败、域名黑白名单验证不通过等错误。参数返回事件名称和错误代码。
+          }
         }
-      );
+      ); //播放器初始化完毕时触发。播放器提供的方法需要在此事件发生后才可以调用。
     });
+    // document.addEventListener("visibilitychange", this.pauseVideo);
   },
   methods: {
     getBeforeWork() {},
+    //初始化参数
     initData() {
       this.timeEventStatus = false;
       this.commitTime = null;
@@ -132,9 +157,10 @@ export default {
       this.openPhotoStatus = 0;
       this.videoPauseSetTimeStatus = false;
       this.firstPlay = true;
-      clearTimeout(this.videoPauseSetTimeout);
-      clearTimeout(this.timeEventStatusTimeout);
+      clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
+      clearTimeout(this.timeEventStatusTimeout); //删除双重保障定时器
     },
+    //获取播放记录
     getRecordLast() {
       return new Promise((resolve) => {
         clearTimeout(this.showRecordSetTimeOut);
@@ -159,6 +185,7 @@ export default {
         });
       });
     },
+    //从头播放
     seekVideo0() {
       if (this.viewSign == 2) {
         this.player_tencent.currentTime(0);
@@ -167,6 +194,7 @@ export default {
       }
       this.showRecordStatus = false;
     },
+    //获取拍照历史记录
     getRecordHistoryPhoto() {
       return new Promise((resolve) => {
         var data = {
@@ -179,10 +207,12 @@ export default {
           moduleId: this.activeSection.moduleId,
         };
         this.$request.getPhotoLastRecord(data).then((res) => {
+          //清空历史数据
           this.photoList = [];
           this.photoHistoryList = [];
           this.photoIndex = 0;
           for (let i = 0; i < res.data.length; i++) {
+            //-2存储随机拍照数组
             if (res.data[i].photoIndex == -2 && res.data[i].timeInterval) {
               this.photoList = res.data[i].timeInterval.split(",");
             } else {
@@ -193,20 +223,26 @@ export default {
         });
       });
     },
+    //计算拍照逻辑
     photoLogic() {
-      if (this.photoList.length > 0 || this.activeSection.learning == 1) return;
+      if (this.photoList.length > 0 || this.activeSection.learning == 1) return; //已从历史拍照数据获得
       if (this.viewSign == 2) {
         var polyvPlayerContext = this.player_tencent;
         var totalVideoTime = polyvPlayerContext.duration();
-        var duration = polyvPlayerContext.currentTime() || 0;
+        var duration =
+          Number(this.activeSection.videoCurrentTime) ||
+          polyvPlayerContext.currentTime() ||
+          0;
       } else {
         var polyvPlayerContext = this.player;
         var totalVideoTime = polyvPlayerContext.j2s_getDuration();
-        var duration = polyvPlayerContext.j2s_getCurrentTime() || 0;
+        var duration =
+          Number(this.activeSection.videoCurrentTime) ||
+          polyvPlayerContext.j2s_getCurrentTime();
       }
       if (this.goodsData.erJianErZao) {
         this.photoList = this.randomConfig(totalVideoTime, duration);
-      } else if (this.goodsData.jjShiGongYuan) {
+      } else if (this.goodsData.jjShiGongYuan && this.goodsData.orderYears) {
         this.photoList = this.ShiPhotoList(totalVideoTime, duration);
       } else if (this.goodsData.goodsPhotographConfig.photoNum > 0) {
         this.photoList = this.getPhotoList(
@@ -214,36 +250,43 @@ export default {
           this.goodsData.goodsPhotographConfig.photoNum
         );
       }
+      //兼容已有观看历史
       for (let i = 0; i < this.photoList.length - 1; i++) {
         if (this.photoList[i] < duration && this.photoList[i + 1] > duration) {
           this.photoIndex = i + 1;
           break;
         }
         if (duration > this.photoList[this.photoList.length - 1]) {
-          this.photoIndex = this.photoList.length - 1;
+          this.photoIndex = this.photoList.length - 1; //取最后一个下标
           break;
         }
       }
     },
+    //普通拍照
     getPhotoList(totalVideoTime, photoNum) {
       let photoList = [];
       if (totalVideoTime >= 900) {
+        //大于15分钟
         if (photoNum == 1) {
+          //开头拍1张
           photoList.push(1);
         } else if (photoNum == 3) {
-          photoList.push(0);
-          let centerTime = Math.floor(totalVideoTime / 2);
-          let centerMinTime = centerTime - 300;
+          //拍3张
+          photoList.push(0); //开头拍一张
+          let centerTime = Math.floor(totalVideoTime / 2); //获取中间时间
+          let centerMinTime = centerTime - 300; //前后5分钟
           let centerMaxTime = centerTime + 300;
           let centerTakeTime = this.randomNum(centerMinTime, centerMaxTime);
-          photoList.push(centerTakeTime);
+          photoList.push(centerTakeTime); //中间拍一张
           let endMaxTime = totalVideoTime - 60;
           let endMinTime = totalVideoTime - 300;
           let endTakeTime = this.randomNum(endMinTime, endMaxTime);
-          photoList.push(endTakeTime);
+          photoList.push(endTakeTime); //最后拍一张
         }
       } else {
+        //小于15分钟,只拍前后各一张
         if (photoNum == 1) {
+          //开头拍1张
           photoList.push(1);
         } else if (photoNum == 3) {
           photoList.push(1);
@@ -259,16 +302,18 @@ export default {
           photoList.push(endTakeTime);
         }
       }
-      this.postCoursePhotoRecord(true);
+      this.postCoursePhotoRecord(true); //提交随机拍照时间数组
       return photoList;
     },
+    //施工继教
     ShiPhotoList(totalVideoTime) {
+      //施工继教带年份的订单拍照设置
       if (totalVideoTime < 2760) {
-        var time1 = 46 * 60 - 1;
+        var time1 = 46 * 60 - 1; //拍照间隔多久一张 46分钟
       } else {
-        var time1 = 45 * 60 - 1;
+        var time1 = 45 * 60 - 1; //拍照间隔多久一张 45分钟
       }
-      let num = Math.ceil(totalVideoTime / time1);
+      let num = Math.ceil(totalVideoTime / time1); //拍照数量
       let photoList = [];
       if (num == 1) {
         photoList.push(parseInt(totalVideoTime / 2));
@@ -279,6 +324,8 @@ export default {
       }
       return photoList;
     },
+
+    // 随机拍摄时间(二建)
     randomConfig(totalVideoTime, duration) {
       this.photoHistoryList = [];
       let photoList = [duration];
@@ -294,6 +341,7 @@ export default {
       }
       return photoList;
     },
+    //postTime = true 只提交随机时间 false 提交拍照
     postCoursePhotoRecord(postTime = false, photoUrl) {
       return new Promise((resolve, reject) => {
         if (this.viewSign == 2) {
@@ -311,7 +359,7 @@ export default {
           sectionId: this.activeSection.sectionId,
           photo: postTime ? "" : photoUrl,
           photoTime: parseInt(currentTime > 0 ? currentTime : 0),
-          photoIndex: postTime ? -2 : parseInt(this.photoIndex),
+          photoIndex: postTime ? -2 : parseInt(this.photoIndex), //从0算起,-2只提交随机时间
           photoNum: parseInt(this.goodsData.goodsPhotographConfig.photoNum),
           timeInterval: postTime ? this.photoList.join(",") : "",
         };
@@ -325,16 +373,21 @@ export default {
           });
       });
     },
+    //随机拍摄时间
     randomNum(minNum, maxNum) {
       switch (arguments.length) {
         case 1:
           return parseInt(Math.random() * minNum + 1, 10);
+          break;
         case 2:
           return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
+          break;
         default:
           return 0;
+          break;
       }
     },
+    // 播放视频
     loadPlayer() {
       return new Promise((resolve) => {
         var self = this;
@@ -361,30 +414,31 @@ export default {
               wrap: "#player",
               width: 810,
               height: 455,
-              preventKeyboardEvent: true,
-              showLine: true,
-              ban_history_time: "on",
+              preventKeyboardEvent: true, //是否屏蔽键盘事件,为true时屏蔽。
+              showLine: true, //是否显示线路选择按钮
+              ban_history_time: "on", //是否禁用续播功能,取值:{on,off}。
               vid: self.activeSection.recordingUrl,
-              autoplay: autoPlay,
-              ban_seek: isAllowSeek,
-              speed: playbackRate,
-              teaser_show: 1,
-              tail_show: 1,
-              hideSwitchPlayer: true,
-              watchStartTime: self.activeSection.videoCurrentTime || 0,
-              ts: res.data.ts,
-              sign: res.data.sign,
+              autoplay: autoPlay, //	是否自动播放。
+              ban_seek: isAllowSeek, //是否禁止拖拽进度条,取值:{on,off}。
+              speed: playbackRate, //当speed参数值为boolean类型时,代表是否显示倍速切换的按钮。
+              teaser_show: 1, //是否播放片头:0 不播放,1 播放。片头可在管理后台进行设置。
+              tail_show: 1, //是否播放片尾:0 不播放,1 播放。片尾可在管理后台进行设置。
+              hideSwitchPlayer: true, //是否隐藏H5和Flash播放器的切换按钮。
+              watchStartTime: self.activeSection.videoCurrentTime || 0, // 播放开始时间,表示视频从第几秒开始播放,参数值需小于视频时长。
+              ts: res.data.ts, //移动播放加密视频需传入的时间戳。
+              sign: res.data.sign, //移动端播放加密视频所需的签名。
               playsafe: function (vid, next) {
                 self.$request.obtainpolyvvideopcsign(vid).then((res) => {
                   next(res.data);
                 });
-              },
+              }, //PC端播放加密视频所需的授权凭证。
             });
-            self.$emit("videoScript", this.player);
+            self.$emit("videoScript", this.player); //抛出播放实例
             resolve();
           });
       });
     },
+    //播放视频-腾讯
     loadPlayer_tencent() {
       return new Promise(async (resolve) => {
         try {
@@ -424,25 +478,34 @@ export default {
               progressControl: isAllowSeek,
               playbackRateMenuButton: playbackRate,
             },
-            fileID: this.activeSection.recordingUrl,
-            appID: data.appID,
-            licenseUrl: data.licenseUrl,
+            // player-tencent 为播放器容器 ID,必须与 html 中一致
+            fileID: this.activeSection.recordingUrl, // 请传入需要播放的视频 fileID(必须)
+            appID: data.appID, // 请传入点播账号的 appID(必须)
+            licenseUrl: data.licenseUrl, // 请传入点播账号的 appID(必须)
+            //私有加密播放需填写 psign, psign 即播放器签名,签名介绍和生成方式参见链接:https://cloud.tencent.com/document/product/266/42436
             psign: data.psign,
           });
-          this.$emit("videoScript", this.player_tencent);
+          this.$emit("videoScript", this.player_tencent); //抛出播放实例
           resolve();
-        } catch (error) {}
+        } catch (error) {
+          console.log(error, "error");
+        }
       });
     },
+    //监听器
     timeEvent() {
-      this.timeEventStatus = true;
+      console.log("监听器执行中~");
+      this.timeEventStatus = true; //双重保障
+      // 定时提交学习记录
       this.submitStudyRecords();
+      //拍照监听执行
       let time = new Date().getTime();
       if (time >= this.commitTimePhoto) {
         this.watchPhoto();
         this.commitTimePhoto = time + 1000;
       }
     },
+    //拍照监听执行
     watchPhoto() {
       if (
         this.photoList.length == 0 ||
@@ -456,38 +519,48 @@ export default {
       } else {
         var videoTime = this.player.j2s_getCurrentTime();
       }
-      let photoTime = 0;
+      let photoTime = 0; //获取拍照秒数
       for (let i = 0; i < this.photoList.length; i++) {
-        photoTime = Number(this.photoList[i]);
+        photoTime = Number(this.photoList[i]); //获取拍照秒数
         if (photoTime < videoTime && photoTime > videoTime - 8) {
+          //3秒区间内才触发拍照,避免拉动滚动条
           if (
             this.photoHistoryList.indexOf(i) < 0 &&
             this.activeSection.learning != 1
           ) {
+            //不存在拍照历史,没有重修过,没有学过,则拍照
             if (this.viewSign == 2) {
-              this.player_tencent.pause();
+              this.player_tencent.pause(); //暂停
             } else {
-              this.player.j2s_pauseVideo();
+              this.player.j2s_pauseVideo(); //暂停
             }
             this.photoIndex = i;
-            this.openPhoto();
+            this.openPhoto(); //启动拍照
           }
         }
       }
     },
+    // 定时提交学习记录
     submitStudyRecords() {
       let time = new Date().getTime();
       if (time >= this.commitTime) {
+        if (!this.commitTime) {
+          //防止发生获取不到视频播放时长
+          this.commitTime = time + 3000;
+          return;
+        }
         this.postStudyRecord(0, null, null);
         this.commitTime = time + 15000;
       }
     },
+    //视频暂停时触发
     onVideoPause() {
       if (
         this.activeSection.learning != 1 &&
         this.goodsData.erJianErZao &&
         !this.failToRegister
       ) {
+        console.log("拍照停留过长计时开始");
         this.videoPauseSetTimeout = setTimeout(() => {
           if (this.isFullScreen()) {
             this.exitFullscreen();
@@ -510,26 +583,35 @@ export default {
               this.$router.go(0);
             })
             .catch(() => {});
-        }, 300000);
+        }, 300000); //300000
       }
     },
+    //视频恢复播放时触发
     onVideoPlay() {
+      console.log("触发一下吧");
       if (this.firstPlay) {
         this.firstPlay = false;
+        //计算拍照逻辑
         this.photoLogic();
+        //开启上次播放位置提示
         if (this.activeSection.videoCurrentTime) {
           this.showRecordStatus = true;
+          if (this.viewSign == 2) {
+            this.player_tencent.currentTime(
+              Number(this.activeSection.videoCurrentTime) || 0
+            );
+          }
           this.showRecordSetTimeOut = setTimeout(() => {
             this.showRecordStatus = false;
           }, 5000);
         }
         if (this.viewSign == 2) {
-          this.player_tencent.on("timeupdate", this.timeEvent);
+          this.player_tencent.on("timeupdate", this.timeEvent); //当前视频播放中触发
         } else {
           this.player.HTML5.video.addEventListener(
             "timeupdate",
             this.timeEvent
-          );
+          ); //监听器
         }
         this.timeEventStatusTimeout = setTimeout(() => {
           if (!this.timeEventStatus) {
@@ -555,17 +637,21 @@ export default {
         }, 5000);
       }
       clearTimeout(this.videoPauseSetTimeout);
+      console.log("视频恢复播放时触发");
     },
+    //当前视频播放完毕时触发
     onPlayOver() {
       this.$message({
         type: "success",
         message: "播放完毕",
       });
       this.isFullScreen();
-      clearTimeout(this.videoPauseSetTimeout);
+      clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
       this.postStudyRecord(1);
+      console.log("当前视频播放完毕时触发");
     },
 
+    //判断是全屏则退出全屏
     isFullScreen() {
       if (!!(document.webkitIsFullScreen || this.fullele())) {
         try {
@@ -589,6 +675,7 @@ export default {
         null
       );
     },
+    //播放出现错误时触发
     onPlayerError(title, msg) {
       this.$router.go(-1);
       this.$notify.error({
@@ -597,20 +684,27 @@ export default {
         message: msg || "视频播放错误,请及时反馈教务人员处理",
       });
     },
+    //发生业务逻辑错误
+    serverError() {
+      clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
+      this.$message.error("视频错误或解码失败");
+    },
+    //启动拍照
     openPhoto() {
       if (this.isFullScreen()) {
         this.exitFullscreen();
       }
       setTimeout(() => {
         if (this.viewSign == 2) {
-          this.player_tencent.pause();
+          this.player_tencent.pause(); //暂停
         } else {
-          this.player.j2s_pauseVideo();
+          this.player.j2s_pauseVideo(); //暂停
         }
       }, 1000);
       this.$refs.takePicture.openPhoto();
       this.HideVideo = true;
     },
+    //拍照成功回显 url
     async returnParameter(url) {
       let file = this.$tools.convertBase64UrlToBlob(url);
       try {
@@ -623,7 +717,9 @@ export default {
           type: "warning",
           message: "上传接口报错,请重新拍照上传",
         });
-        this.openPhoto();
+        setTimeout(() => {
+          this.openPhoto();
+        }, 1500);
         return;
       }
       let compareFaceData = await this.faceRecognition(photoUrl);
@@ -636,7 +732,8 @@ export default {
               0,
               photoUrl,
               compareFaceData
-            );
+            ); //提交记录
+            //恢复播放
             if (STATUS) {
               if (this.viewSign == 2) {
                 var polyvPlayerContext = this.player_tencent;
@@ -652,6 +749,7 @@ export default {
             }
           })
           .catch((err) => {
+            console.log(err, "err");
             this.$message({
               type: "warning",
               message: "上传接口报错,请重新拍照上传",
@@ -670,6 +768,11 @@ export default {
         }, 1500);
       }
     },
+
+    /**
+     * 提交观看记录
+     * status 1 学完 0未学完
+     */
     postStudyRecord(status = 0, imgUrl, compareFaceData) {
       return new Promise((resolve, reject) => {
         let currentTime = 0;
@@ -677,14 +780,14 @@ export default {
         if (this.viewSign == 2) {
           var polyvPlayerContext = this.player_tencent;
           if (polyvPlayerContext) {
-            currentTime = polyvPlayerContext.currentTime();
-            PlayDuration = currentTime;
+            currentTime = polyvPlayerContext.currentTime(); //当前视频播放时刻
+            PlayDuration = currentTime; //本次看的时长--与保利威的不一致
           }
         } else {
           var polyvPlayerContext = this.player;
           if (polyvPlayerContext) {
-            currentTime = polyvPlayerContext.j2s_getCurrentTime();
-            PlayDuration = polyvPlayerContext.j2s_realPlayVideoTime();
+            currentTime = polyvPlayerContext.j2s_getCurrentTime(); //当前视频播放时刻
+            PlayDuration = polyvPlayerContext.j2s_realPlayVideoTime(); //本次看的时长
           }
         }
         let data = {
@@ -695,7 +798,7 @@ export default {
           moduleId: this.activeSection.moduleId,
           chapterId: this.activeSection.chapterId,
           sectionId: this.activeSection.sectionId,
-          fromPlat: 2,
+          fromPlat: 2, //来源平台 1小程序 2网站
           photo: imgUrl || "",
           studyDuration: parseInt(PlayDuration > 0 ? PlayDuration : 0),
           videoCurrentTime: parseInt(currentTime > 0 ? currentTime : 0),
@@ -703,11 +806,12 @@ export default {
         };
 
         if (imgUrl) {
-          data.similarity = compareFaceData;
+          data.similarity = compareFaceData; // 相似度
         }
         if (status > 0) {
           data.status = status;
         }
+        // /study/record 学习记录
         this.$request
           .studyRecord(data)
           .then((res) => {
@@ -731,7 +835,7 @@ export default {
               } else {
                 polyvPlayerContext.j2s_pauseVideo();
               }
-              this.failToRegister = true;
+              this.failToRegister = true; //报名推送不通过
               this.$confirm(`您的信息正在推送中,请稍后再进入学习!`, "提示", {
                 confirmButtonText: "确定",
                 closeOnClickModal: false,
@@ -741,12 +845,15 @@ export default {
                 showClose: false,
               })
                 .then((_) => {
+                  //停止执行-退出页面
                   this.$router.back(-1);
                 })
                 .catch((_) => {
+                  //停止执行-退出页面
                   this.$router.back(-1);
                 });
             } else if (err.code === 559) {
+              console.log("拍照不够触发");
               this.$message.error(err.msg);
               this.openPhotoStatus = 1;
               setTimeout(() => {
@@ -762,11 +869,13 @@ export default {
           });
       });
     },
+    //人脸校验
     faceRecognition(url) {
       return new Promise((resolve) => {
         this.$request
           .faceCertificationCompareFace({
             urlA: url,
+            // imageA: url,
             orderGoodsId: this.goodsData.orderGoodsId,
             gradeId: this.goodsData.gradeId,
           })
@@ -789,6 +898,7 @@ export default {
           });
       });
     },
+    //页面显示隐藏逻辑
     pauseVideo() {
       if (
         this.$refs.takePicture.takePhotoModal ||
@@ -811,17 +921,23 @@ export default {
   },
   beforeDestroy() {
     this.$bus.$off("toPlay");
-    clearTimeout(this.videoPauseSetTimeout);
+    clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
+    // document.removeEventListener("visibilitychange", this.pauseVideo);
     if (this.player) {
-      this.player.HTML5.video.removeEventListener("timeupdate", this.timeEvent);
-      this.player.destroy();
+      this.player.HTML5.video.removeEventListener("timeupdate", this.timeEvent); //监听器
+      this.player.destroy(); //初始化播放器
     }
     if (this.player_tencent) {
       this.player_tencent.off();
-      this.player_tencent.dispose();
+      this.player_tencent.dispose(); //初始化播放器
     }
     this.timeEventStatus = false;
-    clearTimeout(this.timeEventStatusTimeout);
+    clearTimeout(this.timeEventStatusTimeout); //删除双重保障定时器
+    try {
+      this.$msgbox.close();
+    } catch (error) {
+      console.log(error, "element ui - msgBox close error");
+    }
   },
 };
 </script>

+ 5 - 3
src/filters/index.js

@@ -8,11 +8,12 @@ export default {
     }
     
   },
+
   countdown(second) {
     if (second) {
-      let h = parseInt((second / 60 / 60) % 24);
-      let m = parseInt((second / 60) % 60);
-      let s = parseInt(second % 60);
+      let h = parseInt((second / 60 / 60) % 24); //   计算小时
+      let m = parseInt((second / 60) % 60); //   计算分数
+      let s = parseInt(second % 60); //   计算当前秒数
 
       if (h < 10) h = '0' + h;
       if (m < 10) m = '0' + m;
@@ -23,6 +24,7 @@ export default {
       return '';
     }
   },
+  // 金额格式化
   formatPrice(price) {
     price = (price || 0).toLocaleString(
       "zh-CN",

+ 7 - 1
src/main.js

@@ -1,7 +1,9 @@
+// The Vue build version to load with the `import` command
+// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
 import Vue from 'vue'
 import App from './App'
 import router from './router'
-import store from './store'
+import store from './store'   //导入store
 import request from '@/request'
 import tools from '@/common/tools'
 import './style.css'
@@ -9,6 +11,7 @@ import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';
 import filters from './filters/index.js'
 import upload from '@/common/uploadFile'
+// import mixin from '@/mixin/index'
 import moment from "moment"
 import vueEsign from 'vue-esign'
 import axios from './axios.js'
@@ -16,6 +19,7 @@ import 'moment/locale/zh-cn'
 import "./assets/css/quill.core.css";
 import bus from '@/common/eventBus';
 import search from "@/components/search";
+// 通用弹窗
 import BaseDialog from "@/components/BaseDialog";
 import dragVerify from "vue-drag-verify2"
 
@@ -33,11 +37,13 @@ Vue.prototype.$moment = moment
 Vue.use(ElementUI);
 Vue.use(vueEsign)
 Vue.use(dragVerify)
+// Vue.mixin(mixin)
 
 Object.keys(filters).forEach(key => {
   Vue.filter(key, filters[key])
 })
 
+/* eslint-disable no-new */
 new Vue({
   el: '#app',
   router,

+ 31 - 9
src/mixin/index.js

@@ -10,15 +10,18 @@ export default {
 
   methods: {
     calculateScore(data) {
-      let score = 0;
-      let totalScore = 0;
-      let doWrongQuestionIds = [];
-      let doQuestionIds = [];
-      let lessQuestionNum = 0;
-      let rightQuestionIds = [];
-      let totalQuestionNum = 0;
+      let score = 0; //计算总分
+      let totalScore = 0; //总分
+      let doWrongQuestionIds = []; //做错题id(案例题简答不算在内)
+      let doQuestionIds = []; //做过的题目id
+      let lessQuestionNum = 0; //多选题少选
+      let rightQuestionIds = []; //做对的题目id
+      let totalQuestionNum = 0; //排除主观题的总条数(简单题)
       data.forEach((item) => {
+        console.log("答案--", item.ans, "选择--", item.ques);
+
         totalScore += item.score * (item.type == 4 ? item.jsonStr.length : 1);
+
         if (
           item.type < 4 ||
           (item.type == 4 && !item.jsonStr.some((e) => e.type == 5))
@@ -27,11 +30,13 @@ export default {
         }
 
         if (item.type == 1 || item.type == 3) {
+          //正确
           if (item.ques == item.ans) {
             item.scoreResult = item.score;
             score += item.score;
             rightQuestionIds.push(item.questionId);
           } else {
+            //错误
             item.scoreResult = 0;
             if (item.ques) {
               doWrongQuestionIds.push(item.questionId);
@@ -57,9 +62,10 @@ export default {
             rightQuestionIds.push(item.questionId);
           } else {
             let hasPart = false;
-            let checkboxScore = 1;
+            let checkboxScore = 1; //获取单题总分数
             item.ques &&
               item.ques.forEach((ques, quesIndex) => {
+                //选错一个全扣
                 if (item.ques) {
                   if (item.ans.indexOf(item.ques[quesIndex]) == -1) {
                     checkboxScore = 0;
@@ -68,9 +74,12 @@ export default {
                   checkboxScore = 0;
                 }
               });
+
+            //没选错
             if (checkboxScore) {
               checkboxScore = 0;
               item.ans.forEach((ans, quesIndex) => {
+                //漏选扣一部分,对n题给n X partScore 分
                 if (item.ques) {
                   if (item.ques.indexOf(item.ans[quesIndex]) != -1) {
                     checkboxScore += item.partScore;
@@ -83,11 +92,13 @@ export default {
             }
 
             if (!hasPart) {
+              //0分
               item.scoreResult = 0;
               if (item.ques) {
                 doWrongQuestionIds.push(item.questionId);
               }
             } else {
+              //部分分
               lessQuestionNum++;
               item.scoreResult = checkboxScore;
               score += checkboxScore;
@@ -136,6 +147,7 @@ export default {
         totalQuestionNum,
       };
     },
+    //优化题目结构
     questionOptimizeFormat(data) {
       let objs = JSON.parse(JSON.stringify(data))
       objs.forEach((item, index) => {
@@ -143,6 +155,7 @@ export default {
           item.jsonStr = JSON.parse(item.jsonStr);
 
           if (item.type == 2) {
+            //多选
             item.jsonStr.forEach(str => {
               str.optionsId = "" + str.optionsId;
             });
@@ -164,6 +177,7 @@ export default {
               ));
             return;
           } else if (item.type == 5) {
+            //简答题
             item.ansText = {
               text: "",
               imageList: []
@@ -185,6 +199,7 @@ export default {
 
             return;
           } else if (item.type == 4) {
+            //案例题
             item.ques = [];
             item.tabIndex = "0";
             let ansArr = [];
@@ -264,5 +279,12 @@ export default {
       });
     },
   },
-  beforeDestroy() {},
+
+  beforeDestroy() {
+    try {
+      console.log("触发一下给我看")
+      this.$msgbox.close();
+    } catch (err) { }
+  },
+
 }

+ 1 - 1
src/pages/payment/index.vue

@@ -454,7 +454,7 @@ export default {
                 })
                 .catch(_ => {});
               // this.qrCodeShow = true;
-            } else {
+            } else if(err.code != 601) {
               this.$message({
                 type: "warning",
                 message: err.msg

+ 40 - 38
src/pages/person-center/play-record/index.vue

@@ -18,7 +18,7 @@
                 {{ sectionItem.goodsName
                 }}<el-tag
                   type="success"
-                  style="margin-left: 10px;"
+                  style="margin-left: 10px"
                   v-if="sectionItem.learning == 1"
                   >已学完</el-tag
                 >
@@ -48,9 +48,11 @@
                       :stroke-width="16"
                       :percentage="
                         toFixed(
-                          (sectionItem.videoCurrentTime > sectionItem.durationTime?1:sectionItem.videoCurrentTime /
-                            sectionItem.durationTime) *
-                            100
+                          (sectionItem.videoCurrentTime >
+                          sectionItem.durationTime
+                            ? 1
+                            : sectionItem.videoCurrentTime /
+                              sectionItem.durationTime) * 100
                         )
                       "
                     ></el-progress>
@@ -86,15 +88,18 @@
       ref="rebuildModal"
       @rebuildSubmit="rebuildSubmit($event)"
     ></RebuildModal>
+    <media ref="media"></media>
   </div>
 </template>
 
 <script>
+import media from "./media"
 import RebuildModal from "@/components/rebuildModal";
 export default {
   name: "MyCourse",
   components: {
-    RebuildModal
+    media,
+    RebuildModal,
   },
   data() {
     return {
@@ -105,17 +110,17 @@ export default {
       rebuildItem: {},
       params: {
         pageNum: 1,
-        pageSize: 10
+        pageSize: 10,
       },
-      sysTime: 0
+      sysTime: 0,
     };
   },
   mounted() {
     this.studRrecordListUserRecord();
+    this.$refs.media.openBoxs()
   },
   methods: {
     toFixed(num) {
-      console.log(num);
       if (num) {
         let str = String(num).indexOf(".");
 
@@ -135,8 +140,8 @@ export default {
         query: {
           gradeId: item.gradeId,
           orderGoodsId: item.orderGoodsId,
-          rebuild: 1
-        }
+          rebuild: 1,
+        },
       });
     },
     currentChange(e) {
@@ -144,10 +149,10 @@ export default {
       this.studRrecordListUserRecord();
     },
     studRrecordListUserRecord() {
-      this.$request.studRrecordListUserRecord(this.params).then(res => {
+      this.$request.studRrecordListUserRecord(this.params).then((res) => {
         let dateObj = {};
 
-        res.rows.forEach(row => {
+        res.rows.forEach((row) => {
           if (!dateObj[row.date]) {
             dateObj[row.date] = { title: row.goodsName, list: [] };
             dateObj[row.date].list.push(row);
@@ -161,7 +166,6 @@ export default {
         //     return a.createTime - b.createTime;
         //   });
         // }
-        console.log(dateObj, "dateObj");
         this.recordList = dateObj;
         this.total = res.total;
         document.body.scrollTop = 0;
@@ -173,11 +177,10 @@ export default {
       this.sysTime = this.$tools.timest();
       this.$request
         .orderInfo({
-          orderGoodsId: sectionItem.orderGoodsId
+          orderGoodsId: sectionItem.orderGoodsId,
         })
-        .then(async res => {
+        .then(async (res) => {
           let item = res.data;
-          console.log(item, "item");
           // if (item.interfacePushId > 0 && item.officialStatus != 1) {
           //   this.$message({
           //     type: "warning",
@@ -192,7 +195,7 @@ export default {
           ) {
             this.$message({
               type: "warning",
-              message: "不在学习服务期,不能进入学习"
+              message: "不在学习服务期,不能进入学习",
             });
             return;
           }
@@ -203,7 +206,7 @@ export default {
           ) {
             this.$message({
               type: "warning",
-              message: "不在班级有效期,不能进入学习"
+              message: "不在班级有效期,不能进入学习",
             });
             return;
           }
@@ -211,7 +214,7 @@ export default {
           if (item.learningStatus == 2) {
             this.$message({
               type: "warning",
-              message: "开放学习时间待定,不能进入学习"
+              message: "开放学习时间待定,不能进入学习",
             });
             return;
           }
@@ -219,7 +222,7 @@ export default {
           if (item.classStatus == 0) {
             this.$message({
               type: "warning",
-              message: "尚未开班,不能进入学习"
+              message: "尚未开班,不能进入学习",
             });
             return;
           }
@@ -229,7 +232,7 @@ export default {
           ) {
             this.$message({
               type: "warning",
-              message: "不在开放学习时间,不能进入学习"
+              message: "不在开放学习时间,不能进入学习",
             });
             return;
           }
@@ -249,32 +252,32 @@ export default {
           // if (item.educationName == "继续教育") {
           this.$request
             .lockLockStatus({
-              action: "jxjy"
+              action: "jxjy",
             })
-            .then(res => {
+            .then((res) => {
               //有其他端在操作,不能学习
               this.$confirm("有其他端在操作,是否将该用户踢下线?", "提示", {
                 confirmButtonText: "确定",
                 cancelButtonText: "取消",
-                type: "warning"
+                type: "warning",
               })
                 .then(() => {
-                  this.$request.appuseroffline().then(r => {
+                  this.$request.appuseroffline().then((r) => {
                     this.goCourse(sectionItem);
                   });
                 })
                 .catch(() => {});
             })
-            .catch(err => {
+            .catch((err) => {
               //可以学习
               this.$request
                 .courseCourseList({
                   pageNum: 1,
                   pageSize: 1,
                   goodsId: item.goodsId,
-                  gradeId: item.gradeId
+                  gradeId: item.gradeId,
                 })
-                .then(res => {
+                .then((res) => {
                   if (res.rows.length) {
                     // this.go("/my-course-detail/" + sectionItem.goodsId, {
                     //   gradeId: sectionItem.gradeId,
@@ -294,13 +297,13 @@ export default {
                         liveUrl: sectionItem.liveUrl,
                         sectionType: sectionItem.sectionType,
                         liveStartTime: sectionItem.liveStartTime,
-                        liveEndTime: sectionItem.liveEndTime
-                      }
+                        liveEndTime: sectionItem.liveEndTime,
+                      },
                     });
                   } else {
                     this.$message({
                       type: "warning",
-                      message: "课程内暂无可以学习的科目"
+                      message: "课程内暂无可以学习的科目",
                     });
                   }
                 });
@@ -333,27 +336,26 @@ export default {
     go(path, query) {
       this.$router.push({
         path,
-        query
+        query,
       });
     },
-
     /**
      * @param {Object} goodsId 商品id
      * 查询商品重修状态
      */
     courseGoodsRebuildStatus(goodsId, gradeId) {
-      return new Promise(resolve => {
+      return new Promise((resolve) => {
         this.$request
           .courseGoodsRebuildStatus({
             goodsId: goodsId,
-            gradeId: gradeId
+            gradeId: gradeId,
           })
-          .then(res => {
+          .then((res) => {
             resolve(res.data);
           });
       });
-    }
-  }
+    },
+  },
 };
 </script>
 

+ 115 - 0
src/pages/person-center/play-record/media.vue

@@ -0,0 +1,115 @@
+<template>
+  <div id="">
+    <el-dialog
+      width="600px"
+      class="take-photo"
+      :visible.sync="visible"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :show-close="false"
+    >
+      <h1 class="h_t">抽查检测</h1>
+      <div class="content">
+        <video
+          id="video1"
+          v-show="status === 3"
+          class="video"
+          autoplay
+          controls
+          :src="url"
+        ></video>
+        <video v-show="status !== 3" id="video2" class="video" autoplay></video>
+      </div>
+      <div class="footer">
+        <el-button
+          :type="status === 3 ? 'success' : 'primary'"
+          class="pos"
+          @click="luzhi"
+          :disabled="status !== 1"
+          >{{
+            status === 1 ? "开始录制2秒" : status === 2 ? "录制中" : "提交"
+          }}</el-button
+        >
+        <el-button @click="again" v-if="status === 3">重录</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      status: 1, //1未录制 2录制中 3录制完成
+      visible: false,
+      mediaRecorder: null,
+      url: null,
+    };
+  },
+  methods: {
+    openBoxs() {
+      this.visible = true;
+      this.$nextTick(() => {
+        const video = document.getElementById("video2");
+        navigator.mediaDevices
+          .getUserMedia({ video: true })
+          .then((stream) => {
+            video.srcObject = stream;
+            this.mediaRecorder = new MediaRecorder(stream);
+          })
+          .catch(function (err) {
+            console.log("err", err);
+            /* 处理error */
+          });
+      });
+    },
+    again() {
+      this.url = null;
+      this.status = 1;
+    },
+    luzhi() {
+      if (this.status === 3) {
+        //完成提交
+        return;
+      }
+      this.mediaRecorder.start();
+      this.status = 2;
+      setTimeout(() => {
+        this.stop();
+        this.status = 3;
+      }, 2000);
+    },
+    stop() {
+      this.mediaRecorder.stop();
+      this.mediaRecorder.ondataavailable = (event) => {
+        this.$message.success("录制完成");
+        console.log(event.data,'data')
+        // 尝试转换为mp4类型
+        const blob = event.data.slice(0, event.data.size, "video/mp4");
+        this.url = URL.createObjectURL(blob);
+      };
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.video {
+  width: 500px;
+  height: 375px;
+  border: 1px solid #333;
+}
+.h_t {
+  text-align: center;
+  font-size: 34px;
+  color: #333;
+  margin-bottom: 14px;
+}
+.content {
+  text-align: center;
+  margin-bottom: 20px;
+}
+.footer {
+  text-align: center;
+}
+</style>

+ 5 - 0
src/request.js

@@ -11,6 +11,11 @@ import apply from '@/apis/apply' //考试模块
 import bank from '@/apis/bank' //题库模块
 import profileTp from '@/apis/profileTp'
 import mock from '@/apis/mock'
+
+
+
+
+// 导入对应模块------------------------
 export default {
     ...mock,
     ...login,

+ 35 - 3
src/router/index.js

@@ -2,7 +2,7 @@ import Vue from 'vue'
 import Router from 'vue-router'
 import store from '../store/index'
 import request from '@/request'
-import { MessageBox } from 'element-ui'
+import { Notification, MessageBox, Message } from 'element-ui'
 import tools from '../common/tools'
 Vue.use(Router)
 
@@ -776,6 +776,7 @@ router.beforeEach(async (to, from, next) => {
 
   if (!store.state.footer.length) {
     await store.dispatch("getCommonBaseHomeList");
+    //获取字典数据
     store.dispatch("getCommonBaseDictList");
   }
   if (!store.state.isDesktop) {
@@ -807,27 +808,40 @@ router.beforeEach(async (to, from, next) => {
     next();
 
   } else {
-    let { skipPort } = to.query
-    if ((skipPort ) && signLoginPage.some(path => to.path.includes(path))) {
+    // 处理携带skipPort隐式登录
+    let { skipPort, user_account } = to.query
+    if ((skipPort || user_account) && signLoginPage.some(path => to.path.includes(path))) {
       try {
+        if (skipPort) {
           let { data } = await request.skipLogin({ sign: skipPort })
           localStorage.setItem("user_account", data.user_account);
           localStorage.setItem("token", data.token);
+        }
+        if (user_account) {
+          let { data } = await request.account_login({ userAccount: user_account })
+          localStorage.setItem("user_account", user_account);
+          localStorage.setItem("token", data.token);
+        }
       } catch (error) {
         next('/login')
       }
     }
     let token = window.localStorage.getItem('token');
+    //进入页面有token获取用户信息
     if (token) {
       store.token = token;
       if (!store.state.userInfo) {
+        //获取用户信息
         store.dispatch('getUserInfo')
         store.dispatch('getbusinessList')
       }
+      //题库页面要检测是否需要锁定
       let isBankLock = bankAdmin.some(item => {
         return to.path.indexOf(item) != -1
       })
       if (isBankLock) {
+
+        //没有执行定时器,开启锁定
         if (!canToBank) {
           request
             .lockLockStatus({
@@ -835,6 +849,7 @@ router.beforeEach(async (to, from, next) => {
               uuid: tools.getUuid()
             })
             .then((res) => {
+              //有其他端在操作,不能学习
               MessageBox.confirm("有其他端在操作,是否将该用户踢下线?", "提示", {
                 confirmButtonText: "确定",
                 cancelButtonText: "取消",
@@ -842,6 +857,7 @@ router.beforeEach(async (to, from, next) => {
               })
                 .then(() => {
                   request.appuseroffline().then(r => {
+                    //可以学习,开启锁定
                     canToBank = 1;
                     request.lockLockAction({
                       action: 'bank',
@@ -865,6 +881,7 @@ router.beforeEach(async (to, from, next) => {
                   }
                 });
             }).catch(err => {
+              //可以学习,开启锁定
               canToBank = 1;
               request.lockLockAction({
                 action: 'bank',
@@ -884,36 +901,47 @@ router.beforeEach(async (to, from, next) => {
 
           return;
         } else {
+          //正在执行定时器,可以直接进入
           next()
         }
 
         return;
       } else {
+        //从题库页面离开删除锁定
+
         let isLeaveBank = bankAdmin.some(item => {
           return from.path.indexOf(item) != -1
         })
+
         if (isLeaveBank) {
+
           clearInterval(canToBank)
           canToBank = null;
           request.lockDelLock({
             action: 'bank',
             uuid: tools.getUuid()
           }).then(res => {
+
           })
         }
       }
+      //课程页面要检测是否需要锁定
       let isCourseLock = courseAdmin.some(item => {
         return to.path.indexOf(item) != -1
       })
       if (isCourseLock) {
+        //没有执行定时器,开启锁定
         if (!canToCourse) {
           request.goodsDetail(to.params.goodsId).then(res => {
+            //继续教育锁定
+            // if(res.data.educationName == '继续教育') {
             request
               .lockLockStatus({
                 action: "jxjy",
                 uuid: tools.getUuid()
               })
               .then((res) => {
+                //有其他端在操作,不能学习
                 MessageBox.confirm("有其他端在操作,是否将该用户踢下线?", "提示", {
                   confirmButtonText: "确定",
                   cancelButtonText: "取消",
@@ -921,6 +949,7 @@ router.beforeEach(async (to, from, next) => {
                 })
                   .then(() => {
                     request.appuseroffline().then(r => {
+                      //可以学习,开启锁定
                       canToCourse = 1;
                       request.lockLockAction({
                         action: 'jxjy',
@@ -946,6 +975,7 @@ router.beforeEach(async (to, from, next) => {
 
               })
               .catch(err => {
+                //可以学习,开启锁定
                 canToCourse = 1;
                 request.lockLockAction({
                   action: 'jxjy',
@@ -965,10 +995,12 @@ router.beforeEach(async (to, from, next) => {
           })
           return;
         } else {
+          //正在执行定时器,可以直接进入
           next()
         }
         return;
       } else {
+        //非题库页面删除锁定
         let isLeaveCouese = courseAdmin.some(item => {
           return from.path.indexOf(item) != -1
         })

+ 55 - 9
src/store/index.js

@@ -10,17 +10,18 @@ import axios from 'axios'
 Vue.use(Vuex);
 
 export default new Vuex.Store({
+  //所有的数据都放在state中
   state: {
     TENANT_NANE: "",
     msgCount: 0,
     cartCount: 0,
-    applyData: {},
+    applyData: {}, //预约考试数据存放
     currentRouter: {},
     token: '',
     user_account: '',
     userInfo: null,
     examResult: {},
-    dictList: {},
+    dictList: {},//字典数据
     sysTime: 0,
     businessItem: null,
     educationType: null,
@@ -30,13 +31,15 @@ export default new Vuex.Store({
     isDesktop: !navigator.userAgent.match(
       /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|IEMobile)/i
     ),
-    header: {},
-    footer: {},
-    nav: [],
-    links: [],
-    consultPc: {},
-    consultMobile: {},
-    other: {},
+    //--------------------------------
+    header: {},//页头配置
+    footer: {},//页尾配置
+    nav: [],//底部说明
+    links: [],//友情链接
+    consultPc: {},//移动端设置
+    consultMobile: {},//移动端设置
+    other: {},//移动端设置
+    //--------------------------------
   },
 
   getters: {
@@ -75,6 +78,8 @@ export default new Vuex.Store({
     cartCount: state => state.cartCount,
     msgCount: state => state.msgCount
   },
+
+  //操作数据,唯一的通道是mutations
   mutations: {
     setDictList(state, data) {
       state.dictList = data;
@@ -105,6 +110,22 @@ export default new Vuex.Store({
     },
     setHomeSetList(state, data) {
       data.forEach(item => {
+        // if (item.configKey === 'home.header') {
+        //   state.header = JSON.parse(item.configValue)
+        // }
+        // if (item.configKey === 'home.footer') {
+        //   state.footer = JSON.parse(item.configValue)
+        // }
+        // if (item.configKey === 'home.footer.record') {
+        //   state.footerRecord = JSON.parse(item.configValue) || {}
+        // }
+
+        // if (item.configKey === 'home.links') {
+        //   state.links = JSON.parse(item.configValue)
+        // }
+        // if (item.configKey === 'home.mobile') {
+        //   state.mobile = JSON.parse(item.configValue)
+        // }
         if (item.configKey === 'client.config') {
           let configValue = JSON.parse(item.configValue) || {}
           for(let k in configValue){
@@ -128,6 +149,8 @@ export default new Vuex.Store({
       })
     }
   },
+
+  //actions,可以来做异步操作,然后提交给mutations,而后再对state(数据)进行操作
   actions: {
     findTenantId({
       commit
@@ -145,6 +168,8 @@ export default new Vuex.Store({
             favicon.rel = 'icon'
             favicon.href = response.data.data == '867735392558919680' ? '/static/favicon.ico' : '/static/favicons.ico'
             document.head.appendChild(favicon)
+            // const ps = prompt()
+            // commit('setTENANT_NANE', ps)
             commit('setTENANT_NANE', response.data.data)
             resolve()
           })
@@ -153,6 +178,9 @@ export default new Vuex.Store({
           });
       })
     },
+    /**
+     * 设置系统时间
+     */
     setSystemTime({
       commit
     }) {
@@ -182,6 +210,12 @@ export default new Vuex.Store({
       })
 
     },
+    /**
+     * 
+     * @param {*} context 
+     * @returns 
+     * 获取用户信息
+     */
     getUserInfo(context) {
       return new Promise(resolve => {
         login.getInfo({ fromPlat: 2 }).then(res => {
@@ -193,6 +227,12 @@ export default new Vuex.Store({
         }).catch(err => { })
       })
     },
+    /**
+     * 
+     * @param {*} context 
+     * @returns 
+     * 获取首页配置
+     */
     getCommonBaseHomeList(context) {
       return new Promise(resolve => {
         common.getCommonBaseHomeList().then(res => {
@@ -201,6 +241,12 @@ export default new Vuex.Store({
         })
       })
     },
+    /**
+     * 
+     * @param {*} context 
+     * @returns 
+     * 获取字典配置
+     */
     getCommonBaseDictList(context) {
       return new Promise(resolve => {
         common.dictList({status:1}).then(res => {