Ver código fonte

Merge branch 'master' of https://git.cocorobo.cn/CocoRoboLabs/pbl-app

lsc 1 mês atrás
pai
commit
2a82fc6969
69 arquivos alterados com 436 adições e 44 exclusões
  1. 1 0
      dist/index.html
  2. 4 0
      dist/report.html
  3. 0 0
      dist/static/css/app.970aed35.css
  4. 0 0
      dist/static/css/chunk-567be178.e4bd5565.css
  5. 0 0
      dist/static/css/chunk-bd5ed284.ce137eb8.css
  6. 0 0
      dist/static/img/Union.b0ea0f49.svg
  7. 0 0
      dist/static/img/delFile.ec8981b7.svg
  8. 0 0
      dist/static/img/videoFile.22737868.svg
  9. 1 0
      dist/static/js/app.571b38e7.js
  10. 0 0
      dist/static/js/app.cbfcca3d.js
  11. 0 0
      dist/static/js/chunk-00b34a2c.142aec23.js
  12. 0 0
      dist/static/js/chunk-01979dd3.c9735726.js
  13. 0 0
      dist/static/js/chunk-01979dd3.f3236b6c.js
  14. 0 0
      dist/static/js/chunk-01c5f272.88585159.js
  15. 0 0
      dist/static/js/chunk-03851ecf.5eb3ff76.js
  16. 0 0
      dist/static/js/chunk-03851ecf.da18759c.js
  17. 0 0
      dist/static/js/chunk-07b980da.1b24e096.js
  18. 0 0
      dist/static/js/chunk-0e29728a.96decce4.js
  19. 0 0
      dist/static/js/chunk-0e29728a.c1f229f5.js
  20. 0 0
      dist/static/js/chunk-1678db47.47c3da04.js
  21. 0 0
      dist/static/js/chunk-1738a278.c6165126.js
  22. 0 0
      dist/static/js/chunk-18ea3bfa.3e52dd8b.js
  23. 0 0
      dist/static/js/chunk-1a806098.d2a1990d.js
  24. 0 0
      dist/static/js/chunk-1aab73ec.b8834f63.js
  25. 0 0
      dist/static/js/chunk-1aab73ec.c47551a9.js
  26. 0 0
      dist/static/js/chunk-247d1cc7.072a525c.js
  27. 0 0
      dist/static/js/chunk-247d1cc7.0f517fcd.js
  28. 0 0
      dist/static/js/chunk-284ddcf3.128f71f9.js
  29. 0 0
      dist/static/js/chunk-2ba95b61.3d5d69bd.js
  30. 0 0
      dist/static/js/chunk-2d0c7336.5464938b.js
  31. 0 0
      dist/static/js/chunk-2d0c7336.707392c1.js
  32. 0 0
      dist/static/js/chunk-2d0dea77.48eecd6e.js
  33. 0 0
      dist/static/js/chunk-2fc6aeae.4edebcec.js
  34. 1 1
      dist/static/js/chunk-30b5de98.860bd1e3.js
  35. 0 0
      dist/static/js/chunk-55e3fa90.675c073d.js
  36. 0 0
      dist/static/js/chunk-55e3fa90.c8d9c3e3.js
  37. 0 0
      dist/static/js/chunk-567be178.2e835912.js
  38. 0 0
      dist/static/js/chunk-5bb2a616.61a39d29.js
  39. 0 0
      dist/static/js/chunk-60b2ab15.42658972.js
  40. 0 0
      dist/static/js/chunk-67c4ee97.8186b79c.js
  41. 0 0
      dist/static/js/chunk-6ad98842.fc9cdce4.js
  42. 0 0
      dist/static/js/chunk-6e5f7eb4.1ad93511.js
  43. 0 0
      dist/static/js/chunk-793d7e56.8d988c23.js
  44. 0 0
      dist/static/js/chunk-7caf3a38.6dd4ba1b.js
  45. 0 0
      dist/static/js/chunk-7d4543c8.0a8e2249.js
  46. 0 0
      dist/static/js/chunk-7f794d4e.da2e5d01.js
  47. 0 0
      dist/static/js/chunk-81a47c5e.f9e0b7c9.js
  48. 0 0
      dist/static/js/chunk-870f2882.153b86ef.js
  49. 0 0
      dist/static/js/chunk-970a3cc0.88660119.js
  50. 0 0
      dist/static/js/chunk-b265f6f8.dba591eb.js
  51. 0 0
      dist/static/js/chunk-b40d50ca.95fb3681.js
  52. 0 0
      dist/static/js/chunk-bd5ed284.745a410f.js
  53. 0 0
      dist/static/js/chunk-c3be65e4.7153bb72.js
  54. 0 0
      dist/static/js/chunk-d3f058fe.3dca97b5.js
  55. 0 0
      dist/static/js/chunk-d3f058fe.9bf03846.js
  56. 0 0
      dist/static/js/chunk-d4d28b52.a52318d9.js
  57. 0 0
      dist/static/js/chunk-libs.4406bd5f.js
  58. 0 0
      dist/static/js/chunk-libs.d370c650.js
  59. 1 0
      package.json
  60. 10 0
      src/api/wechat.js
  61. 193 0
      src/components/qrScanner.vue
  62. 10 2
      src/components/sweepPage_html5_qrcode.vue
  63. 104 0
      src/components/weChatQrcode.vue
  64. 15 1
      src/main.js
  65. 8 2
      src/views/testDetail/components/choice.vue
  66. 6 0
      src/views/testDetail/components/file.vue
  67. 11 2
      src/views/testDetail/components/gap.vue
  68. 34 14
      src/views/testDetail/components/punchQRcode.vue
  69. 37 22
      src/views/testDetail/components/sweep.vue

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 0
dist/index.html


