谢杰标 2 lat temu
rodzic
commit
3823c11d3b
2 zmienionych plików z 333 dodań i 6 usunięć
  1. 325 5
      components/popup/camera.vue
  2. 8 1
      pages3/polyv/detail.vue

+ 325 - 5
components/popup/camera.vue

@@ -75,27 +75,347 @@
         </view>
       </view>
     </u-popup>
+    <!-- 播放前拍照end -->
+    <u-popup
+      v-model="showSet"
+      :mask-close-able="false"
+      mode="center"
+      border-radius="24"
+    >
+      <view
+        style="
+          align-items: center;
+          padding: 0 40rpx;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+        "
+      >
+        <view
+          style="
+            font-weight: bold;
+            color: #333333;
+            font-size: 30rpx;
+            margin-top: 30rpx;
+          "
+          >温馨提示</view
+        >
+        <view
+          style="
+            width: 457rpx;
+            color: #666666;
+            font-size: 30rpx;
+            margin-top: 30rpx;
+          "
+          >学习过程中需要拍照验证学员身份, 拍照功能需要使用您的相机。
+          是否授权使用?</view
+        >
+        <view style="margin: 40rpx 0">
+          <button
+            open-type="openSetting"
+            @bindopensetting="openSetting"
+            class="btnSet"
+          >
+            去授权
+          </button>
+        </view>
+      </view>
+    </u-popup>
+    <!-- 拍照提示 -->
+    <popup-photo
+      :popupPhotoShow.sync="popupPhotoShow"
+      @takePhoto="toTakePhoto()"
+    ></popup-photo>
   </view>
 </template>
 
 <script>
