<template>
  <div class="get-face">
    <div class="face-upload">
      <el-upload
        class="avatar-uploader"
        action=""
        :show-file-list="false"
        :auto-upload="false"
        :on-change="handleAvatarSuccess">
        <img
          v-if="form.facePic"
          :src="`data:image/jpeg;base64,${form.facePic}`"
          class="avatar">
        <i
          v-else
          class="el-icon-plus avatar-uploader-icon"
        ></i>
      </el-upload>
      <div
        class="dark-btn"
        style="width:60px"
        @click="openCamera(form)">
        <svg-icon icon-class="camera" />
        拍照
      </div>
    </div>
    <div
      class="face-camera-wrapper"
      v-if="cameraVisible">
      <div
        class="face-camera">
        <div class="content">
          <video
            class="video"
            id="video"
            autoplay
          ></video>
          <canvas
            v-show="screenShot"
            class="canvas"
            id="canvas"
            width="500"
            height="500"
          ></canvas>
        </div>
        <div class="ctrl">
          <i
            @click="closeCamera"
            class="el-icon-close"></i>
          <svg-icon
            v-if="!screenShot"
            @click.native="getScrshot"
            icon-class="camera" />
          <svg-icon
            v-if="screenShot"
            @click.native="initCamera"
            icon-class="refresh" />
          <i
            class="el-icon-loading"
            v-if="screenShot && !faceValid"></i>
          <svg-icon
            v-if="screenShot && faceValid"
            @click.native="saveScr"
            icon-class="save" />
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { faceidentify11 } from '@/api/face'
import compressImg from '@/assets/compress'
export default {
  name: 'GetFace',
  props: {
    form: {
      type: Object,
      default: () => {
        return {
          facePic: ''
        }
      }
    }
  },
  data () {
    return {
      cameraVisible: false,
      videoStream: null,
      screenShot: '', // 人脸截图
      faceValid: false // 人脸有效
    }
  },
  methods: {
    // 上传照片
    handleAvatarSuccess (res, list) {
      const isJPG = res.raw.type === 'image/jpeg' || res.raw.type === 'image/png'
      const isLt2M = res.raw.size / 1024 / 1024 < 2
      if (!isJPG) {
        this.$message.error('图片只能是 JPG或PNG 格式!')
        return
      }
      if (!isLt2M) {
        this.$message.error('图片大小不能超过 2MB!')
        return
      }
      let reader = new FileReader()
      reader.readAsDataURL(res.raw)
      reader.onload = (e) => {
        compressImg(e.target.result, 150).then(res => {
          this.$emit('setPic', res.split(',')[1])
        })
      }
    },
    openCamera () {
      this.cameraVisible = true
      this.$nextTick(this.initCamera)
    },
    // 初始化摄像头
    initCamera () {
      this.screenShot = ''
      this.video = document.getElementById('video')
      let canvas = document.getElementById('canvas')
      this.context = canvas.getContext('2d')
      this.getUserMedia({
        video: { width: 200, height: 200 }
      }, (stream) => {
        this.videoStream = stream
        this.video.srcObject = stream
        this.video.play()
      }, (error) => {
        console.log('访问用户媒体设备失败：', error.name, error.message)
      })
    },
    // 获取视频流
    getUserMedia (constrains, success, error) {
      if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error)
      }
    },
    // 获取截图
    getScrshot () {
      this.context.drawImage(this.video, 0, 0, 500, 500)
      let canvas = document.getElementById('canvas')
      let data = canvas.toDataURL('image/jpeg', 0.92)
      this.screenShot = data.split(',')[1]
      this.faceidentify11()
    },
    // 人脸比对API
    faceidentify11 () {
      this.faceValid = false
      faceidentify11({ img1: this.screenShot, img2: this.screenShot }).then(res => {
        if (res.errInfo === '成功') {
          this.faceValid = true
        } else {
          this.initCamera()
          this.$message({
            showClose: true,
            message: '人脸模糊，请重新拍照',
            type: 'error'
          })
        }
      }).catch(() => {
        this.initCamera()
        this.$message({
          showClose: true,
          message: '人脸模糊，请重新拍照',
          type: 'error'
        })
      })
    },
    // 保存截图
    saveScr () {
      this.$emit('setPic', this.screenShot)
      this.closeCamera()
    },
    // 关闭摄像头
    closeCamera () {
      this.screenShot = ''
      this.cameraVisible = false
      if (this.videoStream !== null) {
        let track = this.videoStream.getTracks()[0]
        track.stop()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.svg-icon {
  width: 20px; height: 20px;  margin-left: 5px;  cursor: pointer;
}
.face-upload {
  display: flex;
  .avatar-uploader {
    border: 1px dashed #d9d9d9;  border-radius: 6px;
  }
  .avatar-uploader .el-upload {
    position: relative;  overflow: hidden;  cursor: pointer;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409eff;
  }
  .avatar-uploader-icon {
    width: 100px;  height: 100px;  font-size: 28px;  line-height: 100px;  color: #8c939d;  text-align: center;
  }
  .avatar {
    display: block;  width: 100px;  height: 100px;
  }
}
.face-camera-wrapper {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1032;  background-color: rgba(0, 0, 0, .5);
  .face-camera {
    position: absolute; top: 50%; left: 50%;  display: flex;  width: 550px;  height: 500px;  padding: 20px;  background-color: #fff;  border-radius: 2px;  box-shadow: 0 1px 3px rgba(0,0,0,.3);  transform: translate(-50%, -50%);
    .content {
      position: relative;
      .video {
        width: 500px;  height: 500px;  background-color: #65677c;
      }
      .canvas {
        position: absolute;  top: 0;  left: 0;  width: 500px;  height: 500px;
      }
    }
    .ctrl {
      display: flex;  width: 50px;  padding-left: 20px;  flex-direction: column;  align-items: center;
      .svg-icon {
        width: 30px;  height: 30px;  margin-bottom: 15px;  color: #666;
      }
      i {
        margin-bottom: 15px;  color: #666;
      }
      .el-icon-close {
        align-self: flex-end;
      }
      .el-icon-loading {
        font-size: 26px;
      }
    }
  }
}

</style>