Diferenças do arquivo suprimidas por serem muito extensas
+ 4 - 0
dist/report.html


+ 0 - 0
dist/static/css/app.ba4eed89.css → dist/static/css/app.970aed35.css


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/css/chunk-567be178.e4bd5565.css


+ 0 - 0
dist/static/css/chunk-7f794d4e.ce137eb8.css → dist/static/css/chunk-bd5ed284.ce137eb8.css


+ 0 - 0
dist/static/img/Union.953680c6.svg → dist/static/img/Union.b0ea0f49.svg


+ 0 - 0
dist/static/img/delFile.b454d74e.svg → dist/static/img/delFile.ec8981b7.svg


+ 0 - 0
dist/static/img/videoFile.8b2406f2.svg → dist/static/img/videoFile.22737868.svg


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 0
dist/static/js/app.571b38e7.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/app.cbfcca3d.js


+ 0 - 0
dist/static/js/chunk-00b34a2c.c7e8b15a.js → dist/static/js/chunk-00b34a2c.142aec23.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-01979dd3.c9735726.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-01979dd3.f3236b6c.js


+ 0 - 0
dist/static/js/chunk-01c5f272.14c996b9.js → dist/static/js/chunk-01c5f272.88585159.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-03851ecf.5eb3ff76.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-03851ecf.da18759c.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-07b980da.1b24e096.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-0e29728a.96decce4.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-0e29728a.c1f229f5.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1678db47.47c3da04.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1738a278.c6165126.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-18ea3bfa.3e52dd8b.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1a806098.d2a1990d.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1aab73ec.b8834f63.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-1aab73ec.c47551a9.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-247d1cc7.072a525c.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-247d1cc7.0f517fcd.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-284ddcf3.128f71f9.js


+ 0 - 0
dist/static/js/chunk-2ba95b61.ecd74c0b.js → dist/static/js/chunk-2ba95b61.3d5d69bd.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2d0c7336.5464938b.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2d0c7336.707392c1.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2d0dea77.48eecd6e.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-2fc6aeae.4edebcec.js


+ 1 - 1
dist/static/js/chunk-30b5de98.42d056b7.js → dist/static/js/chunk-30b5de98.860bd1e3.js

