浏览代码

修复bug

chenxiong 3 年之前
父节点
当前提交
8320d20eb5
共有 38 个文件被更改,包括 1587 次插入281 次删除
  1. 137 15
      package-lock.json
  2. 1 0
      package.json
  3. 16 0
      src/apis/user.js
  4. 4 4
      src/common/tools.js
  5. 9 3
      src/components/footer/index.vue
  6. 1 0
      src/components/header/index.vue
  7. 17 4
      src/components/toolbar/index.vue
  8. 2 0
      src/main.js
  9. 5 0
      src/pages/bank-exam-all-explain/index.vue
  10. 5 0
      src/pages/bank-exam-continue/index.vue
  11. 5 0
      src/pages/bank-exam-explain/index.vue
  12. 5 0
      src/pages/bank-exam-wrong-explain/index.vue
  13. 154 13
      src/pages/bank-exam/index.vue
  14. 28 4
      src/pages/bank-report/index.vue
  15. 12 2
      src/pages/cart/index.vue
  16. 194 44
      src/pages/course-detail/index.vue
  17. 9 3
      src/pages/course-exam/index.vue
  18. 4 4
      src/pages/course-report/index.vue
  19. 47 5
      src/pages/goods-detail/course-detail.vue
  20. 515 3
      src/pages/login/index.vue
  21. 71 3
      src/pages/person-center/bank-record/index.vue
  22. 12 6
      src/pages/person-center/my-bank/bank-detail/index.vue
  23. 5 0
      src/pages/person-center/my-bank/bank-explain-detail/index.vue
  24. 16 1
      src/pages/person-center/my-classhour/appointment-add/index.vue
  25. 2 1
      src/pages/person-center/my-classhour/appointment/index.vue
  26. 9 3
      src/pages/person-center/my-classhour/index/index.vue
  27. 37 10
      src/pages/person-center/my-course/index.vue
  28. 21 1
      src/pages/person-center/my-examination/index.vue
  29. 27 18
      src/pages/person-center/my-invoice/add/index.vue
  30. 152 122
      src/pages/person-center/my-invoice/index/index.vue
  31. 11 11
      src/pages/person-center/my-message/index.vue
  32. 20 1
      src/pages/person-center/my-order/index.vue
  33. 6 0
      src/pages/person-center/play-record/index.vue
  34. 5 0
      src/pages/subject/collect-bank.vue
  35. 5 0
      src/pages/subject/collect-type-bank.vue
  36. 5 0
      src/pages/subject/wrong-bank.vue
  37. 5 0
      src/pages/subject/wrong-type-bank.vue
  38. 8 0
      src/store/index.js

+ 137 - 15
package-lock.json

@@ -113,6 +113,11 @@
       "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
       "dev": true
     },
+    "@types/json-schema": {
+      "version": "7.0.11",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+      "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
+    },
     "@types/minimist": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
@@ -254,6 +259,11 @@
         "json-schema-traverse": "^0.3.0"
       }
     },
+    "ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
+    },
     "align-text": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
@@ -873,8 +883,7 @@
     "babel-plugin-syntax-dynamic-import": {
       "version": "6.18.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
-      "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
-      "dev": true
+      "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo="
     },
     "babel-plugin-syntax-exponentiation-operator": {
       "version": "6.13.0",
@@ -1453,8 +1462,7 @@
     "big.js": {
       "version": "5.2.2",
       "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
-      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
-      "dev": true
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
     },
     "binary-extensions": {
       "version": "2.2.0",
@@ -3731,8 +3739,7 @@
     "emojis-list": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
-      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
-      "dev": true
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
     },
     "encodeurl": {
       "version": "1.0.2",
@@ -4323,8 +4330,7 @@
     "fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
     },
     "fastparse": {
       "version": "1.1.2",
@@ -6003,7 +6009,6 @@
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
       "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
-      "dev": true,
       "requires": {
         "big.js": "^5.2.2",
         "emojis-list": "^3.0.0",
@@ -6014,7 +6019,6 @@
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
           "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
-          "dev": true,
           "requires": {
             "minimist": "^1.2.0"
           }
@@ -6511,8 +6515,7 @@
     "minimist": {
       "version": "1.2.6",
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
-      "dev": true
+      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
     },
     "minimist-options": {
       "version": "4.1.0",
@@ -7860,6 +7863,11 @@
         "sha.js": "^2.4.8"
       }
     },
+    "pdfjs-dist": {
+      "version": "2.6.347",
+      "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.6.347.tgz",
+      "integrity": "sha512-QC+h7hG2su9v/nU1wEI3SnpPIrqJODL7GTDFvR74ANKGq1AFJW16PH8VWnhpiTi9YcLSFV9xLeWSgq+ckHLdVQ=="
+    },
     "performance-now": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -10296,6 +10304,63 @@
         "unpipe": "1.0.0"
       }
     },
+    "raw-loader": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
+      "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
+      "requires": {
+        "loader-utils": "^2.0.0",
+        "schema-utils": "^3.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.12.6",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+          "requires": {
+            "fast-deep-equal": "^3.1.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+          "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+        },
+        "json5": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+          "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
+        },
+        "loader-utils": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
+          "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
+        "schema-utils": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
+          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+          "requires": {
+            "@types/json-schema": "^7.0.8",
+            "ajv": "^6.12.5",
+            "ajv-keywords": "^3.5.2"
+          }
+        }
+      }
+    },
     "read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -12463,7 +12528,6 @@
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
       "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
       "requires": {
         "punycode": "^2.1.0"
       },
@@ -12471,8 +12535,7 @@
         "punycode": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-          "dev": true
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
         }
       }
     },
@@ -12766,6 +12829,24 @@
         }
       }
     },
+    "vue-pdf": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/vue-pdf/-/vue-pdf-4.3.0.tgz",
+      "integrity": "sha512-zd3lJj6CbtrawgaaDDciTDjkJMUKiLWtbEmBg5CvFn9Noe9oAO/GNy/fc5c59qGuFCJ14ibIV1baw4S07e5bSQ==",
+      "requires": {
+        "babel-plugin-syntax-dynamic-import": "^6.18.0",
+        "loader-utils": "^1.4.0",
+        "pdfjs-dist": "2.6.347",
+        "raw-loader": "^4.0.2",
+        "vue-resize-sensor": "^2.0.0",
+        "worker-loader": "^2.0.0"
+      }
+    },
+    "vue-resize-sensor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/vue-resize-sensor/-/vue-resize-sensor-2.0.0.tgz",
+      "integrity": "sha512-W+y2EAI/BxS4Vlcca9scQv8ifeBFck56DRtSwWJ2H4Cw1GLNUYxiZxUHHkuzuI5JPW/cYtL1bPO5xPyEXx4LmQ=="
+    },
     "vue-router": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz",
@@ -13594,6 +13675,47 @@
         "errno": "~0.1.7"
       }
     },
+    "worker-loader": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
+      "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
+      "requires": {
+        "loader-utils": "^1.0.0",
+        "schema-utils": "^0.4.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.12.6",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+          "requires": {
+            "fast-deep-equal": "^3.1.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+          "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+        },
+        "json-schema-traverse": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+        },
+        "schema-utils": {
+          "version": "0.4.7",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
+          "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
     "wrap-ansi": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
     "vue": "^2.5.2",
     "vue-awesome-swiper": "^3.1.3",
     "vue-esign": "^1.1.0",
+    "vue-pdf": "^4.3.0",
     "vue-router": "^3.0.1",
     "vuex": "^3.6.2"
   },

+ 16 - 0
src/apis/user.js

@@ -286,6 +286,22 @@ export default {
 		})
 	},
   
+  
+	getCollectInfo(data) {
+		return request({
+			url: '/collect/question/getInfo',
+			params:data,
+			method: 'get'
+		})
+	},
 
+  
+	collectQuestion(data) {
+		return request({
+			url: '/collect/question',
+			data:data,
+			method: 'POST'
+		})
+	},
  
 }

+ 4 - 4
src/common/tools.js

@@ -169,11 +169,11 @@ export default {
     for (var i = 0; i < bytes.length; i++) {
       ia[i] = bytes.charCodeAt(i);
     }
-    return new Blob([ab], { type: "image/png" });
+    return new Blob([ab], { type: "image/jpeg" });
   },
 
 
-  imageToBase64(url) {
+  imageToBase64(url,quality = 0.5) {
     return new Promise(resolve => {
       var image = new Image();
       // 解决跨域 Canvas 污染问题,
@@ -184,11 +184,11 @@ 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/png"); //将图片格式转为base64
+        var url = canvas.toDataURL("image/jpeg",quality); //将图片格式转为base64
 
         resolve(url)
       };
-      image.src = url + "?time=" + Date.now(); //注意,这里是灵魂,否则依旧会产生跨域问题
+      image.src = url + "?time=" + Date.now();
     })
     
   }

+ 9 - 3
src/components/footer/index.vue

@@ -20,10 +20,12 @@
 
       <div class="footer__footer">
         <p>
-          Copyright©2016-2022 广东省祥粤建设职业培训学校) 版权所有
-          粤ICP备15087219号-2
+          Copyright©2016-2022 广东省祥粤建设职业培训学校 版权所有
+          <a href="https://beian.miit.gov.cn/" target="_blank">
+            粤ICP备15087219号-2</a
+          >
         </p>
-        <p>技术支持:中正教育科技有限公司</p>
+        <p>技术支持:广东中正教育科技有限公司</p>
       </div>
     </div>
   </div>
@@ -107,6 +109,10 @@ export default {
       color: #999999;
       line-height: 24px;
     }
+
+    a {
+      color: #999999;
+    }
   }
 }
 </style>

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