+import PopupPhoto from "./index.vue";
 export default {
   name: "SaasMiniprogramCamera",
-  popos: {
-    visible: {
-      type: Boolean,
-      defaule: false,
+  props: {
+    goodsId: {
+      type: Number,
+      default: 0,
     },
   },
   data() {
     return {
       isShow: false,
+      avatarUrl: false,
+      isCameraAuth: false,
+      showSet: false,
+      popupPhotoShow: false,
     };
   },
 
   mounted() {},
 
-  methods: {},
+  methods: {
+    async submit() {
+      if (this.uploadLock) {
+        return;
+      }
+      this.uploadLock = true;
+      let compareFaceData = await this.faceRecognition();
+      this.compareFaceData = compareFaceData;
+      if (compareFaceData >= 80) {
+        await this.imageInfos();
+        this.postCoursePhotoRecord()
+          .then(async (res) => {
+            this.photoHistoryList.push(this.photoIndex);
+            // console.log('拍照确定提交', this.photoHistoryList);
+            this.postStudyRecord(); //提交记录
+            if (this.erJianErZao && this.isReach) {
+              console.log("1校验");
+              await this.postStudyRecord(1);
+              this.photoPopup = false;
+              this.uploadLock = false;
+              this.enableAutoRotation = true;
+              this.nextSection();
+              return;
+            }
+            //恢复播放
+            // #ifdef MP-WEIXIN
+            uni.setKeepScreenOn({
+              keepScreenOn: false,
+            });
+            // #endif
+            this.photoPopup = false;
+            this.uploadLock = false;
+            this.enableAutoRotation = true;
+            this.refPlv.resumeVideo();
+          })
+          .catch((err) => {
+            console.log("拍照记录接口的err", err);
+            uni.showToast({
+              title: "上传接口报错,请重新拍照上传" + err,
+              icon: "none",
+            });
+            this.uploadLock = false;
+            this.openPhoto();
+          });
+      } else {
+        uni.showToast({
+          title: "人脸匹配不通过,请重新拍照上传",
+          icon: "none",
+          duration: 2000,
+        });
+
+        setTimeout(() => {
+          this.uploadLock = false;
+          this.openPhoto();
+        }, 2000);
+      }
+    },
+    openCamera() {
+      // 同一个商品只谈一次提示
+      if (!uni.getStorageSync(`tabkePhotoShow${this.goodsId}`)) {
+        uni.setStorageSync(`tabkePhotoShow${this.goodsId}`, this.goodsId);
+        this.popupPhotoShow = true;
+        return;
+      }
+      if (this.isCameraAuth) {
+        return this.showCamera();
+      }
+      // #ifdef MP-WEIXIN
+      // 屏幕亮度
+      uni.setKeepScreenOn({
+        keepScreenOn: true,
+      });
+      uni.getSetting({
+        success: (res) => {
+          if (res.authSetting["scope.camera"]) {
+            this.isCameraAuth = true;
+          } else {
+            wx.authorize({
+              scope: "scope.camera",
+              success: () => {
+                this.isCameraAuth = true;
+                this.showCamera();
+              },
+              fail: () => {
+                this.isCameraAuth = false;
+                this.showSet = true;
+              },
+            });
+          }
+        },
+        fail: (res) => {},
+      });
+      // #endif
+      // #ifdef H5
+      if (
+        (window.navigator.mediaDevices &&
+          window.navigator.mediaDevices.getUserMedia) ||
+        window.navigator.getUserMedia ||
+        window.navigator.webkitGetUserMedia ||
+        window.navigator.mozGetUserMedia
+      ) {
+        console.log("getUserMedia----");
+        // 调用用户媒体设备, 访问摄像头
+        this.getUserMedia(
+          {
+            video: {
+              width: 400,
+              height: 300,
+              facingMode: "user",
+            },
+          },
+          this.photographSuccess,
+          this.photographError
+        );
+      } else {
+        console.log("1111没有摄像");
+        this.photographError();
+      }
+      // #endif
+    },
+    showCamera() {
+      this.show = true;
+    },
+    //确认拍照
+    takePhoto() {
+      // #ifdef MP-WEIXIN
+      const ctx = uni.createCameraContext();
+      ctx.takePhoto({
+        quality: "high",
+        success: (res) => {
+          this.avatarUrl = res.tempImagePath;
+          console.log("开始拍照this.avatarUrl:", this.avatarUrl);
+          this.isTaking = false;
+        },
+        fail: (err) => {},
+      });
+      // #endif
+      // #ifdef H5
+      const canvas = document.createElement("canvas");
+      canvas.width = 400;
+      canvas.height = 400;
+      const context = canvas.getContext("2d");
+      const box = document.querySelector(".photo_v");
+      const video = box.querySelector("video");
+      context.drawImage(video, 0, 0, 400, 400);
+      this.faceUrl = canvas.toDataURL("image/png");
+      this.isTaking = false;
+      // #endif
+    },
+    /**
+     * 人脸匹配
+     */
+    faceRecognition() {
+      return new Promise((resolve) => {
+        // #ifdef MP-WEIXIN
+        let fileSystem = uni.getFileSystemManager();
+        fileSystem.readFile({
+          filePath: `${this.avatarUrl}`,
+          encoding: "base64",
+          position: 0,
+          success: (res) => {
+            let base64 = "data:image/jpg;base64," + res.data;
+            this.CompareFace(base64, resolve);
+          },
+          fail(err) {
+            // this.$u.toast('人脸识别错误!')
+            console.error(err, "err-----人脸识别错误");
+          },
+        });
+        // #endif
+        // #ifdef H5
+        this.CompareFace(this.faceUrl, resolve);
+        // #endif
+      });
+    },
+    CompareFace(url, resolve) {
+      let timer = setTimeout(() => {
+        uni.showToast({
+          icon: "none",
+          title: "拍照超时,请重新拍照",
+          duration: 2000,
+          success: () => {
+            setTimeout(() => {
+              uni.navigateBack();
+            }, 1000);
+          },
+        });
+      }, 10 * 1000);
+
+      this.$api
+        .faceCertificationCompareFace({
+          imageA: url,
+          orderGoodsId: this.orderGoodsId,
+          gradeId: this.gradeId,
+        })
+        .then((res) => {
+          clearTimeout(timer);
+          console.log(res, "人脸识别成功res");
+          resolve(res.data.data);
+        })
+        .catch((err) => {
+          clearTimeout(timer);
+          // 当前网络延迟,
+          console.log("人脸识别错误:", err);
+          uni.showModal({
+            content: "当前网络延迟",
+            showCancel: false,
+            success: (resultst) => {
+              if (resultst.confirm) {
+                uni.navigateBack();
+              }
+            },
+          });
+        });
+    },
+    photographSuccess(stream) {
+      console.log("有摄像头---", stream);
+      this.isCameraAuth = true;
+      this.showCamera();
+      this.$nextTick(() => {
+        const box = document.querySelector(".photo_v");
+        const video = box.querySelector("video");
+        video.srcObject = stream;
+        video.play();
+      });
+    },
+    photographError(err) {
+      console.log("没有摄像头:", err);
+      uni.showModal({
+        title: "提示",
+        content:
+          "课程学习需要开启摄像头进行拍照,经检测您的设备无摄像头可使用,请检测环境是否支持。",
+        cancelText: "取消",
+        confirmText: "确定",
+        success: (res) => {
+          if (res.confirm) {
+            uni.navigateBack();
+          } else if (res.cancel) {
+          }
+        },
+      });
+    },
+    getUserMedia(constraints, success, error) {
+      console.log("getUserMedia===", constraints, "success:", success);
+      if (window.navigator.mediaDevices.getUserMedia) {
+        // 最新的标准API
+        window.navigator.mediaDevices
+          .getUserMedia(constraints)
+          .then(success)
+          .catch(error);
+      } else if (window.navigator.webkitGetUserMedia) {
+        // webkit核心浏览器
+        window.navigator.webkitGetUserMedia(constraints, success, error);
+      } else if (window.navigator.mozGetUserMedia) {
+        // firfox浏览器
+        window.navigator.mozGetUserMedia(constraints, success, error);
+      } else if (window.navigator.getUserMedia) {
+        // 旧版API
+        window.navigator.getUserMedia(constraints, success, error);
+      }
+    },
+  },
+  components: {
+    PopupPhoto,
+  },
 };
 </script>
 

+ 8 - 1
pages3/polyv/detail.vue

@@ -483,6 +483,8 @@
       :popupPhotoShow.sync="popupPhotoShow"
       @takePhoto="toTakePhoto()"
     ></popup-photo>
+    <!-- 摄像头 -->
+    <Popup-camera :goodsId="goodsId" ref="camera"></Popup-camera>
   </view>
 </template>
 
@@ -493,6 +495,7 @@ import courseChapter from "@/components/course/courseChapter.vue";
 import courseSection from "@/components/course/courseSection.vue";
 import handoutsBox from "@/components/course/handoutsBox.vue";
 import courseTree from "@/components/course/courseTree.vue";
+import PopupCamera from "../../components/popup/camera.vue";
 import PopupPhoto from "@/components/popup/index.vue";
 import myCompressImage from "@/common/compressPhoto.js";
 import myPlayer from "@/components/myPlayer/polyvPlayer.vue";
@@ -511,6 +514,7 @@ export default {
     noteBox,
     answerBox,
     courseTree,
+    PopupCamera,
   },
   data() {
     return {
@@ -533,7 +537,7 @@ export default {
       vid: "",
       goodsId: 0,
       goodsData: {},
-      photoPopup: true,
+      photoPopup: false,
       goodsPlayConfig: null,
       autoplay: false,
       isAllowSeek: "no",
@@ -1505,6 +1509,7 @@ export default {
       return {};
     },
     loadedmetadata(event) {
+      this.$refs["camera"].openCamera();
       this.refPlv = this.$refs.player;
     },
     getPhotoLastRecord() {
@@ -2085,6 +2090,8 @@ export default {
         this.refPlv.playPause();
         return;
       }
+
+      this.$refs["camera"].openCamera();
       this.studyLog();
       if (!this.recordObj.videoCurrentTime) {
         this.postStudyRecord(0);