@@ -1 +1 @@
-(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-30b5de98"],{"6f03":function(t,e,i){},"730a":function(t,e,i){"use strict";i.r(e);i("b0c0");var s=function(){var t=this,e=t._self._c;return e("div",{staticClass:"home-container"},[e("head-bar",{on:{back:t.back},scopedSlots:t._u([{key:"title",fn:function(){return[e("div",{staticClass:"navTitle"},[t._v("查看问卷")])]},proxy:!0}])}),e("div",{staticClass:"step_box"},[e("topicVue",{attrs:{cJson:t.cJson,title:t.name,brief:t.brief,checktype:2,see:t.see}})],1)],1)},c=[],n=i("5530"),o=(i("14d9"),i("e9c4"),i("b64b"),i("98e5")),r=i("71ed"),a=i("2f62"),u=i("bf3a"),d={components:{headBar:r["a"],topicVue:u["a"]},data:function(){return{courseid:this.$route.query.courseid,tid:this.$route.query.tid,name:this.$route.query.name,title:"",brief:"",cJson:[],see:!1}},computed:Object(n["a"])({},Object(a["c"])(["userinfo"])),methods:{back:function(){this.$router.push({path:"/test"})},getData:function(){var t=this,e={cid:this.courseid,tid:this.tid};Object(o["g"])(e).then((function(e){e[1].length&&(t.cJson=JSON.parse(e[1][0].courseJson)),t.title=e[0][0].title,t.brief=e[0][0].brief,t.see=1==e[0][0].open,t.$forceUpdate()})).catch((function(t){console.error(t)}))},publish:function(){var t=this,e=this.$refs["topicVue"].checkArray,i=[{uid:this.userinfo.userid,cid:this.courseid,cjson:JSON.stringify(e),type:2}];Object(o["a"])(i).then((function(e){t.$message.success("提交成功"),t.back()})).catch((function(t){console.error(t)}))}},mounted:function(){this.getData()}},f=d,h=(i("a998"),i("2877")),b=Object(h["a"])(f,s,c,!1,null,"55bd9d6e",null);e["default"]=b.exports},a998:function(t,e,i){"use strict";i("6f03")}}]);
+(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-30b5de98"],{"6f03":function(t,e,i){},"730a":function(t,e,i){"use strict";i.r(e);i("b0c0");var s=function(){var t=this,e=t._self._c;return e("div",{staticClass:"home-container"},[e("head-bar",{on:{back:t.back},scopedSlots:t._u([{key:"title",fn:function(){return[e("div",{staticClass:"navTitle"},[t._v("查看问卷")])]},proxy:!0}])}),e("div",{staticClass:"step_box"},[e("topicVue",{attrs:{cJson:t.cJson,title:t.name,brief:t.brief,checktype:2,see:t.see}})],1)],1)},c=[],n=i("5530"),o=(i("14d9"),i("b64b"),i("e9c4"),i("98e5")),r=i("71ed"),a=i("2f62"),u=i("bf3a"),d={components:{headBar:r["a"],topicVue:u["a"]},data:function(){return{courseid:this.$route.query.courseid,tid:this.$route.query.tid,name:this.$route.query.name,title:"",brief:"",cJson:[],see:!1}},computed:Object(n["a"])({},Object(a["c"])(["userinfo"])),methods:{back:function(){this.$router.push({path:"/test"})},getData:function(){var t=this,e={cid:this.courseid,tid:this.tid};Object(o["g"])(e).then((function(e){e[1].length&&(t.cJson=JSON.parse(e[1][0].courseJson)),t.title=e[0][0].title,t.brief=e[0][0].brief,t.see=1==e[0][0].open,t.$forceUpdate()})).catch((function(t){console.error(t)}))},publish:function(){var t=this,e=this.$refs["topicVue"].checkArray,i=[{uid:this.userinfo.userid,cid:this.courseid,cjson:JSON.stringify(e),type:2}];Object(o["a"])(i).then((function(e){t.$message.success("提交成功"),t.back()})).catch((function(t){console.error(t)}))}},mounted:function(){this.getData()}},f=d,h=(i("a998"),i("2877")),b=Object(h["a"])(f,s,c,!1,null,"55bd9d6e",null);e["default"]=b.exports},a998:function(t,e,i){"use strict";i("6f03")}}]);

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-55e3fa90.675c073d.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-55e3fa90.c8d9c3e3.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-567be178.2e835912.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-5bb2a616.61a39d29.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-60b2ab15.42658972.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-67c4ee97.8186b79c.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-6ad98842.fc9cdce4.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-6e5f7eb4.1ad93511.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-793d7e56.8d988c23.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-7caf3a38.6dd4ba1b.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-7d4543c8.0a8e2249.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-7f794d4e.da2e5d01.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-81a47c5e.f9e0b7c9.js


+ 0 - 0
dist/static/js/chunk-870f2882.2e55723f.js → dist/static/js/chunk-870f2882.153b86ef.js


+ 0 - 0
dist/static/js/chunk-970a3cc0.f9bacf9a.js → dist/static/js/chunk-970a3cc0.88660119.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-b265f6f8.dba591eb.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-b40d50ca.95fb3681.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-bd5ed284.745a410f.js


+ 0 - 0
dist/static/js/chunk-c3be65e4.4e411d8f.js → dist/static/js/chunk-c3be65e4.7153bb72.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-d3f058fe.3dca97b5.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-d3f058fe.9bf03846.js


+ 0 - 0
dist/static/js/chunk-d4d28b52.94630a20.js → dist/static/js/chunk-d4d28b52.a52318d9.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-libs.4406bd5f.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
dist/static/js/chunk-libs.d370c650.js


+ 1 - 0
package.json

@@ -29,6 +29,7 @@
     "nprogress": "^0.2.0",
     "opencc-js": "^1.0.5",
     "papaparse": "^5.5.2",
+    "qr-scanner": "^1.4.2",
     "qrcodejs2": "0.0.2",
     "regenerator-runtime": "^0.13.5",
     "vant": "^2.12.7",

+ 10 - 0
src/api/wechat.js

@@ -68,3 +68,13 @@ export function checkWechatAuth(openid) {
     hideloading: true
   })
 }