@@ -301,6 +301,7 @@ export default {
 
         &.name {
           position: relative;
+          z-index: 99;
           img {
             width: 24px;
             vertical-align: middle;

+ 17 - 4
src/components/toolbar/index.vue

@@ -1,8 +1,10 @@
 <template>
   <div class="toolBar">
     <div class="item" v-if="userInfo" @click="go('/cart')">
-      <i class="img el-icon-shopping-cart-2"></i>
-      <div class="text">购物车</div>
+      <el-badge :value="cartCount || ''">
+        <i class="img el-icon-shopping-cart-2"></i>
+        <div class="text">购物车</div>
+      </el-badge>
     </div>
 
     <div class="item">
@@ -22,18 +24,24 @@
 </template>
 
 <script>
-import { mapGetters } from "vuex";
+import { mapGetters, mapMutations } from "vuex";
 export default {
   name: "ToolBar",
   computed: {
-    ...mapGetters(["userInfo"]),
+    ...mapGetters(["userInfo", "cartCount"]),
   },
   data() {
     return {
       scrollTimer: null,
     };
   },
+  mounted() {
+    if (this.$tools.isLogin()) {
+      this.getCartCount();
+    }
+  },
   methods: {
+    ...mapMutations(["getCartCount"]),
     go(path) {
       this.$router.push({
         path,
@@ -79,6 +87,7 @@ export default {
     align-items: center;
     justify-content: center;
     color: #3f8dfd;
+    position: relative;
 
     &:nth-last-of-type(1) {
       border: 0;
@@ -105,6 +114,10 @@ export default {
       font-size: 14px;
       color: #3f8dfd;
     }
+
+    .el-badge {
+      text-align: center;
+    }
   }
 }
 </style>

+ 2 - 0
src/main.js

@@ -11,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 'moment/locale/zh-cn'
@@ -25,6 +26,7 @@ Vue.prototype.$moment = moment;
 
 Vue.use(ElementUI);
 Vue.use(vueEsign)
+Vue.mixin(mixin)
 
 Object.keys(filters).forEach(key => {
     Vue.filter(key, filters[key])

+ 5 - 0
src/pages/bank-exam-all-explain/index.vue

@@ -1001,6 +1001,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 5 - 0
src/pages/bank-exam-continue/index.vue

@@ -1566,6 +1566,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 5 - 0
src/pages/bank-exam-explain/index.vue

@@ -1052,6 +1052,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 5 - 0
src/pages/bank-exam-wrong-explain/index.vue

@@ -1024,6 +1024,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 154 - 13
src/pages/bank-exam/index.vue

@@ -98,7 +98,19 @@
                         </div>
                       </div>
                       <div class="question__btns">
-                        <div class="collect" @click="collect">收藏本题</div>
+                        <div
+                          class="collect"
+                          @click="
+                            collect(collectList[questionIndex], questionIndex)
+                          "
+                        >
+                          <template v-if="!collectList[questionIndex]"
+                            ><i class="el-icon-star-off"></i>收藏本题</template
+                          >
+                          <template v-if="collectList[questionIndex]"
+                            ><i class="el-icon-star-on"></i>已收藏</template
+                          >
+                        </div>
                       </div>
                     </div>
                     <div
@@ -175,7 +187,19 @@
                         >
                           确认答案
                         </div>
-                        <div class="collect" @click="collect">收藏本题</div>
+                        <div
+                          class="collect"
+                          @click="
+                            collect(collectList[questionIndex], questionIndex)
+                          "
+                        >
+                          <template v-if="!collectList[questionIndex]"
+                            ><i class="el-icon-star-off"></i>收藏本题</template
+                          >
+                          <template v-if="collectList[questionIndex]"
+                            ><i class="el-icon-star-on"></i>已收藏</template
+                          >
+                        </div>
                       </div>
                     </div>
                     <div
@@ -234,7 +258,19 @@
                         </div>
                       </div>
                       <div class="question__btns">
-                        <div class="collect" @click="collect">收藏本题</div>
+                        <div
+                          class="collect"
+                          @click="
+                            collect(collectList[questionIndex], questionIndex)
+                          "
+                        >
+                          <template v-if="!collectList[questionIndex]"
+                            ><i class="el-icon-star-off"></i>收藏本题</template
+                          >
+                          <template v-if="collectList[questionIndex]"
+                            ><i class="el-icon-star-on"></i>已收藏</template
+                          >
+                        </div>
                       </div>
                     </div>
                     <div
@@ -661,7 +697,19 @@
                         </el-tabs>
                       </div>
                       <div class="question__btns">
-                        <div class="collect" @click="collect">收藏本题</div>
+                        <div
+                          class="collect"
+                          @click="
+                            collect(collectList[questionIndex], questionIndex)
+                          "
+                        >
+                          <template v-if="!collectList[questionIndex]"
+                            ><i class="el-icon-star-off"></i>收藏本题</template
+                          >
+                          <template v-if="collectList[questionIndex]"
+                            ><i class="el-icon-star-on"></i>已收藏</template
+                          >
+                        </div>
                       </div>
                     </div>
                     <div
@@ -755,7 +803,19 @@
                         >
                           确认答案
                         </div>
-                        <div class="collect" @click="collect">收藏本题</div>
+                        <div
+                          class="collect"
+                          @click="
+                            collect(collectList[questionIndex], questionIndex)
+                          "
+                        >
+                          <template v-if="!collectList[questionIndex]"
+                            ><i class="el-icon-star-off"></i>收藏本题</template
+                          >
+                          <template v-if="collectList[questionIndex]"
+                            ><i class="el-icon-star-on"></i>已收藏</template
+                          >
+                        </div>
                       </div>
                     </div>
                   </template>
@@ -770,7 +830,7 @@
                 <div class="right-box__header">
                   <div class="title">答题卡</div>
                   <div class="time" v-if="allTimes">
-                    {{ lastTime | countDown }}
+                    {{ countdown(lastTime) }}
                   </div>
                 </div>
                 <div class="right-box__body">
@@ -865,6 +925,7 @@ export default {
       timer: null,
       examData: {},
       orderGoodsId: "",
+      collectList: [],
     };
   },
   async mounted() {
@@ -894,6 +955,26 @@ export default {
       }
     },
 
+    /**
+     * @param {Object} current
+     * 获取收藏信息
+     */
+    getCollectInfo(current) {
+      this.$request
+        .getCollectInfo({
+          examId: this.examId,
+          questionId: this.questionList[current].questionId,
+          goodsId: this.goodsId,
+          orderGoodsId: this.orderGoodsId,
+        })
+        .then((res) => {
+          this.$set(this.collectList, current, res.data);
+        })
+        .catch((err) => {
+          this.$set(this.collectList, current, false);
+        });
+    },
+
     /**
      * 请求题目列表
      */
@@ -913,6 +994,30 @@ export default {
           this.allTimes = res.data[0].answerTime * 60;
           this.lastTime = res.data[0].answerTime && res.data[0].answerTime * 60;
 
+          //考试时间到了自动交卷
+          if (this.lastTime) {
+            this.timer = setInterval(() => {
+              if (this.lastTime <= 0) {
+                clearInterval(this.timer);
+                this.$confirm(`考试时间已到,系统将自动交卷`, "提示", {
+                  confirmButtonText: "立即交卷",
+                  closeOnClickModal: false,
+                  showCancelButton: false,
+                  closeOnPressEscape: false,
+                  distinguishCancelAndClose: false,
+                  showClose: false,
+                });
+
+                setTimeout(() => {
+                  this.examSubmit();
+                }, 3000);
+                return;
+              }
+              this.lastTime--;
+            }, 1000);
+          } else {
+          }
+
           res.data.forEach((item, index) => {
             if (typeof item.jsonStr == "string") {
               item.jsonStr = JSON.parse(item.jsonStr);
@@ -1478,6 +1583,7 @@ export default {
 
     changeIndex(index) {
       this.current = index;
+      this.getCollectInfo(this.current);
     },
     nextQuestion() {
       if (this.current >= this.questionList.length - 1) {
@@ -1488,6 +1594,7 @@ export default {
         return;
       }
       this.current++;
+      this.getCollectInfo(this.current);
     },
     prevQuestion() {
       if (this.current == 0) {
@@ -1498,10 +1605,10 @@ export default {
         return;
       } else {
         this.current--;
+        this.getCollectInfo(this.current);
       }
     },
     isRight(item, index) {
-      console.log(item);
       //单选
       if (this.questionList[index].ques) {
         if (item.type == 1) {
@@ -1647,18 +1754,47 @@ export default {
       return count;
     },
 
-    collect() {
-      this.$message({
-        message: "试做题目,不支持收藏~",
-        type: "warning",
-      });
+    collect(state, index) {
+      if (!state) {
+        this.$request
+          .collectQuestion({
+            examId: this.examId,
+            questionId: this.questionList[index].questionId,
+            goodsId: this.goodsId || "",
+            orderGoodsId: this.orderGoodsId,
+          })
+          .then((res) => {
+            if (res.data.code == 200) {
+              this.$set(this.collectList, index, true);
+              uni.showToast({
+                title: "收藏成功",
+                duration: 2000,
+                icon: "none",
+              });
+              this.getCollectInfo(index);
+            }
+          });
+      } else {
+        this.$request
+          .deleteCollectQuestion(this.collectList[index].collectQuestionId)
+          .then((res) => {
+            if (res.data.code == 200) {
+              this.$set(this.collectList, index, false);
+              uni.showToast({
+                title: "取消收藏成功",
+                duration: 2000,
+                icon: "none",
+              });
+            }
+          });
+      }
       return;
     },
     submit() {
       let ansCount = this.questionOverNum(true); //已答题数
       this.lastCount = this.questionList.length - ansCount; //统计未答完的题数
       //没有答完
-      if (this.lastCount !== 0) {
+      if (this.lastCount > 0) {
         this.$confirm(
           `您还有${this.lastCount}道题未作答, 现在继续作答,还是下次继续?`,
           "提示",
@@ -1991,6 +2127,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 28 - 4
src/pages/bank-report/index.vue

@@ -12,8 +12,12 @@
             测试未通过
           </div>
           <div class="desc" v-if="reportdata.doTime">
-            答题时长:{{ reportdata.doTime }}分钟
-            <span class="note">(限时{{ reportdata.examTime }}分钟)</span>
+            总时间:{{ $tools.secondToTime(reportdata.examTime) }}
+            <span class="note"
+              >答题时长:{{
+                $tools.secondToTime(reportdata.doTime, false)
+              }}</span
+            >
           </div>
         </div>
         <div
@@ -25,11 +29,28 @@
             测试通过
           </div>
           <div class="desc" v-if="reportdata.doTime">
-            答题时长:{{ reportdata.doTime }}分钟
-            <span class="note">(限时{{ reportdata.examTime }}分钟)</span>
+            总时间:{{ $tools.secondToTime(reportdata.examTime) }}
+            <span class="note"
+              >答题时长:{{
+                $tools.secondToTime(reportdata.doTime, false)
+              }}</span
+            >
           </div>
         </div>
 
+        <template v-else>
+          <div class="section__header" v-if="reportdata.doTime">
+            <div class="desc">
+              答题时长:{{ $tools.secondToTime(reportdata.examTime) }}
+              <span class="note"
+                >交卷时间:{{
+                  $tools.secondToTime(reportdata.doTime, false)
+                }}</span
+              >
+            </div>
+          </div>
+        </template>
+
         <div class="section__body">
           <div class="section__body__content">
             <div class="left-box">
@@ -164,6 +185,9 @@ export default {
     back() {
       this.$router.replace({
         path: "/person-center/my-bank/bank-detail/" + this.goodsId,
+        query: {
+          orderGoodsId: this.orderGoodsId,
+        },
       });
     },
     /**

+ 12 - 2
src/pages/cart/index.vue

@@ -84,7 +84,16 @@
                         <el-option
                           v-for="item in scope.row.gradeList"
                           :key="item.gradeId"
-                          :label="item.className"
+                          :label="
+                            item.className +
+                            (item.classEndTime
+                              ? `,有效期至:${$tools.timestampToTime(
+                                  item.classEndTime
+                                )},本班还剩 ${$tools.GetRTime(
+                                  item.classEndTime
+                                )} 天将结束学习`
+                              : '')
+                          "
                           :value="item.gradeId"
                         >
                         </el-option>
@@ -209,7 +218,7 @@ export default {
     this.cartList();
   },
   methods: {
-    ...mapMutations(["setCheckGoodsList"]),
+    ...mapMutations(["setCheckGoodsList", "getCartCount"]),
     areaChange(row, index) {
       console.log(row);
       let node = this.$refs["cascader" + index].getCheckedNodes()[0]; //选中的根节点
@@ -430,6 +439,7 @@ export default {
           this.$request.cartDelete(row.id).then((res) => {
             this.$message.con;
             this.cartList();
+            this.getCartCount();
           });
         })
         .catch((_) => {});

+ 194 - 44
src/pages/course-detail/index.vue

@@ -1246,7 +1246,10 @@
                       <div class="lecture-notes">
                         <div class="lecture-notes__content clearfix">
                           <div class="left-box">
-                            <div class="textarea clearfix">
+                            <div
+                              class="textarea clearfix"
+                              v-if="isPlayRebuild > 0"
+                            >
                               <el-input
                                 resize="none"
                                 rows="3"
@@ -1344,7 +1347,6 @@
                                       >
                                         预览
                                       </div>
-                                      <!-- <div class="btn">打印</div> -->
                                       <div
                                         class="btn"
                                         @click="
@@ -1363,22 +1365,34 @@
                                 </div>
                               </div>
                             </div>
-                            <div class="lecture-list__footer">
+                            <div class="lecture-list__footer" v-if="showPdf">
                               <div class="lecture-scan">
                                 <div class="lecture-scan__header">
                                   {{ courseHandoutsData.urlName }}
                                 </div>
                                 <div class="lecture-scan__body">
-                                  <iframe
+                                  <pdf
                                     class="iframe"
                                     :src="
                                       $tools.splitImgHost(
                                         courseHandoutsData.handoutsUrl
                                       )
                                     "
+                                    v-for="i in numPages"
+                                    :key="i"
+                                    :page="i"
+                                    ref="pdf"
+                                  ></pdf>
+                                  <iframe
+                                    id="printIframe"
+                                    :src="
+                                      $tools.splitImgHost(
+                                        courseHandoutsData.handoutsUrl
+                                      )
+                                    "
                                     frameborder="0"
+                                    style="display: none"
                                   ></iframe>
-                                  <!-- <img src="@/assets/banner.png" alt="" /> -->
                                 </div>
                               </div>
                             </div>
@@ -1439,12 +1453,14 @@
             type="primary"
             v-if="!isTaking"
             class="take"
+            :loading="loading"
             @click="reTake"
             >重拍</el-button
           >
           <el-button
             type="primary"
             v-if="!isTaking"
+            :loading="loading"
             class="take"
             @click="takeOk"
             >确认</el-button
@@ -1668,24 +1684,37 @@
                     : ''
                 "
               >
-                <div style="display: inline-block; vertical-align: top">
+                <div class="upload-box">
                   <div
                     :style="
                       item.fieldKey === 'recent_photos'
                         ? 'width: 120px; height: 169px;background:url(' +
                           require('@/assets/info_1.png') +
-                          ') no-repeat center;background-size:cover;'
+                          ') no-repeat center;background-size:cover;position:relative;'
                         : item.fieldKey === 'idcard_face_photo'
                         ? 'width: 120px; height: 82px;background:url(' +
                           require('@/assets/info_2.png') +
-                          ') no-repeat center;background-size:cover;'
+                          ') no-repeat center;background-size:cover;position:relative;'
                         : item.fieldKey === 'idcard_national_photo'
                         ? 'width: 120px; height: 82px;background:url(' +
                           require('@/assets/info_3.png') +
-                          ') no-repeat center;background-size:cover;'
+                          ') no-repeat center;background-size:cover;position:relative;'
                         : ''
                     "
                   >
+                    <i
+                      @click="deleteImg(item)"
+                      class="el-icon-error"
+                      v-if="
+                        item.fieldKey === 'recent_photos'
+                          ? fileList1[0]
+                          : item.fieldKey === 'idcard_face_photo'
+                          ? fileList2[0]
+                          : item.fieldKey === 'idcard_national_photo'
+                          ? fileList3[0]
+                          : ''
+                      "
+                    ></i>
                     <el-image
                       style="width: 100%; height: 100%"
                       :src="
@@ -1883,7 +1912,7 @@
                     :style="
                       'width: 120px; height: 120px;background:url(' +
                       require('@/assets/info_4.png') +
-                      ') no-repeat center;background-size:cover;'
+                      ') no-repeat center;background-size:cover;position:relative;'
                     "
                   >
                     <el-image
@@ -1938,15 +1967,33 @@ import Header from "@/components/header/index";
 import ToolBar from "@/components/toolbar/index";
 import { mapGetters } from "vuex";
 import * as baseUrls from "@/axios.js";
+import pdf from "vue-pdf";
 export default {
   name: "CourseDetail",
   components: {
     Footer,
     Header,
     ToolBar,
+    pdf,
   },
   data() {
     return {
+      numPages: 0,
+      showPdf: false,
+      // 总页数
+      pdfPages: 10,
+      // 当前页数
+      pageNum: 1,
+      // 加载进度
+      loadedRatio: 10,
+      // 页面加载完成
+      curPageNum: 0,
+      // 放大系数 默认百分百
+      scale: 100,
+      // 旋转角度 ‘90’的倍数才有效
+      pageRotate: 0,
+      // 单击内部链接时触发 (目前我没有遇到使用场景)
+      page: 0,
       bgColor: "#ccc",
       recordObj: {},
       showInfoDetailModal: false,
@@ -2003,7 +2050,7 @@ export default {
       duration: 0,
       noteParams: {
         pageNum: 1,
-        pageSize: 4,
+        // pageSize: 4,
       },
       ossAvatarUrl: "", //照片地址
       nowTime: 0,
@@ -2225,6 +2272,7 @@ export default {
       uploading: false,
       veryIdCard: "",
       veryIdName: "",
+      isPlayRebuild: false,
     };
   },
   computed: {
@@ -2237,6 +2285,10 @@ export default {
     this.orderGoodsId = this.$route.query.orderGoodsId;
     this.gradeId = this.$route.query.gradeId;
 
+    if (this.$route.query.rebuild) {
+      this.courseTabIndex = "2";
+    }
+
     this.courseCourseList();
     this.getbaseprofiletplists();
     this.dictList();
@@ -2248,13 +2300,7 @@ export default {
   },
   methods: {
     async takeOk() {
-      this.loading = this.$loading({
-        lock: true,
-        text: "上传中",
-        spinner: "el-icon-loading",
-        background: "rgba(0, 0, 0, 0.1)",
-        target: document.querySelector(".section__body"),
-      });
+      this.loading = true;
       let compareFaceData = await this.faceRecognition();
 
       if (compareFaceData >= 80) {
@@ -2278,7 +2324,7 @@ export default {
             }
           })
           .catch((err) => {
-            this.loading.close();
+            this.loading = false;
             console.log(err, "err");
             this.$message({
               type: "warning",
@@ -2293,7 +2339,7 @@ export default {
         });
 
         setTimeout(() => {
-          this.loading.close();
+          this.loading = false;
           this.reTake();
         }, 2000);
         return;
@@ -2336,6 +2382,12 @@ export default {
         });
     },
 
+    // 页面加载成功  当前页数
+    pageLoaded(e) {
+      this.$emit("current", e);
+      this.curPageNum = e;
+    },
+
     changePhotoListHeader1(params, fileList) {
       console.log(params);
       const file = params.raw;
@@ -2686,7 +2738,8 @@ export default {
         let base = await this.$tools.imageToBase64(
           this.$tools.splitImgHost(this.infoForm.idcard_face_photo)
         );
-
+        console.log(base);
+        console.log(this.$tools.splitImgHost(this.infoForm.idcard_face_photo));
         let resData = await this.$request.faceCertificationIDCardOCR({
           cardSide: 1, //1人像  2 国徽
           cardImageBase64: base,
@@ -2715,13 +2768,13 @@ export default {
           this.$tools.splitImgHost(this.infoForm.recent_photos)
         );
 
-        let data = {
+        let newData = {
           idNum: this.veryIdCard,
           idName: this.veryIdName,
           oneInchPhotos: base64,
         };
 
-        this.$request.facCertificationImageRecognition(data).then((res1) => {
+        this.$request.facCertificationImageRecognition(newData).then((res1) => {
           if (res1.data.sim >= 70) {
             var self = this;
             if (self.remarkStatus) {
@@ -2798,7 +2851,7 @@ export default {
                 orderGoodsId: this.orderGoodsId,
                 keyValue: JSON.stringify(objs),
               };
-              this.$api
+              this.$request
                 .addbaseprofiletp(datas)
                 .then((res) => {
                   this.uploading = false;
@@ -2894,7 +2947,7 @@ export default {
           orderGoodsId: this.orderGoodsId,
           keyValue: JSON.stringify(objs),
         };
-        this.$api
+        this.$request
           .addbaseprofiletp(datas)
           .then((res) => {
             this.uploading = false;
@@ -3197,6 +3250,19 @@ export default {
       this.$store.state.allowLoading = true;
     },
 
+    deleteImg(item) {
+      if (item.fieldKey == "recent_photos") {
+        this.fileList1 = [];
+        this.infoForm["recent_photos"] = "";
+      } else if (item.fieldKey == "idcard_face_photo") {
+        this.fileList2 = [];
+        this.infoForm["idcard_face_photo"] = "";
+      } else if (item.fieldKey == "idcard_national_photo") {
+        this.fileList3 = [];
+        this.infoForm["idcard_national_photo"] = "";
+      }
+    },
+
     /**
      *  getbaseprofiletpgetInfo接口返回值result.data.data不存在的话说明是第一次填写资料
      */
@@ -3422,6 +3488,7 @@ export default {
         var data = {
           imageStatus: int,
           gradeId: this.gradeId,
+          orderGoodsId: this.orderGoodsId,
         };
         self.$request
           .getPolicy(data)
@@ -3454,7 +3521,7 @@ export default {
           .catch((err) => {
             this.$message({
               type: "warning",
-              message: "签名错误" + JSON.stringify(err.data),
+              message: "签名错误" + JSON.stringify(err),
             });
             return;
           });
@@ -3470,11 +3537,10 @@ export default {
             gradeId: this.gradeId,
           })
           .then((res) => {
-            console.log(res, "res");
             resolve(res.data);
           })
           .catch((err) => {
-            this.loading.close();
+            this.loading = false;
             this.$message({
               type: "warning",
               message: err.msg,
@@ -3565,11 +3631,15 @@ export default {
     courseChange() {
       this.noteParams = {
         pageNum: 1,
-        pageSize: 4,
+        // pageSize: 4,
       };
       this.duration = 0;
       this.playSectionId = 0;
       this.vid = "";
+      if (this.player) {
+        this.player.destroy();
+      }
+      this.player = "";
       this.vidzb = "";
       this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
       this.courseDetail(); //课程详情
@@ -3981,10 +4051,12 @@ export default {
           );
         //播放视频
         this.sectionItem = section;
+        console.log(section, "section");
+        this.isPlayRebuild = section.rebuild;
         this.moduleId = section.moduleId || 0;
         this.chapterId = section.chapterId || 0;
         this.playSectionId = section.sectionId || section.menuId;
-        console.log(this.moduleId, this.chapterId, this.playSectionId);
+        // console.log(this.moduleId, this.chapterId, this.playSectionId);
         await this.getPhotoLastRecord();
         this.recordObj = await this.getRecordLast();
         this.getNoteList();
@@ -4088,7 +4160,6 @@ export default {
       let moduleId = section.moduleId || 0;
       let chapterId = section.chapterId || 0;
       let sectionId = section.sectionId || section.menuId;
-
       if (
         moduleId == this.moduleId &&
         chapterId == this.chapterId &&
@@ -4909,12 +4980,30 @@ export default {
     noteClick(note) {
       if (this.vid) {
         //切换视频
-        var polyvPlayerContext = this.player;
-        polyvPlayerContext.changeVid(note.recordingUrl);
+        if (this.vid == note.recordingUrl) {
+          var polyvPlayerContext = this.player;
+          if (polyvPlayerContext) {
+            polyvPlayerContext.j2s_seekVideo(note.noteSecond);
+          }
+        } else {
+          var polyvPlayerContext = this.player;
+          if (polyvPlayerContext) {
+            polyvPlayerContext.changeVid(note.recordingUrl);
+          }
+        }
       } else {
-        this.vid = note.recordingUrl;
-        note.sectionType = 3;
-        this.initVideo(note);
+        var polyvPlayerContext = this.player;
+        console.log(polyvPlayerContext);
+        if (polyvPlayerContext) {
+          polyvPlayerContext.changeVid(note.recordingUrl);
+        } else {
+          this.vid = note.recordingUrl;
+          this.moduleId = note.moduleId;
+          this.chapterId = note.chapterId;
+          this.playSectionId = note.sectionId;
+          note.sectionType = 3;
+          this.loadPlayerScript(this.loadPlayer);
+        }
       }
       this.recordObj = { videoCurrentTime: note.noteSecond };
     },
@@ -4968,6 +5057,10 @@ export default {
                 label: "重修目录",
               },
             ];
+
+            if (courseTabIndex == "2") {
+              return;
+            }
             this.courseTabIndex = "1";
           } else {
             this.menuTab = [
@@ -4989,6 +5082,14 @@ export default {
         .courseHandouts(this.goodsData.handoutsId)
         .then((res) => {
           this.courseHandoutsData = res.data;
+          const loadingTask = pdf.createLoadingTask(
+            this.$tools.splitImgHost(this.courseHandoutsData.handoutsUrl)
+          );
+          loadingTask.promise
+            .then((pdf) => {
+              this.numPages = pdf.numPages;
+            })
+            .catch((err) => {});
         })
         .catch((err) => {});
     },
@@ -5023,15 +5124,46 @@ export default {
     },
 
     download(url, fileName) {
-      var a = document.createElement("a");
-      var event = new MouseEvent("click");
-      a.download = fileName;
-      a.href = url;
-      a.dispatchEvent(event);
+      let xhr = new XMLHttpRequest();
+      xhr.open("get", url, true);
+      xhr.setRequestHeader("Content-Type", `application/pdf`);
+      xhr.responseType = "blob";
+      let that = this;
+      xhr.onload = function () {
+        if (this.status == 200) {
+          //接受二进制文件流
+          var blob = this.response;
+          that.downloadExportFile(blob, fileName);
+        }
+      };
+      xhr.send();
+    },
+
+    downloadExportFile(blob, tagFileName) {
+      let downloadElement = document.createElement("a");
+      let href = "";
+      if (typeof blob == "string") {
+        downloadElement.target = "_blank";
+      } else {
+        href = window.URL.createObjectURL(blob); //创建下载的链接
+      }
+      downloadElement.href = href;
+      downloadElement.download = tagFileName;
+      //下载后文件名
+      document.body.appendChild(downloadElement);
+      downloadElement.click(); //点击下载
+      document.body.removeChild(downloadElement); //下载完成移除元素
+      if (typeof blob != "string") {
+        window.URL.revokeObjectURL(href); //释放掉blob对象
+      }
+    },
+
+    print() {
+      document.getElementById("printIframe").contentWindow.print();
     },
 
     previvew(url) {
-      window.open(url, "_blank");
+      this.showPdf = true;
     },
     noteSubmit() {
       let self = this;
@@ -5081,6 +5213,8 @@ export default {
         noteText: this.textareaNote,
         noteDate: noteDate,
         noteSecond: noteSecond,
+        moduleId: this.moduleId,
+        chapterId: this.chapterId,
       };
       this.$request.postNote(data).then((res) => {
         this.$message({
@@ -5282,7 +5416,7 @@ export default {
 
                         .live-btn {
                           margin-left: 20px;
-                          width: 32px;
+                          width: 60px;
                           height: 20px;
                           border-radius: 4px;
                           background: #eeeeee;
@@ -5880,10 +6014,11 @@ export default {
 
                       &__body {
                         height: 800px;
+                        text-align: center;
+                        overflow-y: scroll;
 
                         .iframe {
                           width: 100%;
-                          height: 100%;
                         }
                       }
                     }
@@ -5995,6 +6130,21 @@ export default {
         height: 300px;
         background: #ccc;
       }
+
+      .upload-box {
+        display: inline-block;
+        vertical-align: top;
+
+        .el-icon-error {
+          cursor: pointer;
+          z-index: 99;
+          position: absolute;
+          left: 100%;
+          bottom: 100%;
+          font-size: 20px;
+          color: red;
+        }
+      }
     }
   }
 }

+ 9 - 3
src/pages/course-exam/index.vue

@@ -770,7 +770,7 @@
                 <div class="right-box__header">
                   <div class="title">答题卡</div>
                   <div class="time" v-if="allTimes">
-                    剩余时间 {{ lastTime | countdown }}
+                    剩余时间 {{ lastTime }}
                   </div>
                 </div>
                 <div class="right-box__body">
@@ -1229,7 +1229,7 @@ export default {
 
                 setTimeout(() => {
                   this.examSubmit();
-                }, 5000);
+                }, 3000);
                 return;
               }
               this.lastTime--;
@@ -1258,6 +1258,7 @@ export default {
         var data = {
           imageStatus: int,
           gradeId: this.gradeId,
+          orderGoodsId: this.orderGoodsId,
         };
         self.$request
           .getPolicy(data)
@@ -1290,7 +1291,7 @@ export default {
           .catch((err) => {
             this.$message({
               type: "warning",
-              message: "签名错误" + JSON.stringify(err.data),
+              message: "签名错误" + JSON.stringify(err),
             });
             return;
           });
@@ -2180,6 +2181,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 4 - 4
src/pages/course-report/index.vue

@@ -11,10 +11,10 @@
             <span class="icon">X</span>
             测试未通过
           </div>
-          <div class="desc">
+          <!-- <div class="desc">
             答题时长:12分钟
             <span class="note">(限时60分钟)</span>
-          </div>
+          </div> -->
         </div>
         <div
           class="section__header section__header--success"
@@ -24,10 +24,10 @@
             <span class="icon">✔</span>
             测试通过
           </div>
-          <div class="desc">
+          <!-- <div class="desc">
             答题时长:12分钟
             <span class="note">(限时60分钟)</span>
-          </div>
+          </div> -->
         </div>
 
         <div class="section__body">

+ 47 - 5
src/pages/goods-detail/course-detail.vue

@@ -31,7 +31,7 @@
                     {{ courseList.length }} 课程
                     {{ goodsDetail.classHours }}学时
                   </div>
-                  <div class="price" v-if="goodsDetail.standPrice">
+                  <div class="price">
                     ${{ goodsDetail.standPrice | toFixed }}
                   </div>
                   <div class="btns">
@@ -404,7 +404,9 @@ export default {
     return {
       questionList: [],
       goodsExamConfig: [],
-      goodsDetail: {},
+      goodsDetail: {
+        standPrice: 0,
+      },
       courseList: [],
       goodsId: "",
       checked: false,
@@ -737,6 +739,8 @@ export default {
           width: 800,
           height: 450,
           vid: self.vid,
+          start: 0,
+          end: 30,
           teaser_show: 0,
           ts: res.data.ts,
           sign: res.data.sign,
@@ -1074,7 +1078,45 @@ export default {
     },
     buyNow() {
       if (this.$tools.isLogin()) {
-        this.selectClassModal = true;
+        if (this.goodsDetail.templateType) {
+          this.selectClassModal = true;
+        } else {
+          let selectGoodsList = JSON.parse(JSON.stringify([this.goodsDetail]));
+          selectGoodsList.forEach((item) => {
+            if (item.goodsType == 1) {
+              if (item.templateType == "class") {
+                let goodsInputData = {
+                  type: "class",
+                  gradeId: this.gradeId,
+                  gradeJson: JSON.stringify(
+                    this.gradeList.find(
+                      (grade) => grade.gradeId == this.gradeId
+                    )
+                  ),
+                };
+                item.goodsInputData = goodsInputData;
+              }
+              if (item.templateType == "apply") {
+                let goodsInputData = {
+                  type: "apply",
+                  applyAreasJson: JSON.stringify(this.applyAreas),
+                  examDateJson: JSON.stringify(
+                    this.examineList.find(
+                      (exam) => exam.educationId == this.educationId
+                    )
+                  ),
+                };
+                item.goodsInputData = goodsInputData;
+              }
+            }
+          });
+
+          this.setCheckGoodsList(selectGoodsList);
+
+          this.$router.push({
+            path: "/payment",
+          });
+        }
       } else {
         this.setCurrentRouter(this.$route);
         this.$router.push({
@@ -1184,7 +1226,7 @@ export default {
         if (res.data.pcDetailHtml) {
           res.data.pcDetailHtml = res.data.pcDetailHtml.replace(
             /<img/gi,
-            '<img style="max-width:100%;"'
+            '<img style="max-width:100%;max-height:400px;"'
           );
         }
         this.goodsDetail = res.data;
@@ -1311,7 +1353,7 @@ export default {
             }
 
             .btns {
-              margin-top: 154px;
+              margin-top: 124px;
               display: flex;
 
               .buynow {

+ 515 - 3
src/pages/login/index.vue

@@ -199,9 +199,9 @@
                       </div>
 
                       <div>
-                        <a>《用户使用协议》</a>
-                        及
-                        <a>《个人信息保护政策》</a>
+                        <a @click="showAgreementModal = true"
+                          >《用户使用协议》《个人信息保护政策》</a
+                        >
                       </div>
                     </el-form-item>
                   </div>
@@ -338,6 +338,488 @@
       </div>
     </section>
 
+    <el-dialog
+      title="提示"
+      class="agreement"
+      :visible.sync="showAgreementModal"
+      width="800px"
+      :before-close="handleClose"
+    >
+      <div class="agreement__content">
+        <div class="content">
+          <div class="bold">欢迎注册成为“祥粤云学堂”用户!</div>
+
+          <div>
+            在您注册过程中,您需要完成我们的注册流程并通过点击“同意并继续”的形式在线签署以下协议及政策,请您务必仔细阅读、充分理解协议中的条款内容后再点击同意(尤其是以粗体标识的条款,因为这些条款可能会明确您应履行的义务或对您的权利有所限制)。
+          </div>
+
+          <div>
+            <span class="bold">【请您注意】</span
+            >如果您不同意以下协议及政策全部或任何条款约定,请您停止注册。您停止注册后仅可以浏览我们的产品(或服务),但无法使用我们的产品(或服务)。如果您按照注册流程提示填写信息,阅读并点击同意上述协议及政策且完成全部注册流程后,即表示您也充分阅读、理解并接受协议及政策的全部内容,并表明您同意我们可以依照协议及政策内容来处理您的个人信息。如您对以下协议内容有任何疑问,请随时通过《个人信息保护政策》中的联系方式联系我们。
+          </div>
+
+          <div class="center bold">《用户使用协议》</div>
+
+          <div>
+            本《用户使用协议》(以下称“本协议”)是由您(以下称“用户”)与广东省祥粤建设职业培训学校(以下简称“祥粤”或“我们”)就用户使用祥粤提供的“祥粤云学堂”互联网服务产品(包括但不限于:祥粤云学堂网站www.xyyxt.net、微信小程序等,以下简称“祥粤云学堂”),包括但不限于注册、登录、使用等方面所订立的相关权利义务规范。本服务条款对用户和祥粤均具有法律效力。本协议连同所有更新材料、补充条款以及祥粤的其他规则和政策共同构成了用户与祥粤之间的协议。
+            我们在此特别提醒,在用户注册使用“祥粤云学堂”服务前,请务必审慎阅读本协议的全部条款、充分理解各条款内容后再点击同意,特别是免除或者限制祥粤责任的条款、对用户权利限制的条款、法律适用和争议解决条款,这些条款将尽可能以加粗方式标识。如用户按照注册页面提示填写信息、点击同意本协议且完成全部注册流程,或者在我们更新本协议后继续使用“祥粤云学堂”提供的服务,即表示用户已充分阅读、理解并接受本协议及祥粤的其他规则和政策的全部内容,成为具有法律约束力的本协议的一方。如果用户不同意本协议任何条款及/或修改后的内容,应立即停止注册程序或停止使用“祥粤云学堂”的服务。
+            如对本协议内容有任何疑问、意见或建议,用户可通过“祥粤云学堂”网站(www.xyyxt.net)页面上的联系方式与我们联系。
+          </div>
+
+          <div class="bold">一、账号注册与使用</div>
+
+          <div>
+            1.用户在使用“祥粤云学堂”服务时需要注册一个账号,账号注册成功后,将产生“祥粤云学堂”账号及相应的用户名和密码等账号信息。用户所创建的“祥粤云学堂”账号的所有权归祥粤所有,用户完成申请注册手续后,即获得“祥粤云学堂”账号的使用权,该使用权仅属于初始申请注册人,禁止赠与、借用、租用、转让或售卖或以其他方式许可他人使用该账号,用户应谨慎合理地保存、使用其用户名和密码。如果我们发现或者有合理理由认为使用者并非账号初始注册人,为保障账号安全,我们有权立即暂停或终止向该注册账号提供服务,并有权永久禁用该账号。
+          </div>
+
+          <div>
+            2.您可以使用微信账号登录并使用“祥粤云学堂”,但您需要将微信账号与“祥粤云学堂”账号绑定,账号绑定后,您可以直接使用微信账号扫码登录并使用“祥粤云学堂”的相关服务。
+          </div>
+
+          <div>
+            3.用户在注册及使用“祥粤云学堂”服务时,必须提供真实、准确、完整、合法有效的资料,且有义务维持并及时更新相关资料。用户在账号注册及使用过程中需遵守相关法律法规,不得实施任何侵害国家利益、损害其他公民合法权益,有害社会道德风尚的行为。我们有权对用户提交的注册信息进行审核。如果用户提供的资料违反本款要求,用户需承担因此引起的相应责任及后果,并且我们保留终止用户使用“祥粤云学堂”各项服务或采取其他处理措施的权利。
+          </div>
+
+          <div>
+            4.作为“祥粤云学堂”服务的提供者,为使用户更好地使用“祥粤云学堂”的各项服务,保障用户的账号安全,我们有权要求用户按照我国法律规定完成实名认证。若用户提交的材料或提供的信息不准确、不真实、不规范、不合法或者我们有理由怀疑为错误、不实或不合法的资料,则我们有权拒绝为用户提供相关服务,用户可能无法使用“祥粤云学堂”互联网服务或在使用过程中部分功能受到限制。
+          </div>
+
+          <div>
+            5.用户应当对以其用户账号进行的所有活动和事件负法律责任。用户同意在任何情况下不使用其他用户的账号或密码,不得冒充他人,也不得恶意使用注册账号导致其他用户误认,否则我们有权立即停止提供服务,收回其账号并由用户独自承担由此而产生的一切法律责任。在用户怀疑他人使用其账号或密码时,用户同意立即通知我们并按照要求提供相关身份证明文件等材料,同意授权我们采取一切合理措施以保证用户的利益不受损害,并认可该等措施所产生的法律效果归于用户自身。如用户丢失账号或遗忘密码,可通过平台页眉的联系方式及时申诉请求找回账号或密码。用户理解并认可,密码找回机制仅需要识别申诉提供资料与系统记录资料具有一致性,而无法识别申诉人是否系账号真正有权使用者。我们特别提醒用户应妥善保管账号和密码,当用户使用完毕后,应安全退出。因黑客行为、用户的保管疏忽或不可抗力因素等非祥粤的原因导致账号、密码遭他人非法使用、丢失的,我们不承担任何责任。
+          </div>
+
+          <div>
+            6.账号注销。在需要终止使用“祥粤云学堂”账号服务时,符合以下条件的,用户可以申请注销其“祥粤云学堂”账号:
+          </div>
+
+          <div>
+            (1)用户仅能申请注销用户本人的账号,并依照“祥粤云学堂”的要求和流程进行注销;
+          </div>
+          <div>
+            (2)用户仍应对其在注销账号前且使用“祥粤云学堂”服务期间的行为承担相应责任;
+          </div>
+          <div>(3)注销成功后,账号记录、功能等将无法恢复或提供。</div>
+          <div>
+            如用户需要注销“祥粤云学堂”账号,请打开“祥粤云学堂”网站www.xyyxt.net,如有疑问可联系客服。
+          </div>
+          <div>7. 用户必须自行准备如下设备和承担如下开支:</div>
+          <div>
+            (1)自行配备上网的所需设备,包括个人手机、平板电脑、调制解调器、路由器等;
+          </div>
+          <div>
+            (2)自行负担个人上网所支付的与此服务有关的电话费用、网络费用等。
+          </div>
+          <div class="bold">二、服务内容</div>
+          <div>
+            1.网上购物下单。使用“祥粤云学堂”网站下订单,您应具备购买相关商品/服务的权利能力和行为能力,如果您在18周岁以下,您需要在监护人的监护参与下才能注册并使用本网站。在下订单的同时,即视为您满足上述条件,并对您在订单中提供的所有信息的真实性负责。
+          </div>
+
+          <div>
+            2.在线课程学习。您在购买课程后,可以在平台进行相应在线课程的学习。我们将尽最大努力保障在线课程的正常使用,如因网站维护、系统升级、课程更新等技术原因导致课程无法正常使用的,请您及时向我们反馈,我们将会尽快解决问题。如您购买的课程包含考试报名,我们会根据您提供的考试报名所需的个人信息,向相关考试机构提交报名信息,您应对提供的个人信息的真实性负责。
+          </div>
+
+          <div class="bold">三、用户个人信息保护及授权</div>
+
+          <div>
+            1.您知悉并同意,为方便您使用“祥粤云学堂”相关服务,我们将视不同产品/服务,存储您在使用时的必要信息,包括但不限于您的真实姓名、身份证号码、手机号码、个人生物识别信息、学历信息等。除法律法规规定的情形外,未经您的许可,我们不会向第三方公开、透露您的个人信息。我们对相关信息采取专业加密存储与传输方式,利用合理措施保障用户个人信息的安全。
+          </div>
+
+          <div>2.您充分理解并同意:</div>
+          <div>
+            (1)同意通过短信、电话、站内私信等形式,接受“祥粤云学堂”发送的多类通知,用于用户消息告知、身份验证、安全验证等用途;我们可能使用您的个人信息,通过我们的站内私信、电子邮件或其他方式向您提供或推广我们或第三方的商品和服务;
+          </div>
+
+          <div>
+            (2)为配合行政监管机关、司法机关执行工作,在法律规定范围内我们有权向上述行政、司法机关提供您在使用“祥粤云学堂”时所储存的相关信息,包括但不限于您的注册信息等,或使用相关信息进行证据保全,包括但不限于公证、见证等;
+          </div>
+
+          <div>
+            (3)我们依法保障您在使用过程中的知情权和选择权,在您使用“祥粤云学堂”服务过程中,涉及您设备自带功能的服务会提前征得您同意,您一经确认,我们有权开启包括但不限于使用摄像头、访问相册等提供服务必要的辅助功能。
+          </div>
+
+          <div>
+            (4)我们有权根据实际情况,在法律规定范围内自行决定单个用户在“祥粤云学堂”及服务中数据的最长储存期限以及用户日志的储存期限,并在服务器上为其分配数据存储空间等。
+          </div>
+
+          <div class="bold">四、用户行为规范</div>
+
+          <div>1、您同意严格遵守法律法规规章规定,依法遵守以下义务:</div>
+          <div>
+            (1)不得制作、传输或发表以下违法信息资料:反对宪法所确定的基本原则,煽动抗拒、破坏宪法和法律法规实施的;危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的,煽动推翻社会主义制度的;损害国家荣誉和利益的;歪曲、丑化、亵渎、否定英雄烈士事迹和精神,侵害英雄烈士的姓名、肖像、名誉、荣誉的;宣扬或煽动实施恐怖主义、极端主义及其活动的;煽动民族仇恨、民族歧视、破坏民族团结的言论;破坏国家宗教政策,宣扬邪教和封建迷信的;散布谣言,扰乱经济秩序和社会秩序的;散布淫秽、色情、暴力或者教唆犯罪的;侮辱或者诽谤他人,侵害他人名誉、隐私和其他合法权益的;法律、行政法规禁止的其他内容。
+          </div>
+
+          <div>
+            (2)防范和抵制制作、复制、发布含有下列内容的不良信息资料:标题严重夸张,发表内容与标题严重不符的;不当评述自然灾害、重大事故等灾难的;煽动人群歧视、地域歧视等的;宣扬低俗、庸俗、媚俗内容的;违反社会公德行为的;侵犯未成年人合法权益的;其他对网络生态造成不良影响的内容。
+          </div>
+
+          <div>
+            2、本协议依据国家相关法律法规规章制定,您亦同意严格遵守以下义务:
+          </div>
+          <div>(1)从中国大陆向境外传输资料信息时必须符合中国有关法规;</div>
+          <div>
+            (2)不得利用本网站从事洗钱、窃取商业秘密、窃取个人信息等违法犯罪活动;
+          </div>
+          <div>
+            (3)不得干扰本网站的正常运转,不得侵入本网站及国家计算机信息系统;
+          </div>
+          <div>
+            (4)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的、不文明的等信息资料;
+          </div>
+          <div>
+            (5)不得教唆他人从事违法违规或本协议、平台规则所禁止的行为;
+          </div>
+          <div>(6)不得利用在本网站注册的账户进行牟利性经营活动;</div>
+          <div>
+            (7)不得发布任何侵犯他人个人信息、著作权、商标权等知识产权或合法权利的内容。
+          </div>
+          <div>
+            3、您须对自己在网上的言论和行为承担法律责任,您若在“祥粤云学堂”上散布和传播反动、色情或其它违反国家法律的信息,“祥粤云学堂”的系统记录有可能作为您违反法律的证据。
+          </div>
+
+          <div class="bold">五、知识产权</div>
+          <div>
+            “祥粤云学堂”提供的网络服务中包含的任何文本、图片、图形、音频和/或视频资料均受版权、商标和/或其它财产所有权法律的保护,祥粤享有上述知识产权,但相关权利人依照法律规定应享有的权利除外。未经祥粤书面同意,用户均不得将上述资料在任何媒体直接或间接发布、播放、出于播放或发布目的而改写或再发行,或者被用于其他任何商业目的。所有以上资料或资料的任何部分仅可作为私人和非商业用途使用。
+          </div>
+
+          <div class="bold">六、协议修改</div>
+          <div>
+            1.
+            根据互联网的发展和有关法律、法规及规范性文件的变化,或者因业务发展、技术条件、产品功能等变化的需要,我们将在必要时对本协议的服务条款作出修改或变更。我们将会直接在“祥粤云学堂”互联网服务产品上公布修改之后的协议内容,该公布行为视为祥粤已经通知用户修改内容,修改后的内容一经公布即有效替代原有服务条款。我们也可采用电子邮件或私信的传送方式,提示用户协议条款的修改、服务变更、或其它重要事项。
+            2.
+            用户可登录“祥粤云学堂”互联网服务产品中查阅最新版本的相关协议条款。如果用户继续使用“祥粤云学堂”提供的服务,即视为用户已经接受修改后的服务条款;如果用户不接受修改后的服务条款或对内容存在异议的,应当停止使用“祥粤云学堂”提供的服务。
+          </div>
+
+          <div class="bold">七、免责声明</div>
+          <div>1.我们不保证(包括但不限于):</div>
+          <div>
+            (1)“祥粤云学堂”的服务不受干扰,及时、安全、可靠或不出现错误;
+          </div>
+          <div>
+            (2)用户经由“祥粤云学堂”取得的任何产品、服务或其他材料符合用户的期望。
+          </div>
+          <div>
+            2.用户使用经由“祥粤云学堂”下载的或取得的任何资料,其风险自行负担。
+          </div>
+          <div>
+            3.由于地震、台风、洪水、火灾、战争、政府禁令以及其他不能预见并且对其发生和后果不能防止或避免的不可抗力或互联网上的黑客攻击事件,致使影响本服务条款的履行,祥粤不承担责任。
+          </div>
+
+          <div>
+            4.用户同意“祥粤云学堂”因政策法规变化、教学需要等原因有权更新课程,包括但不限于变更在线课程的授课老师、讲义及课件内容等。
+          </div>
+          <div class="bold">八、法律适用及争议解决</div>
+          <div>
+            1.
+            本协议的成立、效力、履行、解释及纠纷的解决,适用于中华人民共和国法律。本协议之任何规定因与中华人民共和国法律抵触而无效,则这些条款应在不违反法律的前提下按照尽可能接近本协议原条文目的之原则进行重新解释和适用,且本协议其它规定仍应具有完整的效力及效果。
+          </div>
+          <div>
+            2.本协议的签署地点为中华人民共和国广州市天河区,若用户和祥粤之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户同意将纠纷或争议提交协议签订地有管辖权的人民法院管辖。
+          </div>
+
+          <div class="bold center">《个人信息保护政策》</div>
+          <div>
+            广东省祥粤建设职业培训学校(注册地址:广东省广州市天河区燕岭路123号3楼)及其关联方(以下简称“祥粤”或“我们”)作为“祥粤云学堂”互联网服务产品(包括但不限于祥粤云学堂网站www.xyyxt.net、微信小程序等,下称“祥粤云学堂”)的运营者,深知个人信息对您的重要性,我们将按照法律法规的规定,保护您的个人信息安全。我们制定本“个人信息保护政策”并特别提示:希望您在使用“祥粤云学堂”及相关服务前仔细阅读并理解本个人信息保护政策,以便做出适当的选择。本政策中涉及的相关术语,我们尽量以简明扼要的方式进行表述,以便您更好地理解。您使用或在我们更新本政策后(我们会及时提示您更新的情况并再次取得您对本政策更新版本的同意)继续使用我们的服务,即意味着您同意本政策(含更新版本)内容,并且同意我们按照本政策收集、使用、存储、传输、共享、转让和公开披露您的相关信息。
+          </div>
+
+          <div class="bold">本个人信息保护政策将帮助您了解:</div>
+          <div>
+            •
+            我们会遵循个人信息保护政策收集、使用您的信息,但不会仅因您同意本个人信息保护政策而采用强制捆绑的方式一揽子收集个人信息。
+          </div>
+          <div>
+            •
+            当您使用或开启相关功能或使用服务时,为实现功能、服务所必需,我们会收集、使用相关信息。除非是为实现基本业务功能或根据法律法规要求所必需的必要信息,您均可以拒绝提供且不影响其他功能或服务,对于前述您可以拒绝提供的信息,我们将在个人信息保护政策中进行说明。
+          </div>
+
+          <div>
+            •
+            地理位置、网络、通知、相机、摄像头、麦克风、相册等权限,均不会默认开启,只有经过您的明示授权才会在为实现特定功能或服务时使用,您也可以撤回授权。特别需要指出的是,即使经过您的授权,我们获得了这些敏感权限,也不会在相关功能或服务不需要时而收集您的信息。
+          </div>
+
+          <div>
+            •本个人信息保护政策适用于您通过“祥粤云学堂”官方网站或微信小程序来访问和使用我们的产品和服务。
+          </div>
+
+          <div>
+            下文将帮您详细了解我们将如何收集、使用、存储、传输、共享、转让、公开披露和保护(如适用)您的个人信息,帮您了解查询、访问、删除、更正、撤回授权个人信息的方式。其中,有关您个人信息权益的条款重要内容我们已用加粗形式提示,请特别关注。请您了解并知悉,“祥粤云学堂”未来有可能根据信息处理情境不时更新或修改本政策。
+          </div>
+
+          <div class="bold">一、我们如何收集和使用您的个人信息</div>
+          <div>
+            个人信息是指以电子或者其他方式记录的与已识别或者可识别的自然人有关的各种信息,不包括匿名化处理后的信息。个人敏感信息是指一旦泄露或者非法使用,容易导致自然人的人格尊严受到侵害或者人身、财产安全受到危害的个人信息,包括生物识别、宗教信仰、特定身份、医疗健康、金融账户、行踪轨迹等信息,以及不满十四周岁未成年人的个人信息。本政策中涉及的个人信息包括但不限于基本信息(包括个人姓名、生日、性别、住址、个人电话号码、电子邮箱、工作单位等)、个人身份信息(包括身份证、军官证、护照、驾驶证等)、个人生物识别信息(包括声纹、面部识别特征等)、网络身份标识信息(包括个人信息主体账号、IP地址、邮箱地址及与前述有关的密码、口令、口令保护答案等)、个人财产信息(包括交易和消费记录)、通讯录、个人上网记录(包括网站浏览记录、软件使用记录、点击记录等)、个人常用设备信息(如硬件序列号、设备MAC地址、软件列表、唯一设备识别码(如IMEI/Android
+            ID/IDFA/OPENUDID/GUID、SIM卡IMSI信息等)在内的描述个人常用设备基本情况的信息)及个人位置信息(包括行踪轨迹、精准定位信息、住宿信息、经纬度等);其中,字体加粗部分为涉及的个人敏感信息。
+          </div>
+          <div class="bold">(一)我们收集和使用个人信息的功能和场景</div>
+          <div>
+            我们根据合法、正当、必要的原则,仅收集实现产品/服务功能所必要的信息用于实现明确、合理的处理目的。我们不会以欺诈、诱骗、误导的方式收集个人信息,也不会从非法渠道获取个人信息。
+          </div>
+          <div>我们提供如下功能和服务时,可能会处理下列与您有关的信息。</div>
+          <div>
+            如果您不提供相关信息,您可能无法注册成为我们的用户或无法享受我们提供的某些产品/服务,或者无法达到使用相关服务拟达到的效果。
+          </div>
+          <div class="bold">用户注册/登录</div>
+          <div>
+            您使用“祥粤云学堂”提供的服务,可以注册并登录经注册的“祥粤云学堂”账号。当您注册“祥粤云学堂”账号时,您需向我们提供您的移动电话号码,我们将通过发送短信验证码的方式来验证您的身份是否有效,验证无误后我们会为您创建账号;此外,您也可以使用微信账号登录并使用“祥粤云学堂”,但您仍需要将微信账号与“祥粤云学堂”账号绑定,账号绑定后,您可以直接使用微信账号扫码登录并使用本产品和相关服务。
+          </div>
+          <div>
+            为了满足相关法律法规的网络实名制要求,我们需要收集您的移动电话号码。如您拒绝提供移动电话号码或进行实名验证,在您同意接受本《个人信息保护政策》及《祥粤云学堂用户使用协议》适用条款的前提下,您仍可浏览“祥粤云学堂”网站的内容,但将无法使用课程购买、课程学习、考试预约等其他全部或部分“祥粤云学堂”提供的服务。
+          </div>
+          <div class="bold">网上购物下单</div>
+          <div>
+            当您准备对您平台购物车内的产品/服务进行结算时,我们的网站系统会生成您购买该产品/服务的订单。针对不同的产品/服务,可能还需要您提供额外的个人信息,以完成下单。
+          </div>
+          <div>
+            (1)考前培训课程:您在登录个人账号后,如需要购买考前培训课程,无须提供额外的个人信息,便可完成下单。
+          </div>
+          <div>
+            (2)二级建造师继续教育:您在登录个人账号后,如需要购买二级建造师继续教育课程,根据广东省建设执业注册管理中心的要求,您需提供以下个人信息,以便完成下单:姓名、性别、身份证号码、移动电话号码、身份证照片、一寸照、证书名称/岗位、证书编号、证书有效期、工作单位。
+          </div>
+          <div>
+            (3)施工现场管理人员(七大员)新考证:您在登录个人账号后,如需要购买七大员新考的考试报名及考前培训课程,根据广州市建筑教育协会的要求,您需提供以下个人信息,以便完成下单:姓名、性别、身份证号码、移动电话号码、身份证照、承诺书照、一寸照、用户电子签名、学历信息、工作单位、工作年限。
+          </div>
+          <div>
+            (4)施工现场管理人员(七大员)继续教育:您在登录个人账号后,如需要购买七大员继续教育课程,根据广东省建筑教育协会的要求,您需提供以下个人信息,以便完成下单:姓名、身份证号码、移动电话号码、证书名称/岗位、证书编号、发证时间、证书有效期、工作单位。
+          </div>
+          <div>
+            上述所有信息构成您的“订单信息”,我们将使用您的订单信息来进行您的身份核验、确定交易、支付结算、为您查询订单以及提供客服咨询与售后服务;我们还会使用您的订单信息来判断您的交易是否存在异常以保护您的交易安全。
+          </div>
+          <div>
+            我们会收集您的交易记录信息,以便您查询您的交易记录及保障交易安全。
+          </div>
+          <div class="bold">支付</div>
+          <div>
+            在您使用消费功能并选择支付时,您可以使用微信支付所提供的支付服务。支付功能本身并不收集您的个人信息,但我们需要将您的订单号与交易金额信息与支付机构共享以实现其确认您的支付指令并完成支付。
+          </div>
+          <div class="bold">在线课程学习</div>
+          <div>
+            您在购买相应课程后,可以在平台进行在线课程学习,部分课程可能需额外获取您的个人信息。
+          </div>
+          <div>
+            (1)考前培训课程:您在登录个人账号后,即可进行在线学习,无须提供其他个人信息。
+          </div>
+          <div>
+            (2)施工现场管理人员(七大员)继续教育:您在登录个人账号后,即可进行在线学习,无须提供其他个人信息。我们会将您的以下个人信息提供予广东省建筑教育协会:姓名、身份证号码、移动电话号码、证书名称/岗位、证书编号。
+          </div>
+          <div>
+            (3)二级建造师继续教育:您在登录个人账号后,即可进行在线学习,根据广东省建设执业注册管理中心的要求,在您每一节在线课程的培训过程中,我们需要通过您设备上的摄像头随机拍摄三张照片,用于比对核实学习人员的身份。我们会将您的以下个人信息提供予广东省建设执业注册管理中心:姓名、性别、身份证号码、移动电话号码、身份证照片、一寸照、证书名称/岗位、证书编号、有效期、人脸照片、学习详细记录。
+          </div>
+          <div>
+            (4)施工现场管理人员(七大员)新考证:您在登录个人账号后,即可进行在线学习,根据广州市建筑教育协会的要求,在您每一节在线课程的培训过程中,我们需要通过您设备上的摄像头随机拍摄三张照片,用于比对核实学习人员的身份。我们会将您的以下个人信息提供予广州市建筑教育协会:姓名、性别、身份证号码、移动电话号码、身份证照、承诺书照、一寸照、用户电子签名、学历信息、工作年限、人脸照片、学习详细记录。
+          </div>
+          <div class="bold">商品或服务推荐</div>
+          <div>
+            为了改进我们的商业广告服务,将您可能感兴趣的商品或服务信息(包括但不限于课程等)展示给您,提升现有服务体验,我们可能会收集您的年龄、学历信息、工作年限等信息,并以此开展内部审计、进行数据分析、形成用户画像,以便为您提供个性化的商品或服务推荐。
+          </div>
+          <div class="bold">客服与发票功能</div>
+          <div>
+            在您与我们的在线客服/电话客服进行沟通时,为了及时有效地与您沟通,我们的在线客服/电话客服功能会使用您的账号信息、订单信息。
+          </div>
+          <div>
+            为保证您的账号安全,我们的在线客服/电话客服会使用您的账号信息与您核验您的身份。当您需要我们提供与您订单信息相关的客服与售后服务时,我们将会查询您的订单信息。若您需要开具发票,则需提供相应的开票信息。
+          </div>
+          <div class="bold">保障账号和服务安全</div>
+          <div>
+            为提高您使用我们的服务时系统的安全性并保障网站数据安全,更准确地预防钓鱼网站欺诈和保护账户安全,我们会收集您的有关信息对“祥粤云学堂”系统问题进行分析、统计流量并排查可能存在的风险、在您选择向我们发送异常信息时予以排查。我们可能使用您的账户信息、服务日志信息以及我们关联方、合作方在获得您授权或依法可以共享的信息,用于判断账户安全、进行身份验证、检测及防范安全事件。尤其是在接到您有关账号安全方面的需求(如账号找回)时,我们可能会要求您再次提供相关信息(如移动电话号码等)用于安全验证,如您拒绝提供的,我们可能无法判断您账户的安全情况或无法为您进行与账号安全相关的操作。
+          </div>
+          <div class="bold">设备权限调用</div>
+          <div>
+            我们在提供服务的过程中,基于服务的具体场景和功能,可能需要您开启一些设备访问权限,例如相机(摄像头)、相册(图片库)等访问权限,以实现拍摄、上传图片等功能所涉及的信息收集和使用。您也可以在设备的设置功能中随时选择关闭部分或全部权限,从而撤回您授予我们某项权限的同意。在不同设备中,权限显示方式及关闭方式可能有所不同,具体请参考设备及系统开发方说明或指引。请您注意,您开启这些权限即代表您授权我们可以收集和使用这些个人信息来实现上述的功能,您关闭权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您提供与这些授权所对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息的处理。
+          </div>
+          <div class="bold">消息通知</div>
+          <div>
+            您知悉并同意,对于您在使用产品及/或服务的过程中提供的您的联系方式(例如:移动电话号码),我们在运营中可能会向其中的一种或多种发送多类通知,用于用户消息告知、身份验证、安全验证等用途;我们可能使用您的个人信息,通过我们的站内私信、电子邮件或其他方式向您提供或推广我们或第三方的商品和服务。如相关页面设置了“退订”或类似功能且您不希望我们通过上述方式向您发送商品或服务的相关信息,您可以按照页面提示的操作进行设置或联系我们进行反馈,要求全部或部分停止接收我们发送的相关推广信息。
+          </div>
+          <div class="bold">征得授权同意的例外</div>
+          <div>
+            根据相关法律法规的规定,以下情形中收集您的个人信息无需征得您的授权同意:
+          </div>
+          <div>(1)与我们履行法律法规规定的义务相关的;</div>
+          <div>(2)与国家安全、国防安全直接相关的;</div>
+          <div>(3)与公共安全、公共卫生、重大公共利益直接相关的;</div>
+          <div>(4)与刑事侦查、起诉、审判和判决执行等直接相关的;</div>
+          <div>
+            (5)出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您本人同意的;
+          </div>
+          <div>(6)所收集的个人信息是您或您的监护人自行向社会公众公开的;</div>
+          <div>
+            (7)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道;
+          </div>
+          <div>(8)根据您的要求签订和履行合同所必需的;</div>
+          <div>
+            (9)用于维护所提供的产品或服务的安全稳定运行所必需的,例如发现、处置产品或服务的故障;
+          </div>
+          <div>(10)为合法的新闻报道所必需的;</div>
+          <div>
+            (11)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
+          </div>
+          <div>(12)法律法规规定的其他情形。</div>
+          <div class="bold">(二)您个人信息使用的规则</div>
+          <div>
+            1、我们会根据本政策的约定并为实现我们的服务功能对所收集的个人信息进行使用。
+          </div>
+          <div>
+            2、请您注意,您在使用我们的服务时所提供的所有个人信息,除非您删除或通过系统设置拒绝我们收集,否则将在您使用我们的服务期间持续授权我们使用。在您注销账号后,我们将停止为您提供服务,您的个人信息将在“祥粤云学堂”全站匿名化处理,使您的账号处在不可被检索、访问的状态,并在符合相关法律法规规定的前提下删除您的个人信息。
+          </div>
+          <div>
+            3、当我们要将您的个人信息用于本政策未载明的其他用途时,或基于特定目的收集而来的信息用于其他目的时,会通过您主动做出勾选或其他合法形式事先征求您的同意。
+          </div>
+          <div>
+            4、根据法律法规的规定,经过处理无法识别特定个人且不能复原的信息不属于个人信息,我们有权自行决定收集、使用该部分信息,包括但不限于对该类信息进行分析并予以商业化的利用。
+          </div>
+          <div class="bold">二、我们会如何使用Cookies和同类技术</div>
+          <div>
+            您使用我们的服务时,我们会在您的计算机或移动设备上存储名为Cookies的小数据文件。Cookies通常包含标识符、站点名称以及一些号码和字符。我们使用该等信息判断注册用户是否已经登录,提升服务质量及优化用户体验。
+          </div>
+          <div>
+            我们不会将Cookies用于本政策所述目的之外的任何用途。您可根据自己的偏好管理或删除Cookies。您可以清除计算机上保存的所有Cookies,大部分网络浏览器都设有阻止Cookies的功能。但如果您这么做,您可能需要在每一次访问我们的网站时亲自更改用户设置,而且您之前所记录的相应信息也均会被删除,并且可能会对您所使用服务的安全性有一定影响。
+          </div>
+          <div class="bold">
+            三、我们会如何委托处理、共享、转让、公开披露您的个人信息
+          </div>
+          <div class="bold">(一)委托处理</div>
+          <div>
+            为了向您提供更完善、优质的产品/服务,某些功能可能由我们的服务合作方提供(如我们的第三方服务供应商、承包商、代理等),我们会委托服务合作方代表我们处理您的某些个人信息,例如委托第三方进行人脸识别等。
+          </div>
+          <div>
+            对接受我们的委托处理您个人信息的公司、组织和个人,我们会与其签署保密协定或数据处理协议,明确双方责任、处理事项和处理目的等,要求他们仅按照我们的要求、本政策以及相关的保密和安全措施来处理个人信息。如该等第三方要改变个人信息的处理目的,该等第三方应再次征求您的同意。如果您拒绝我们的服务合作方在提供服务时收集为提供服务所必需的个人信息,将可能导致您无法使用我们的产品/服务来享用该合作方提供的服务。
+          </div>
+          <div>委托处理您的个人信息的第三方SDK包括:</div>
+          <div>功能类型</div>
+          <div>第三方名称</div>
+          <div>获取信息目的</div>
+          <div>涉及个人信息范围</div>
+          <div>隐私政策链接</div>
+          <div>人脸识别</div>
+          <div>腾讯云</div>
+          <div>人脸比对</div>
+          <div>身份证照片</div>
+          <div>人脸照片</div>
+          <div class="bold">(二)共享</div>
+          <div>
+            我们不会在未经您同意或授权的情况下向任何公司、组织和个人分享您的个人信息,但是您在此同意,我们可在以下情况下共享您的个人信息:
+          </div>
+          <div>
+            1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的个人信息。
+          </div>
+          <div>
+            2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的个人信息。
+          </div>
+          <div>
+            3、与我们的关联公司共享:在本政策声明的使用目的范围内,您的个人信息可能会与我们的关联公司共享。作为一项政策,我们只会共享必要的信息。关联公司如要改变个人信息的处理目的,将再次征求您的授权同意。
+          </div>
+          <div>
+            4、与授权合作伙伴共享:仅为实现本政策中声明的目的,平台的某些服务将由平台和授权合作伙伴共同提供。平台可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。平台仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息。
+          </div>
+          <div>
+            如果为了向您提供服务而需要将您的信息共享至第三方,我们将评估该第三方收集信息的合法性、正当性、必要性。我们将要求第三方对您的信息采取保护措施,并且严格遵守相关法律法规与监管要求。平台的合作伙伴无权将共享的个人信息用于与产品或服务无关的其他用途。
+          </div>
+          <div>
+            5、祥粤云学堂服务含有到其他网站的链接。除法律另有规定外,我们对其他网站的隐私保护措施不负任何责任。平台可能在任何需要的时候增加商业伙伴或共用品牌的网站,但是提供给他们的将仅是匿名化的信息,平台将不会公开您的身份。
+          </div>
+          <div class="bold">(三)转让</div>
+          <div>
+            我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
+          </div>
+          <div>
+            1、在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;
+          </div>
+          <div>
+            2、在涉及合并、收购或破产清算时,如涉及到个人信息转让,我们会要求新的持有您个人信息的公司、组织继续受本政策的约束,否则我们将要求该公司、组织重新向您征求授权同意。
+          </div>
+          <div class="bold">(四)公开披露</div>
+          <div>我们仅会在以下情况下,公开披露您的个人信息:</div>
+          <div>1、获得您明确同意后;</div>
+          <div>
+            2、基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息。
+          </div>
+          <div class="bold">四、我们会如何保护和保存您的个人信息</div>
+          <div class="bold">(一)我们保护您个人信息的技术与措施</div>
+          <div>
+            1、为保障您的信息安全,我们会在现有技术水平下努力采取合理必要的物理、技术和行政管理方面的安全措施来保护您的信息,以防止您的信息遭受丢失、误用、非授权访问、公开披露和更改,包括但不限于SSL、信息加密存储、数据中心的访问控制、专用的网络通道及代理。
+          </div>
+          <div>
+            互联网环境并非百分之百安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
+          </div>
+          <div>
+            2、我们建立专门的管理制度、流程、组织并采取相应措施确保信息安全。例如,我们对可能接触到您的信息的员工或外包人员进行严格管理,包括但不限于根据岗位的不同采取不同的权限控制,与其签署保密协议,监控其操作情况等措施;组织对员工的数据安全或合规培训等。
+          </div>
+          <div>
+            3、若我们确认发生个人信息泄露等安全事件,我们会启动应急预案,阻止安全事件扩大,并以推送通知、公告等形式告知您。同时,我们还将按照监管部门要求上报个人信息安全事件及其处置情况。
+          </div>
+          <div class="bold">(二)我们如何保存您的个人信息</div>
+          <div>1、我们收集和产生的个人信息将存储在中华人民共和国境内。</div>
+          <div>
+            2、当我们的产品/服务发生停止运营的情况时,我们将及时停止继续收集您的个人信息,并将以推送通知或公告等形式通知您,且会对您的个人信息进行删除或匿名化处理,但国家法律法规、规章、规范性文件或政府的政策、命令等另有要求或为履行我们的合规义务而保留您的个人信息的除外。为免疑义,在产品/服务停止运营时,我们对您的个人信息删除或匿名化处理并不影响我们的关联公司基于您的同意而继续处理您的个人信息以及您届时相应地继续使用该等关联公司的服务。
+          </div>
+          <div>
+            3、我们仅会在达到本政策所述目的所必需的时限内保存您的个人信息,但为了遵守适用的法律法规、法院判决或裁定、其他有权机关的要求、维护公共利益等目的,我们可能会将个人信息保存时间予以适当延长。
+          </div>
+          <div class="bold">五、您的权利</div>
+          <div>
+            我们非常重视您对个人信息的关注,并尽全力保护您对于您个人信息访问、更正、删除以及注销账号的权利,以使您拥有充分的能力保障您的个人信息安全。您的权利包括:
+          </div>
+          <div>
+            1、您可以按照我们的相关政策及“祥粤云学堂”网站页面提示,通过网站联系方式或“个人信息”功能界面等对您的个人信息进行查询、访问、更正及删除;具体权限及方式以“祥粤云学堂”网站相关页面显示的操作要求及信息为准。同时,我们将尽一切可能采取适当的技术手段,保证收集到的有关于您的个人信息的准确性,并保证及时进行更新。
+          </div>
+          <div>
+            2、注销账户。您可注销您注册的“祥粤云学堂”账户,具体注销路径:
+          </div>
+          <div>3、响应您的请求</div>
+          <div>
+            如果您无法通过上述方式查询、访问、更正或删除您的个人信息,或您需要访问、更正或删除您在使用我们服务时所产生的其他个人信息,或您认为我们存在任何违反法律法规或与您关于个人信息的收集使用的约定,您均可以通过“祥粤云学堂”网站页面上的联系方式与我们联系。为了保障安全,我们可能需要您提供书面请求,或以其他方式证明您的身份,我们将在收到您反馈并验证您的身份后的十五个工作日内答复您的请求。
+          </div>
+          <div class="bold">六、第三方提供商及其服务</div>
+          <div>
+            为确保流畅的浏览体验,您可能会收到来自“祥粤云学堂”及其合作伙伴外部的第三方(以下简称“第三方”)提供的内容或网络链接。我们对此类第三方无控制权。您可选择是否访问第三方提供的链接、内容、产品和服务。
+          </div>
+          <div>
+            我们无法控制第三方的隐私和个人信息保护政策,此类第三方不受到本政策的约束。您在向第三方提交个人信息之前,请确保您阅读并认可这些第三方的个人信息保护政策或隐私政策。
+          </div>
+          <div class="bold">七、我们会如何处理未成年人的个人信息</div>
+          <div>
+            若您是未满18周岁的未成年人,在使用我们的产品和服务前,应事先取得您监护人的同意。但是,如果您确认自己能够完全理解本政策的全部内容且您为使用“祥粤云学堂”服务所进行的相关操作行为与您的年龄、智力相适应的,则您可以独立进行相关操作(包括向我们提交您的个人信息)。
+          </div>
+          <div>
+            我们将根据国家相关法律法规的规定保护未成年的个人信息。如果我们发现在未事先获得可证实的父母或其他监护人同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关信息。
+          </div>
+          <div class="bold">八、本政策如何更新及适用范围</div>
+          <div>
+            我们保留不时更新或修改本政策的权利,我们会在“祥粤云学堂”网站页面上发布对本政策所做的任何变更。对于重大变更,我们还会提供更为显著的通知(包括对于某些服务,我们会通过电子邮件发送通知,说明个人信息保护政策的具体变更内容)。渠道向您发送变更通知,包括但不限于网站公示、私信通知、电子邮件通知等方式。
+          </div>
+          <div>本政策所指的重大变更包括但不限于:</div>
+          <div>
+            1、我们的服务模式发生重大变化。如处理个人信息的目的、处理的个人信息类型、个人信息的使用方式等;
+          </div>
+          <div>
+            2、我们在所有权结构、组织架构等方面发生重大变化。如业务调整、破产并购等引起的所有者变更等;
+          </div>
+          <div>3、个人信息共享、转让或公开披露的主要对象发生变化;</div>
+          <div>4、您参与个人信息处理方面的权利及其行使方式发生重大变化;</div>
+          <div>
+            5、我们负责处理个人信息安全的责任部门、联络方式及投诉渠道发生变化时;
+          </div>
+          <div>6、个人信息安全影响评估报告表明存在高风险时。</div>
+          <div>
+            若您不同意修改后的个人信息保护政策,您有权并应立即停止使用“祥粤云学堂”的服务。
+          </div>
+          <div>
+            如果您继续使用“祥粤云学堂”服务,则视为您接受我们对本政策相关条款所做的修改。
+          </div>
+          <div>
+            “祥粤云学堂”的所有服务均适用本政策。但某些服务有其特定的个人信息保护政策,该等特定的个人信息保护政策更具体地说明我们在该服务中如何处理您的信息。如本政策与特定服务的个人信息保护政策有不一致之处,请以该特定个人信息保护政策为准。
+          </div>
+          <div class="bold">九、联系我们</div>
+          <div>
+            当您有个人信息相关问题或其他的投诉、建议等,可以通过如下方式与平台联系,平台将尽快审核所涉及内容,并于15个工作日内对于您的问题、投诉、建议进行回复:
+          </div>
+          <div>平台运营主体名称:广东省祥粤建设职业培训学校</div>
+          <div>注册地址:广东省广州市天河区燕岭路123号3楼</div>
+          <div>联系地址:广东省广州市天河区燕岭路123号3楼</div>
+          <div>联系电话:020-87085982、020-87085983</div>
+        </div>
+      </div>
+    </el-dialog>
+
     <Footer></Footer>
   </div>
 </template>
@@ -426,6 +908,7 @@ export default {
       loginPwdShow: false,
       registerPwdShow: false,
       forgetPwdShow: false,
+      showAgreementModal: false,
     };
   },
   computed: {
@@ -938,5 +1421,34 @@ export default {
       }
     }
   }
+
+  .agreement {
+    /deep/ .el-dialog__header {
+      display: none;
+    }
+    /deep/ .el-dialog__body {
+      padding: 0;
+      overflow: unset;
+    }
+
+    height: 100%;
+
+    &__content {
+      padding: 30px 40px 28px;
+      line-height: 24px;
+      font-size: 14px;
+      color: #666;
+
+      .bold {
+        color: #333;
+        font-size: 16px;
+        font-weight: bold;
+      }
+
+      .center {
+        text-align: center;
+      }
+    }
+  }
 }
 </style>

+ 71 - 3
src/pages/person-center/bank-record/index.vue

@@ -1,6 +1,39 @@
 <template>
   <div class="bank-record">
-    <div class="bank-record__header">做题记录</div>
+    <div class="bank-record__header">
+      <div class="title">做题记录</div>
+      <div class="content">
+        <el-select
+          clearable
+          @change="reGetExamRecordList"
+          v-model="param.goodsId"
+          placeholder="请选择"
+        >
+          <el-option
+            clearable
+            v-for="item in list"
+            :key="item.goodsId"
+            :label="item.goodsName"
+            :value="item.goodsId"
+          >
+          </el-option>
+        </el-select>
+        <el-select
+          @change="reGetExamRecordList"
+          v-model="param.paperId"
+          placeholder="请选择"
+        >
+          <el-option
+            v-for="item in list1"
+            :key="item.paperId"
+            :label="item.paperName"
+            :value="item.paperId"
+          >
+          </el-option>
+        </el-select>
+      </div>
+    </div>
+
     <div class="bank-record__body">
       <div class="bank-item" v-for="(record, index) in recordList" :key="index">
         <div class="bank-item__header">
@@ -117,18 +150,47 @@ export default {
   name: "BankRecord",
   data() {
     return {
+      list1: [],
+      list: [],
       param: {
         pageNum: 1,
         pageSize: 10,
+        goodsId: "",
+        paperId: "",
       },
       recordList: [],
       total: 0,
     };
   },
   mounted() {
+    this.listGoodsUserQuestion();
+    this.examaperList();
     this.getExamRecordList();
   },
   methods: {
+    reGetExamRecordList() {
+      this.param.pageNum = 1;
+      this.getExamRecordList();
+    },
+    examaperList() {
+      this.$request.examaperList().then((res) => {
+        this.list1 = res.rows;
+        this.list1.unshift({
+          paperId: "",
+          paperName: "全部试卷类型",
+        });
+      });
+    },
+
+    listGoodsUserQuestion() {
+      this.$request.listGoodsUserQuestion().then((res) => {
+        this.list = res.rows;
+        this.list.unshift({
+          goodsId: "",
+          goodsName: "全部题库记录",
+        });
+      });
+    },
     go(path, query) {
       this.$router.push({
         path,
@@ -225,8 +287,14 @@ export default {
 <style scoped lang="scss">
 .bank-record {
   &__header {
-    height: 56px;
-    line-height: 56px;
+    .title {
+      height: 56px;
+      line-height: 56px;
+    }
+
+    .content {
+      margin: 10px 0;
+    }
     border-bottom: 1px solid #eee;
   }
   &__body {

+ 12 - 6
src/pages/person-center/my-bank/bank-detail/index.vue

@@ -59,7 +59,13 @@
                                 <el-button
                                   v-if="section.recordStatus == -1"
                                   type="primary"
-                                  @click="toDo(section)"
+                                  @click="
+                                    toDo(
+                                      section,
+                                      chapter.chapterExamId,
+                                      item.majorId
+                                    )
+                                  "
                                   class="btn"
                                   >开始做题</el-button
                                 >
@@ -137,7 +143,7 @@
                                 <el-button
                                   v-if="section.recordStatus == -1"
                                   type="primary"
-                                  @click="toDo(section)"
+                                  @click="toDo(section, item.major, 0)"
                                   class="btn"
                                   >开始做题</el-button
                                 >
@@ -184,7 +190,7 @@
                             <el-button
                               v-if="item.recordStatus == -1"
                               type="primary"
-                              @click="toDo(item)"
+                              @click="toDo(item, 0, 0)"
                               class="btn"
                               >开始做题</el-button
                             >
@@ -700,7 +706,7 @@ export default {
     /**
      * 去做题
      */
-    async toDo(section) {
+    async toDo(section, chapterId, moduleId) {
       let count = await this.examRecordCount(section.examId || section.majorId);
       let answerNum = await this.getExamDetail(
         section.examId || section.majorId
@@ -719,8 +725,8 @@ export default {
         path: "/bank-exam/" + this.goodsId,
         query: {
           examId: section.examId || section.majorId,
-          moduleId: section.moduleId || 0,
-          chapterId: section.chapterId || 0,
+          moduleId: moduleId || 0,
+          chapterId: chapterId || 0,
           orderGoodsId: this.orderGoodsId,
         },
       });

+ 5 - 0
src/pages/person-center/my-bank/bank-explain-detail/index.vue

@@ -1130,6 +1130,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 16 - 1
src/pages/person-center/my-classhour/appointment-add/index.vue

@@ -37,8 +37,19 @@
             <el-select v-model="timeIndex" placeholder="请选择">
               <el-option
                 :label="
-                  item.dataTime + ' ' + item.startTime + ' ~ ' + item.endTime
+                  item.dataTime +
+                  ' ' +
+                  item.startTime +
+                  ' ~ ' +
+                  item.endTime +
+                  `已报:${item.registration}/ ${item.num} ` +
+                  (item.status === 2
+                    ? '预约名额已满'
+                    : item.status === 1
+                    ? '此时段您已经有其他考试预约'
+                    : '')
                 "
+                :disabled="item.status !== 0"
                 :value="index"
                 v-for="(item, index) in activeList"
                 :key="index"
@@ -281,6 +292,10 @@ export default {
         border: 1px solid #eeeeee;
         box-shadow: 0px 0px 7px 1px rgba(0, 0, 0, 0.04);
         border-radius: 8px;
+
+        .el-select {
+          width: 300px;
+        }
       }
 
       &__footer {

+ 2 - 1
src/pages/person-center/my-classhour/appointment/index.vue

@@ -29,7 +29,7 @@
               listData.applyIntroduce || ""
             }}</el-descriptions-item>
             <el-descriptions-item label="报考专业" :span="2">{{
-              listData.major || ""
+              listData.major
             }}</el-descriptions-item>
             <el-descriptions-item label="姓名">
               {{ listData.realname }}
@@ -153,6 +153,7 @@ export default {
                         showCancel: false,
                         content: "请联系管理员配置补考商品",
                       });
+                    } else {
                     }
                     // this.$router.push({
                     //   path: "/payment-success",

+ 9 - 3
src/pages/person-center/my-classhour/index/index.vue

@@ -225,7 +225,7 @@
                   </div> -->
                   <div class="desc">
                     原因:
-                    <span class="note">拍照异常/时间异常</span>
+                    <span class="note">{{ item.auditReason }}</span>
                   </div>
                 </div>
               </div>
@@ -365,6 +365,7 @@ export default {
               this.$router.push({
                 path: `/my-course-detail/${this.rebuildItem.goodsId}`,
                 query: {
+                  rebuild: "1",
                   gradeId: this.rebuildItem.gradeId,
                   orderGoodsId: this.rebuildItem.orderGoodsId,
                 },
@@ -406,24 +407,29 @@ export default {
         });
 
       let sysTime = this.$tools.timest();
-      if (item.serviceEndTime && item.serviceEndTime < sysTime) {
+      if (item.serviceEndTime && item.serviceEndTime > +sysTime) {
+        console.log(1);
         this.rebuildShow = true;
       } else {
+        console.log(2);
         this.rebuildShow = false;
         this.showDetailModal = true;
         return;
       }
 
       if (item.classEndTime) {
-        if (item.classEndTime < sysTime) {
+        if (item.classEndTime < +sysTime) {
+          console.log(3);
           this.rebuildShow = true;
         } else {
           this.rebuildShow = false;
+          console.log(4);
           this.showDetailModal = true;
           return;
         }
       } else {
       }
+
       this.showDetailModal = true;
     },
 

+ 37 - 10
src/pages/person-center/my-course/index.vue

@@ -506,6 +506,27 @@
         </div>
       </div>
     </el-dialog>
+
+    <el-dialog
+      title="提示"
+      class="exercises-modal"
+      :visible.sync="showExercisesModal"
+      width="800px"
+    >
+      <div class="exercises-modal__content">
+        <div>1.不支持网页端刷题</div>
+        <div>2.请使用手机扫码,进入【祥粤云学堂】小程序环境,进行刷题</div>
+        <div>
+          <img src="@/assets/xcxqrcode.jpg" alt="" />
+        </div>
+      </div>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="showExercisesModal = false"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -534,6 +555,7 @@ export default {
       courseList: [],
       selectItem: {},
       loading: null,
+      showExercisesModal: false,
     };
   },
   computed: {
@@ -739,16 +761,7 @@ export default {
     },
 
     appBeforeAddress(item) {
-      this.$request
-        .appBeforeAddress({
-          orderGoodsId: item.orderGoodsId,
-        })
-        .then((res) => {
-          window.open(res.url, "_blank");
-        })
-        .catch((err) => {
-          this.$message.warning(err.msg);
-        });
+      this.showExercisesModal = true;
     },
 
     rebuildSubmit() {
@@ -1281,5 +1294,19 @@ export default {
       }
     }
   }
+
+  .exercises-modal {
+    &__content {
+      > div {
+        font-size: 16px;
+        line-height: 30px;
+        text-align: center;
+
+        img {
+          display: inline;
+        }
+      }
+    }
+  }
 }
 </style>

+ 21 - 1
src/pages/person-center/my-examination/index.vue

@@ -147,7 +147,7 @@
             :key="index"
             @click="resultChange(item, index)"
           >
-            {{ item.label }}
+            {{ item.label }} {{ item.count ? `(${item.count})` : "" }}
           </div>
         </div>
 
@@ -379,6 +379,26 @@ export default {
         .then((res) => {
           this.examList[2].count = res.total;
         });
+
+      this.$request
+        .getApplylist({
+          pageNum: 1,
+          pageSize: 1,
+          result: 1,
+        })
+        .then((res) => {
+          this.resultList[0].count = res.total;
+        });
+
+      this.$request
+        .getApplylist({
+          pageNum: 1,
+          pageSize: 1,
+          result: 0,
+        })
+        .then((res) => {
+          this.resultList[1].count = res.total;
+        });
     },
     tabChange(e) {
       if (this.activeName == e.name) {

+ 27 - 18
src/pages/person-center/my-invoice/add/index.vue

@@ -75,9 +75,16 @@
           <el-form-item label="发票抬头:" required prop="invoiceTitle">
             <el-input v-model="form.invoiceTitle"></el-input>
           </el-form-item>
-          <el-form-item label="纳税登记号:" required prop="taxRegistryNumber">
-            <el-input v-model="form.taxRegistryNumber"></el-input>
-          </el-form-item>
+
+          <template v-if="form.subject == 2">
+            <el-form-item
+              label="纳税登记号:"
+              required
+              prop="taxRegistryNumber"
+            >
+              <el-input v-model="form.taxRegistryNumber"></el-input>
+            </el-form-item>
+          </template>
 
           <template v-if="form.type == 2">
             <el-form-item label="单位地址:" required prop="companyAddress">
@@ -158,7 +165,7 @@ export default {
             required: true,
             message: "请输入收件手机",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
           {
             validator: (rule, value, callback) => {
@@ -171,7 +178,7 @@ export default {
               }
             },
             // 触发器可以同时用blur和change
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         type: [
@@ -179,7 +186,7 @@ export default {
             required: true,
             message: "请选择发票类型",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         subject: [
@@ -187,7 +194,7 @@ export default {
             required: true,
             message: "请选择申请主体",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         invoiceTitle: [
@@ -195,7 +202,7 @@ export default {
             required: true,
             message: "请输入发票抬头",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         taxRegistryNumber: [
@@ -203,7 +210,7 @@ export default {
             required: true,
             message: "请输入纳税登记号",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
           {
             validator: (rule, value, callback) => {
@@ -215,7 +222,7 @@ export default {
               }
             },
             // 触发器可以同时用blur和change
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         companyAddress: [
@@ -223,7 +230,7 @@ export default {
             required: true,
             message: "请输入单位地址",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         phone: [
@@ -231,7 +238,7 @@ export default {
             required: true,
             message: "请输入电话号码",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         bankName: [
@@ -239,7 +246,7 @@ export default {
             required: true,
             message: "请输入开户银行",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
           {
             validator: (rule, value, callback) => {
@@ -258,7 +265,7 @@ export default {
             required: true,
             message: "请输入银行账号",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
           {
             validator: (rule, value, callback) => {
@@ -271,7 +278,7 @@ export default {
               }
             },
             // 触发器可以同时用blur和change
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         receivingAddress: [
@@ -279,7 +286,7 @@ export default {
             required: true,
             message: "请输入收件地址",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         receivingName: [
@@ -287,7 +294,7 @@ export default {
             required: true,
             message: "请输入收件人",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
         orderGoodsIds: [
@@ -295,7 +302,7 @@ export default {
             required: true,
             message: "请选择订单",
             // 可以单个或者同时写两个触发验证方式
-            trigger: ["change"],
+            trigger: ["change", "blur"],
           },
         ],
       },
@@ -310,6 +317,8 @@ export default {
     changeType(e) {
       if (this.form.type == "2") {
         this.form.subject = "2";
+      } else {
+        this.form.subject = "1";
       }
     },
     changeSelect(e) {

+ 152 - 122
src/pages/person-center/my-invoice/index/index.vue

@@ -60,7 +60,7 @@
         <el-table-column align="center" header-align="center" label="开票订单">
           <template slot-scope="scope">
             <div v-for="(item, index) in scope.row.orderList" :key="index">
-              {{ item.orderSn }}
+              {{ index + 1 }}.{{ item.goodsName }}
             </div>
           </template>
         </el-table-column>
@@ -134,131 +134,152 @@
       :visible.sync="invoiceDetailModal"
       custom-class="invoice-modal"
     >
-      <el-descriptions title="发票申请信息" :column="2">
-        <el-descriptions-item label="发票类型"
-          ><span v-if="invoiceDetail.type == 1">普通发票</span>
-          <span v-if="invoiceDetail.type == 2"
-            >增值税专用发票</span
-          ></el-descriptions-item
-        >
-        <el-descriptions-item label="申请主体"
-          ><span v-if="invoiceDetail.subject == 1">个人</span>
-          <span v-if="invoiceDetail.subject == 2"
-            >企业</span
-          ></el-descriptions-item
-        >
-        <el-descriptions-item label="发票抬头">{{
-          invoiceDetail.invoiceTitle
-        }}</el-descriptions-item>
+      <el-row>
+        <el-col :span="12">
+          <el-descriptions title="发票申请信息" :column="1">
+            <el-descriptions-item label="发票类型"
+              ><span v-if="invoiceDetail.type == 1">普通发票</span>
+              <span v-if="invoiceDetail.type == 2"
+                >增值税专用发票</span
+              ></el-descriptions-item
+            >
+            <el-descriptions-item label="申请主体"
+              ><span v-if="invoiceDetail.subject == 1">个人</span>
+              <span v-if="invoiceDetail.subject == 2"
+                >企业</span
+              ></el-descriptions-item
+            >
+            <el-descriptions-item label="发票抬头">{{
+              invoiceDetail.invoiceTitle
+            }}</el-descriptions-item>
 
-        <el-descriptions-item label="开票订单"> </el-descriptions-item>
+            <template v-if="invoiceDetail.subject == 2">
+              <el-descriptions-item label="纳税登记号">
+                {{ invoiceDetail.taxRegistryNumber || "" }}
+              </el-descriptions-item>
+            </template>
 
-        <el-descriptions-item label="开票金额">
-          ¥ {{ invoiceDetail.amount }}
-        </el-descriptions-item>
+            <el-descriptions-item label="开票订单">
+              <div
+                class="order-item"
+                v-for="(orderItem, orderIndex) in invoiceDetail.orderList"
+                :key="orderIndex"
+              >
+                <div>{{ orderItem.goodsName }}</div>
+                <div>{{ orderItem.orderSn }}</div>
+                <div>¥{{ orderItem.goodsRealPrice | toFixed }}</div>
+              </div>
+            </el-descriptions-item>
 
-        <template v-if="invoiceDetail.type == 2">
-          <el-descriptions-item label="纳税登记号">
-            {{ invoiceDetail.taxRegistryNumber || "" }}
-          </el-descriptions-item>
-          <el-descriptions-item label="单位地址">{{
-            invoiceDetail.companyAddress || ""
-          }}</el-descriptions-item
-          ><el-descriptions-item label="电话号码">{{
-            invoiceDetail.phone || ""
-          }}</el-descriptions-item
-          ><el-descriptions-item label="开户银行">{{
-            invoiceDetail.bankName || ""
-          }}</el-descriptions-item
-          ><el-descriptions-item label="银行账号">{{
-            invoiceDetail.bankAccount || ""
-          }}</el-descriptions-item
-          ><el-descriptions-item label="收件地址">{{
-            invoiceDetail.receivingAddress || ""
-          }}</el-descriptions-item
-          ><el-descriptions-item label="收件人">{{
-            invoiceDetail.receivingName || ""
-          }}</el-descriptions-item
-          ><el-descriptions-item label="收件手机">{{
-            invoiceDetail.receivingTel || ""
-          }}</el-descriptions-item>
-        </template>
-      </el-descriptions>
+            <el-descriptions-item label="开票金额">
+              ¥ {{ invoiceDetail.amount | toFixed }}
+            </el-descriptions-item>
 
-      <el-descriptions title="发票申请结果" :column="1">
-        <el-descriptions-item label="审核结果">
-          <span class="text wait" v-if="invoiceDetail.periodStatus == 1"
-            >待审核</span
-          >
-          <span class="text agree" v-if="invoiceDetail.periodStatus == 3"
-            >通过</span
-          >
-          <span class="text refuse" v-if="invoiceDetail.periodStatus == 2"
-            >驳回</span
-          >
-        </el-descriptions-item>
-        <el-descriptions-item label="审核反馈">{{
-          invoiceDetail.periodReason || ""
-        }}</el-descriptions-item>
-        <el-descriptions-item label="发票状态">
-          <span class="text refuse" v-if="invoiceDetail.invoiceStatus == 1"
-            >未开票</span
-          >
-          <span class="text agree" v-if="invoiceDetail.invoiceStatus == 2"
-            >已开票</span
-          >
-          <span class="text refuse" v-if="invoiceDetail.invoiceStatus == -1"
-            >已退票</span
-          >
-        </el-descriptions-item>
-        <el-descriptions-item
-          label="发票预览"
-          v-if="
-            invoiceDetail.periodStatus == 3 &&
-            (invoiceDetail.invoiceStatus == 2 ||
-              invoiceDetail.invoiceStatus == -1) &&
-            invoiceDetail.invoiceImg
-          "
-        >
-          <div class="preview-wrap">
-            <img
-              class="preview"
-              :src="$tools.splitImgHost(invoiceDetail.invoiceImg)"
-            />
-          </div>
+            <template v-if="invoiceDetail.type == 2">
+              <el-descriptions-item label="单位地址">{{
+                invoiceDetail.companyAddress || ""
+              }}</el-descriptions-item
+              ><el-descriptions-item label="电话号码">{{
+                invoiceDetail.phone || ""
+              }}</el-descriptions-item
+              ><el-descriptions-item label="开户银行">{{
+                invoiceDetail.bankName || ""
+              }}</el-descriptions-item
+              ><el-descriptions-item label="银行账号">{{
+                invoiceDetail.bankAccount || ""
+              }}</el-descriptions-item
+              ><el-descriptions-item label="收件地址">{{
+                invoiceDetail.receivingAddress || ""
+              }}</el-descriptions-item
+              ><el-descriptions-item label="收件人">{{
+                invoiceDetail.receivingName || ""
+              }}</el-descriptions-item
+              ><el-descriptions-item label="收件手机">{{
+                invoiceDetail.receivingTel || ""
+              }}</el-descriptions-item>
+            </template>
+          </el-descriptions>
+        </el-col>
+        <el-col :span="12">
+          <el-descriptions title="发票申请结果" :column="1">
+            <el-descriptions-item label="审核结果">
+              <span class="text wait" v-if="invoiceDetail.periodStatus == 1"
+                >待审核</span
+              >
+              <span class="text agree" v-if="invoiceDetail.periodStatus == 3"
+                >通过</span
+              >
+              <span class="text refuse" v-if="invoiceDetail.periodStatus == 2"
+                >驳回</span
+              >
+            </el-descriptions-item>
+            <el-descriptions-item label="审核反馈">{{
+              invoiceDetail.periodReason || ""
+            }}</el-descriptions-item>
+            <el-descriptions-item label="发票状态">
+              <span class="text refuse" v-if="invoiceDetail.invoiceStatus == 1"
+                >未开票</span
+              >
+              <span class="text agree" v-if="invoiceDetail.invoiceStatus == 2"
+                >已开票</span
+              >
+              <span class="text refuse" v-if="invoiceDetail.invoiceStatus == -1"
+                >已退票</span
+              >
+            </el-descriptions-item>
+            <el-descriptions-item
+              label="发票预览"
+              v-if="
+                invoiceDetail.periodStatus == 3 &&
+                (invoiceDetail.invoiceStatus == 2 ||
+                  invoiceDetail.invoiceStatus == -1) &&
+                invoiceDetail.invoiceImg
+              "
+            >
+              <div class="preview-wrap">
+                <el-image
+                  class="preview"
+                  :src="$tools.splitImgHost(invoiceDetail.invoiceImg)"
+                  :preview-src-list="[
+                    $tools.splitImgHost(invoiceDetail.invoiceImg),
+                  ]"
+                ></el-image>
+              </div>
 
-          <el-button type="primary" @click="download(invoiceDetail)"
-            >下载电子发票</el-button
-          >
-        </el-descriptions-item>
-        <el-descriptions-item
-          label="机构发票邮寄状态"
-          v-if="
-            invoiceDetail.periodStatus == 3 &&
-            (invoiceDetail.invoiceStatus == 2 ||
-              invoiceDetail.invoiceStatus == -1) &&
-            invoiceDetail.type == 2 &&
-            invoiceDetail.subject == 2
-          "
-        >
-          <span class="text" v-if="invoiceDetail.sendInvoice == 1">是</span>
-          <span class="text" v-else>否</span>
-        </el-descriptions-item>
+              <el-button type="primary" @click="download(invoiceDetail)"
+                >下载电子发票</el-button
+              >
+            </el-descriptions-item>
+            <el-descriptions-item
+              label="机构发票邮寄状态"
+              v-if="
+                invoiceDetail.periodStatus == 3 &&
+                (invoiceDetail.invoiceStatus == 2 ||
+                  invoiceDetail.invoiceStatus == -1) &&
+                invoiceDetail.type == 2 &&
+                invoiceDetail.subject == 2
+              "
+            >
+              <span class="text" v-if="invoiceDetail.sendInvoice == 1">是</span>
+              <span class="text" v-else>否</span>
+            </el-descriptions-item>
 
-        <el-descriptions-item
-          label="发票邮寄快递单号:(点击可复制)"
-          v-if="
-            invoiceDetail.periodStatus == 3 &&
-            (invoiceDetail.invoiceStatus == 2 ||
-              invoiceDetail.invoiceStatus == -1) &&
-            invoiceDetail.sendInvoice == 1 &&
-            invoiceDetail.type == 2 &&
-            invoiceDetail.subject == 2
-          "
-        >
-          {{ invoiceDetail.trackingNum }}
-        </el-descriptions-item>
-      </el-descriptions>
+            <el-descriptions-item
+              label="发票邮寄快递单号:(点击可复制)"
+              v-if="
+                invoiceDetail.periodStatus == 3 &&
+                (invoiceDetail.invoiceStatus == 2 ||
+                  invoiceDetail.invoiceStatus == -1) &&
+                invoiceDetail.sendInvoice == 1 &&
+                invoiceDetail.type == 2 &&
+                invoiceDetail.subject == 2
+              "
+            >
+              {{ invoiceDetail.trackingNum }}
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-col>
+      </el-row>
 
       <span slot="footer" class="dialog-footer">
         <el-button
@@ -280,7 +301,9 @@ export default {
   name: "MyInvoice",
   data() {
     return {
-      invoiceDetail: {},
+      invoiceDetail: {
+        amount: 0,
+      },
       invoiceDetailModal: false,
       tableData: [],
       params: {
@@ -418,7 +441,7 @@ export default {
 
   .invoice-modal {
     .preview-wrap {
-      img {
+      /deep/ img {
         max-width: 200px;
       }
     }
@@ -434,6 +457,13 @@ export default {
         color: #34c759;
       }
     }
+
+    .order-item {
+      background: #ccc;
+      padding: 5px 10px;
+      border-radius: 10px;
+      margin-top: 10px;
+    }
   }
 }
 </style>

+ 11 - 11
src/pages/person-center/my-message/index.vue

@@ -242,7 +242,7 @@
                     >
                     {{ index + 1 }}、{{ item.name }}
                   </div>
-                  <div class="desc">
+                  <!-- <div class="desc">
                     <div class="imgs">
                       <div
                         class="img"
@@ -255,10 +255,10 @@
                         </div>
                       </div>
                     </div>
-                  </div>
+                  </div> -->
                   <div class="desc">
                     原因:
-                    <span class="note">拍照异常/时间异常</span>
+                    <span class="note">{{ item.auditReason }}</span>
                   </div>
                 </div>
               </div>
@@ -267,7 +267,7 @@
         </div>
         <div class="rebuild__footer">
           <el-button class="confirm" @click="rebuildSubmit" type="primary"
-            >确认重学</el-button
+            >确认已阅读</el-button
           >
         </div>
       </div>
@@ -437,15 +437,15 @@ export default {
             let currentTime = this.$tools.timest();
             console.log(currentTime);
             console.log(item);
-            console.log(item.studyStartTime);
-            console.log(item.studyEndTime);
+            console.log(item.serviceStartTime);
+            console.log(item.serviceEndTime);
             console.log(
-              currentTime < item.studyStartTime ||
-                currentTime > item.studyEndTime
+              currentTime < item.serviceStartTime ||
+                currentTime > item.serviceEndTime
             );
             if (
-              currentTime < item.studyStartTime ||
-              currentTime > item.studyEndTime
+              currentTime < item.serviceStartTime ||
+              currentTime > item.serviceEndTime
             ) {
               this.$message({
                 type: "warning",
@@ -495,7 +495,7 @@ export default {
             if (
               item.gradeStatus == 1 &&
               item.status == 1 &&
-              item.studyEndTime > currentTime &&
+              item.serviceEndTime > currentTime &&
               item.classEndTime &&
               item.classEndTime < currentTime &&
               (item.periodStatus == 0 || item.periodStatus == -1) &&

+ 20 - 1
src/pages/person-center/my-order/index.vue

@@ -16,6 +16,14 @@
         <div class="no-data">您暂无相关订单哦~</div>
       </div>
       <div class="list" v-else>
+        <template v-if="activeName == '2' && orderList.length">
+          <el-button
+            type="primary"
+            class="invoice"
+            @click="go('/person-center/my-invoice')"
+            >发票申请</el-button
+          >
+        </template>
         <div class="order-item" v-for="(item, index) in orderList" :key="index">
           <div class="order-item__header">
             <div class="state">
@@ -71,7 +79,15 @@
                   <div class="price-number">${{ item.payPrice }}</div>
                 </div>
               </div>
-              <div class="btns-wrap">
+              <div
+                class="btns-wrap"
+                v-if="
+                  (item.orderStatus === 0 &&
+                    (item.orderFrom === 2 || item.orderFrom === 3)) ||
+                  ((item.orderStatus === -1 || item.orderStatus === -2) &&
+                    (item.orderFrom === 2 || item.orderFrom === 3))
+                "
+              >
                 <div class="btns">
                   <el-button
                     type="primary"
@@ -457,6 +473,9 @@ export default {
     }
   }
   &__body {
+    .invoice {
+      margin-top: 10px;
+    }
     .list {
       .order-item {
         margin-top: 24px;

+ 6 - 0
src/pages/person-center/play-record/index.vue

@@ -132,6 +132,12 @@ export default {
             dateObj[row.date].list.push(row);
           }
         });
+
+        // for (let k in dateObj) {
+        //   dateObj[k].list.sort((a, b) => {
+        //     return a.createTime - b.createTime;
+        //   });
+        // }
         this.recordList = dateObj;
         this.total = res.total;
       });

+ 5 - 0
src/pages/subject/collect-bank.vue

@@ -1574,6 +1574,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 5 - 0
src/pages/subject/collect-type-bank.vue

@@ -1571,6 +1571,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 5 - 0
src/pages/subject/wrong-bank.vue

@@ -1573,6 +1573,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 5 - 0
src/pages/subject/wrong-type-bank.vue

@@ -1564,6 +1564,11 @@ export default {
                   font-weight: 400;
                   color: #666666;
                   line-height: 24px;
+
+                  /deep/ img {
+                    max-width: 100% !important;
+                    max-height: 400px !important;
+                  }
                 }
 
                 &__content {

+ 8 - 0
src/store/index.js

@@ -1,6 +1,7 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
 import login from '@/apis/login'
+import user from '@/apis/user'
 import common from '@/apis/common'
 
 Vue.use(Vuex);
@@ -8,6 +9,7 @@ Vue.use(Vuex);
 export default new Vuex.Store({
   //所有的数据都放在state中
   state: {
+    cartCount:0,
     applyData: {}, //预约考试数据存放
     currentRouter:{},
     token: '',
@@ -32,6 +34,7 @@ export default new Vuex.Store({
     getApplyData: state => state.applyData,
     examResult: state => state.examResult,
     currentRouter: state => state.currentRouter,
+    cartCount: state => state.cartCount
   },
 
   //操作数据,唯一的通道是mutations
@@ -66,6 +69,11 @@ export default new Vuex.Store({
           console.log(state.links)
         }
       })
+    },
+    getCartCount(state) {
+      user.cartList().then((res) => {
+        state.cartCount = res.total;
+      });
     }
   },