+
+// 微信获取signature
+export function getSignature(data) {
+  return request({
+    url: api + 'wechat-get-signature',
+    method: 'GET',
+    params: data,
+    hideloading: true
+  })
+}

+ 193 - 0
src/components/qrScanner.vue

@@ -0,0 +1,193 @@
+<template>
+  <div class="sweep" v-if="show">
+    <video ref="video" playsinline id="reader" style="width:100%;height:auto;"></video>
+    <div class="ku-scanner">
+      <div class="ku-scanner-content">
+        <div class="ku-scanner-tooltip">
+          将二维码/条码放入框内,即自动扫描
+          {{ msg }}
+        </div>
+        <div class="ku-scanner-section">
+          <div class="ku-scanner-section-animation-line"></div>
+          <div class="ku-scanner-section-angle"></div>
+        </div>
+      </div>
+    </div>
+    <span class="closeBtn" @click="close">
+      <svg
+        t="1733477770331"
+        class="icon"
+        viewBox="0 0 1024 1024"
+        version="1.1"
+        xmlns="http://www.w3.org/2000/svg"
+        p-id="4265"
+        width="64"
+        height="64"
+      >
+        <path
+          d="M623.807 528.693a113.756 113.756 0 0 0-0.139-33.126l252.787-252.692c26.245-26.236 26.245-68.772 0-95.006-26.248-26.236-68.798-26.236-95.043 0L528.281 400.902c-5.296-0.762-10.708-1.164-16.216-1.164s-10.92 0.402-16.216 1.164l-253.13-253.031c-26.245-26.236-68.796-26.236-95.043 0-26.245 26.234-26.245 68.77 0 95.006l252.789 252.692a113.726 113.726 0 0 0-0.14 33.124L147.676 781.247c-26.245 26.236-26.245 68.77 0 95.006 26.248 26.236 68.798 26.236 95.043 0L494.85 624.218c5.613 0.859 11.362 1.305 17.215 1.305s11.602-0.446 17.215-1.305l252.13 252.035c26.245 26.236 68.796 26.236 95.043 0 26.245-26.236 26.245-68.77 0-95.006L623.807 528.693z"
+          fill="#000000"
+          p-id="4266"
+        ></path>
+        <path
+          d="M512.063 444.326c37.407 0 67.73 30.327 67.73 67.736 0 37.41-30.323 67.735-67.73 67.735-37.405 0-67.728-30.325-67.728-67.735 0.001-37.408 30.323-67.736 67.728-67.736z"
+          fill="#000000"
+          p-id="4267"
+        ></path>
+      </svg>
+    </span>
+  </div>
+</template>
+
+<script>
+import QrScanner from 'qr-scanner'
+export default {
+  data() {
+    return {
+      show: false,
+      scanner: null,
+      msg: ''
+      // constraints:{
+      // 	width:300,
+      // 	height:300
+      // }
+    }
+  },
+  methods: {
+    open() {
+      this.show = true
+      this.$nextTick(() => {
+        if (this.$refs.video) {
+          // this.$toast('测试测试')
+          this.startScanner()
+        }
+      })
+    },
+    close() {
+      if (this.scanner) {
+        this.scanner.stop()
+      }
+      this.show = false
+    },
+    async startScanner() {
+      this.scanner = new QrScanner(
+        this.$refs.video,
+        result => {
+          if (result.data) {
+            this.$emit('success', result.data)
+          }
+
+          // this.scanner.stop() // 扫描一次后停止
+          // this.close()
+        },
+        { preferredCamera: 'environment' } // 优先使用后置摄像头
+      )
+      await this.scanner.start()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.sweep {
+  width: 100vw;
+  height: 100vh;
+  z-index: 9990;
+  background-color: #000;
+  position: fixed;
+  top: 0;
+  left: 0;
+}
+
+.closeBtn {
+  width: 40px;
+  height: 40px;
+  position: absolute;
+  top: 20px;
+  border-radius: 50%;
+  background-color: #ffffff80;
+  right: 20px;
+  z-index: 9992;
+  box-sizing: border-box;
+  padding: 10px;
+  svg {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+.ku-scanner {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  right: 0;
+  top: 0;
+  z-index: 9991;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  .ku-scanner-content {
+    background-size: 3rem 3rem;
+    background-position: -1rem -1rem;
+    width: 100%;
+    height: 100%;
+    position: relative;
+    background-color: rgba(18, 18, 18, 0);
+    margin: auto;
+    // 提示信息
+    .ku-scanner-tooltip {
+      width: 100%;
+      height: 35px;
+      line-height: 35px;
+      font-size: 14px;
+      text-align: center; /* color: #f9f9f9; */
+      margin: 0 auto;
+      position: absolute;
+      top: 0;
+      left: 0;
+      color: #ffffff;
+    }
+    .ku-scanner-section {
+      width: 213px;
+      height: 213px;
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      overflow: hidden;
+      border: 0.1rem solid rgba(86, 247, 118, 0.301);
+      // 扫描活动线
+      .ku-scanner-section-animation-line {
+        height: calc(100% - 2px);
+        width: 100%;
+        background: linear-gradient(180deg, rgba(0, 255, 51, 0) 43%, #2ffc58 211%);
+        border-bottom: 3px solid #2ffc58;
+        transform: translateY(-100%);
+        animation: radar-beam 2s infinite alternate;
+        animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99);
+        animation-delay: 1.4s;
+      }
+    }
+  }
+}
+// 扫描活动线--上下 动画
+@keyframes radar-beam {
+  0% {
+    transform: translateY(-100%);
+  }
+
+  100% {
+    transform: translateY(0);
+  }
+}
+
+#reader {
+  width: 100% !important;
+  height: 100% !important;
+  object-fit: cover;
+  position: absolute;
+  top: 0;
+  left: 0;
+  object-fit: cover; /* 使视频自适应填充 */
+}
+</style>

+ 10 - 2
src/components/sweepPage_html5_qrcode.vue

@@ -134,8 +134,16 @@ export default {
       //   .catch(err => {
       //     this.msg += err
       //   })
-      this.cameras = new Html5Qrcode('reader')
-      this.cameras.start({ facingMode: { exact: 'environment' } }, { fps: 10 }, this.CamerasSuccess)
+      this.cameras = new Html5Qrcode('reader', {
+        fps: 10,
+        videoConstraints: {
+          width: { ideal: 1280 },
+          height: { ideal: 720 },
+          // 或尝试 facingMode
+          facingMode: 'environment' // 后置摄像头
+        }
+      })
+      this.cameras.start({ facingMode: { exact: 'environment' }}, { fps: 10 }, this.CamerasSuccess)
     },
     CamerasSuccess(decodedText, decodedResult) {
       console.log(decodedResult)

+ 104 - 0
src/components/weChatQrcode.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="weChatQrCode" v-if="false"></div>
+</template>
+
+<script>
+import wx from 'weixin-js-sdk'
+import { getSignature } from '@/api/wechat'
+export default {
+  data() {
+    return {
+      show: false
+    }
+  },
+  methods: {
+    open() {
+      this.show = true
+      this.onScan()
+    },
+    onScan() {
+      this.getConfig()
+      const that = this
+      try {
+        console.log('测试测试ready')
+        // console.log(wx.ready)
+        // console.log(wx.ready())
+        wx.ready(function() {
+          console.log('测试2222')
+          wx.checkJsApi({
+            // 需要使用的JS接口列表,在这里只需要用到scanQRCode
+            jsApiList: ['scanQRCode'],
+            success: function(res1) {
+              if (res1.checkResult.scanQRCode) {
+                // 当scanQRCode可使用时
+                wx.scanQRCode({
+                  needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
+                  scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
+                  success: function(res2) {
+                    const result = res2.resultStr
+                    that.$emit('success', result)
+                    // console.log(res2.resultStr, '扫描的结果~')
+                    // window.location.href = result
+                  },
+                  error: function(response) {
+                    this.close()
+                    this.$nextTick(() => {
+                      that.$toast(response)
+                    })
+                  }
+                })
+              }
+            }
+          })
+        })
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    async getConfig() {
+      const that = this
+      const res = await getSignature({ url: encodeURIComponent(window.location.href.split('#')[0]) })
+      // console.log('res', res)
+      that.wxConfig(res.data.appId, res.data.params.timestamp, res.data.params.nonceStr, res.data.signature)
+    },
+    // wx.config的配置
+    wxConfig(appId, timestamp, nonceStr, signature) {
+      const that = this
+      try {
+        const params = {
+          debug: false, // 开启调试模式,
+          appId: appId, // 必填,企业号的唯一标识
+          timestamp: timestamp, // 必填,生成签名的时间戳
+          nonceStr: nonceStr, // 必填,生成签名的随机串
+          signature: signature, // 必填,签名
+          jsApiList: ['scanQRCode', 'checkJsApi'] // 必填,需要使用的JS接口列表
+        }
+        wx.config(params)
+        wx.error(function(res) {
+          console.log('测试测试111')
+          that.close()
+          alert('出错了👉' + res.errMsg) // wx.config配置错误,会弹出窗口哪里错误,然后根据微信文档查询即可。
+        })
+        console.log('测试测试wxConfig')
+      } catch (error) {
+        console.log(error)
+      }
+    },
+    close() {
+      this.show = false
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.weChatQrCode {
+  width: 100%;
+  height: 100%;
+  z-index: 9999;
+  position: fixed;
+  top: 0;
+  left: 0;
+  background: #000;
+}
+</style>

+ 15 - 1
src/main.js

@@ -36,11 +36,25 @@ Vue.use(VueAudio)
 // 引入本地存储
 import { storage, sessionStorage } from '@/utils/storage'
 import hevueImgPreview from '@/components/hevue-img-preview'
-const echarts = require('echarts');
+const echarts = require('echarts')
 Vue.prototype.$echarts = echarts
 import '@/permission' // permission control
 Vue.prototype.$storage = storage
 Vue.prototype.$sessionStorage = sessionStorage
+
+const ua = navigator.userAgent.toLowerCase()
+const isWeChat = /micromessenger/i.test(ua)
+
+// 额外验证:检查微信JSBridge
+if (isWeChat && typeof WeixinJSBridge === 'undefined') {
+  // 这种情况可能发生在某些特殊微信版本或modified UA
+  console.warn('检测到微信UA但无JSBridge,可能是不完整的微信环境')
+}
+console.log('$isWechat', isWeChat)
+
+// 判断是否为微信浏览器
+Vue.prototype.$isWechat = isWeChat
+
 // 动态设置title
 Vue.use(require('vue-wechat-title'))
   .use(Calendar)

+ 8 - 2
src/views/testDetail/components/choice.vue

@@ -16,6 +16,12 @@
           <span>{{ checkJson.score2 }}分</span><span style="margin: 0 10px">/</span><span>{{ checkJson.score }}分</span>
         </div>
       </div>
+      <div
+        class="detail"
+        v-if="checkJson.detail"
+        v-html="checkJson.detail"
+        style="color: #00000099;margin-top: 5px;"
+      ></div>
       <div class="choices">
         <div class="choice" v-for="(item, index) in checkJson.array" :key="index">
           <div class="choice_c" v-if="checkJson.type == 2">
@@ -79,8 +85,8 @@ export default {
   },
   computed: {
     score2() {
-      let answer2 = this.checkJson.answer2 ? this.checkJson.answer2.sort().join(',') : ''
-      let answer = this.checkJson.answer ? this.checkJson.answer.sort().join(',') : ''
+      const answer2 = this.checkJson.answer2 ? this.checkJson.answer2.sort().join(',') : ''
+      const answer = this.checkJson.answer ? this.checkJson.answer.sort().join(',') : ''
       this.checkJson.score2 = answer2 == answer ? this.checkJson.score : 0
       this.$forceUpdate()
       return answer2 == answer ? this.checkJson.score : 0

+ 6 - 0
src/views/testDetail/components/file.vue

@@ -19,6 +19,12 @@
           <span>{{ checkJson.score2 }}分</span><span style="margin: 0 10px">/</span><span>{{ checkJson.score }}分</span>
         </div>
       </div>
+      <div
+        class="detail"
+        v-if="checkJson.detail"
+        v-html="checkJson.detail"
+        style="color: #00000099;margin-top: 5px;"
+      ></div>
       <div class="choices">
         <div class="file_box" v-if="checkJson.mobanFile && checkJson.mobanFile.length" v-loading="loading">
           <div class="file_item" v-for="(item, index) in checkJson.mobanFile" :key="index">

+ 11 - 2
src/views/testDetail/components/gap.vue

@@ -6,14 +6,17 @@
       <!-- <div class="title"><div>{{ `(${option[checkJson.type].name})` }}</div><div v-html="checkJson.title"></div></div> -->
       <div class="c_title">
         <div class="title">
-          {{ tindex + 1 + '、' + `(${option[checkJson.type].name})` + checkJson.title
-          }}<span v-if="see" style="color: #efa030"
+          {{ tindex + 1 + '、' + `(${option[checkJson.type].name})` + checkJson.title }}222<span
+            v-if="see"
+            style="color: #efa030"
             >({{ checkJson.answer ? '参考答案:' + checkJson.answer : '暂无参考答案' }}
             {{ cJson.score ? '分值:' + cJson.score + '分' : '' }})</span
           >
           <span style="color: #efa030" v-if="checkJson.score && !see">({{ '分值:' + checkJson.score + '分' }})</span>
+
           <!-- </div><div v-html="checkJson.title"></div> -->
         </div>
+
         <div class="p_box" v-if="isTeacher == 1 && checkJson.score">
           <el-input v-model="checkJson.score2" class="c_input" @change="numberPan" placeholder="请输入得分"></el-input
           ><span style="margin: 0 10px">/</span><span>{{ checkJson.score }}分</span>
@@ -22,6 +25,12 @@
           <span>{{ checkJson.score2 }}分</span><span style="margin: 0 10px">/</span><span>{{ checkJson.score }}分</span>
         </div>
       </div>
+      <div
+        class="detail"
+        v-if="checkJson.detail"
+        v-html="checkJson.detail"
+        style="color: #00000099;margin-top: 5px;"
+      ></div>
       <div class="choices">
         <textarea
           :readonly="checktype == 2"

+ 34 - 14
src/views/testDetail/components/punchQRcode.vue

@@ -24,13 +24,17 @@
       </div>
     </div>
     <!-- <sweepPage ref="sweepPageRef" @success="sweepSuccess" @error="sweepError" /> -->
-    <sweepPage_html5_qrcode ref="sweepPage_html5_qrcodeRef" @success="sweepSuccess" @error="sweepError" />
+    <!-- <sweepPage_html5_qrcode ref="sweepPage_html5_qrcodeRef" @success="sweepSuccess" @error="sweepError" /> -->
+    <qrScanner ref="qrScannerRef" @success="sweepSuccess" />
+    <weChatQrcode ref="weChatQrcodeRef" @success="sweepSuccess" />
   </div>
 </template>
 
 <script>
-import sweepPage from '@/components/sweepPage.vue'
-import sweepPage_html5_qrcode from '@/components/sweepPage_html5_qrcode.vue'
+// import sweepPage from '@/components/sweepPage.vue'
+// import sweepPage_html5_qrcode from '@/components/sweepPage_html5_qrcode.vue'
+import qrScanner from '@/components/qrScanner.vue'
+import weChatQrcode from '@/components/weChatQrcode.vue'
 export default {
   props: {
     tindex: {
@@ -49,8 +53,10 @@ export default {
     }
   },
   components: {
-    sweepPage,
-    sweepPage_html5_qrcode
+    // sweepPage,
+    // sweepPage_html5_qrcode
+    qrScanner,
+    weChatQrcode
   },
   data() {
     return {
@@ -77,19 +83,29 @@ export default {
       return JSON.parse(JSON.stringify(s))
     },
     sweepBtn() {
-      // this.$refs.sweepPageRef.open()
-      this.$refs.sweepPage_html5_qrcodeRef.open()
+      if (this.$isWechat) {
+        this.$refs.weChatQrcodeRef.open()
+      } else {
+        this.$refs.qrScannerRef.open()
+      }
     },
     sweepSuccess(result) {
-      let _valueAndTime = this.extractValueAndTime(result)
+      const _valueAndTime = this.extractValueAndTime(result)
 
-      if (!_valueAndTime) return this.$toast.fail('扫码的格式不正确')
+      if (!_valueAndTime) {
+        if (this.$isWechat) {
+          this.$refs.weChatQrcodeRef.close()
+        } else {
+          this.$refs.qrScannerRef.close()
+        }
+        return this.$toast.fail('扫码的格式不正确')
+      }
 
-      //判断当前时间和扫码时间是否超过设置的时间
+      // 判断当前时间和扫码时间是否超过设置的时间
       if (_valueAndTime.time) {
-        let currentTime = new Date().getTime() // 获取当前时间戳
-        let checkTime = new Date(_valueAndTime.time).getTime() // 获取_valueAndTime.time的时间戳
-        let minutes = parseInt(this.checkJson.minutes) // 获取minutes对象
+        const currentTime = new Date().getTime() // 获取当前时间戳
+        const checkTime = new Date(_valueAndTime.time).getTime() // 获取_valueAndTime.time的时间戳
+        const minutes = parseInt(this.checkJson.minutes) // 获取minutes对象
 
         if (currentTime - checkTime > minutes * 60 * 1000) {
           // 超过指定分钟数的逻辑处理
@@ -102,7 +118,11 @@ export default {
       }
       console.log(_valueAndTime)
       // this.checkJson.answer2 = result;
-      this.$refs.sweepPage_html5_qrcodeRef.close()
+      if (this.$isWechat) {
+        this.$refs.weChatQrcodeRef.close()
+      } else {
+        this.$refs.qrScannerRef.close()
+      }
     },
     sweepError(error) {
       // this.$message.error(error)

+ 37 - 22
src/views/testDetail/components/sweep.vue

@@ -12,9 +12,9 @@
         style="color: #00000099;margin-top: 5px;"
       ></div>
 
-			<div
+      <div
         class="detail"
-        v-if="checkJson.answer2 && typeof checkJson.answer2=='string'"
+        v-if="checkJson.answer2 && typeof checkJson.answer2 == 'string'"
         v-html="checkJson.answer2"
         style="color: #000000;margin-top: 5px;"
       ></div>
@@ -23,14 +23,18 @@
         <el-button type="primary" size="small" @click="sweepBtn">扫一扫</el-button>
       </div>
     </div>
-		<!-- <sweepPage ref="sweepPageRef" @success="sweepSuccess"  @error="sweepError"/> -->
-    <sweepPage_html5_qrcode ref="sweepPage_html5_qrcodeRef" @success="sweepSuccess"  @error="sweepError"/>
+    <!-- <sweepPage ref="sweepPageRef" @success="sweepSuccess"  @error="sweepError"/> -->
+    <!-- <sweepPage_html5_qrcode ref="sweepPage_html5_qrcodeRef" @success="sweepSuccess"  @error="sweepError"/> -->
+    <qrScanner ref="qrScannerRef" @success="sweepSuccess" />
+    <weChatQrcode ref="weChatQrcodeRef" @success="sweepSuccess" />
   </div>
 </template>
 
 <script>
 // import sweepPage from '@/components/sweepPage.vue';
-import sweepPage_html5_qrcode from '@/components/sweepPage_html5_qrcode.vue';
+// import sweepPage_html5_qrcode from '@/components/sweepPage_html5_qrcode.vue';
+import qrScanner from '@/components/qrScanner.vue'
+import weChatQrcode from '@/components/weChatQrcode.vue'
 export default {
   props: {
     tindex: {
@@ -48,10 +52,12 @@ export default {
       default: false
     }
   },
-	components:{
-		// sweepPage
-    sweepPage_html5_qrcode
-	},
+  components: {
+    // sweepPage
+    // sweepPage_html5_qrcode
+    qrScanner,
+    weChatQrcode
+  },
   data() {
     return {
       option: {
@@ -59,9 +65,9 @@ export default {
       },
       userid: this.$route.query.userid,
       checkJson: {
-				title:"",
-				detail:""
-			},
+        title: '',
+        detail: ''
+      }
     }
   },
   watch: {
@@ -76,15 +82,24 @@ export default {
     depthCopy(s) {
       return JSON.parse(JSON.stringify(s))
     },
-		sweepBtn(){
-			this.$refs.sweepPage_html5_qrcodeRef.open();
-		},
-		sweepSuccess(result){
-			this.checkJson.answer2 = result;
-			this.$refs.sweepPage_html5_qrcodeRef.close();
-      this.$forceUpdate();
-		},
-    sweepError(error){
+    sweepBtn() {
+      if (this.$isWechat) {
+        this.$refs.weChatQrcodeRef.open()
+      } else {
+        this.$refs.qrScannerRef.open()
+      }
+    },
+    sweepSuccess(result) {
+      this.checkJson.answer2 = result
+      if (this.$isWechat) {
+        this.$refs.weChatQrcodeRef.close()
+      } else {
+        this.$refs.qrScannerRef.close()
+      }
+      // this.$toast(result)
+      this.$forceUpdate()
+    },
+    sweepError(error) {
       this.$toast.fail(error)
       // if (error.name === 'NotAllowedError') {
       //     this.$toast.fail('您需要授予相机访问权限')
@@ -101,7 +116,7 @@ export default {
       //   }else{
       //     this.$toast.fail(error.name)
       //   }
-    },
+    }
   },
   mounted() {
     this.checkJson = this.cJson ? this.depthCopy(this.cJson) : undefined

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff