Newer
Older
securityFront / src / views / visitor / visitorCheckIn.vue
wangxitong on 20 Feb 2021 12 KB bug修改
<!-- 访客刷证登记页面 -->
<template>
  <el-dialog :title="textMap[dialogStatus]" :close-on-click-modal="false" :visible.sync="dialogFormVisible" append-to-body  @close="closeDialog">
    <el-form ref="dataForm" :rules="rules" :model="dataForm" label-well-code="right" label-width="100px">
      <el-row>
        <el-col :span="6">
          <el-row style="margin-top: -20px">
            <div class="avatar">
              <el-image
                :src="photo!==''?photo:defaultPhoto"
                fit="cover"
                style="width: 130px; height: 175px"/>
            </div>
          </el-row>
          <el-row style="margin-top: -20px">
            <el-button v-show="isEditMode" :disabled="readCard||canRead" type="primary" plain class="id-card-btn" @click="readIDCard">读取身份证</el-button>
          </el-row>
          <el-row style="margin-top: -10px">
            <el-button type="primary" plain class="id-card-btn" @click="readCamera">{{ btnCamera }}</el-button>
          </el-row>
        </el-col>

        <el-col :span="16">
          <el-row>
            <el-col :span="12">
              <el-form-item label="姓名" prop="name">
                <el-input v-model.trim="dataForm.name" :readonly="readCard" :disabled="!isEditMode" type="text" placeholder="必填"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="性别" prop="sex">
                <el-select v-model="dataForm.sex" :disabled="readCard||!isEditMode" placeholder="性别" clearable>
                  <el-option v-for="item in sexList" :key="item.value" :label="item.name" :value="item.value"/>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="24" prop="idCard">
              <el-form-item label="身份证号" prop="idCard">
                <el-input v-model.trim="dataForm.idCard" :readonly="readCard" :disabled="!isEditMode" type="text" placeholder="身份证号"/>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row>
            <el-col :span="14">
              <el-form-item label="联系电话" prop="phone">
                <el-input v-model.trim="dataForm.phone" :disabled="!isEditMode" type="text" placeholder="联系电话"/>
              </el-form-item>
            </el-col>
            <el-col :span="10">
              <el-form-item label="体温(℃)">
                <el-input v-model.trim="dataForm.temperature" :disabled="!isEditMode" type="text" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row class="dialog-footer">
            <video v-show="showVideo" width="200px" height="150px" style="margin-right: 20px"></video>
            <canvas v-show = "false" width="200px" height="150px"></canvas>
            <el-button :loading="btnLoading" type="primary" @click="saveData" style="width: 150px">保 存</el-button>
          </el-row>
        </el-col>
      </el-row>
    </el-form>
  </el-dialog>
</template>

<script>
import { getSexType } from '@/api/allDict'
import { getBirthdayByIdNO, getSexByIdNO } from '@/utils/dataAnalysis'
import { phoneValidator, temValidator } from '@/utils/validate'
import { validateIDCard } from '@/utils/validate'
export default {
  name: 'VisitorCheckIn',
  data() {
    return {
      canRead: false,
      btnCamera:'读取摄像头',
      showVideo: false,
      stream:'',
      isEditMode: true, // 是否为编辑模式,非编辑模式都为只读
      readCard: false, // 是否从读卡器读卡,未从读卡器读卡不能提交,读卡之后不能编辑
      dialogFormVisible: false, // 对话框是否显示
      dialogStatus: '', // 对话框类型:create,update,detail
      dataForm: {
        idCard: '', // 身份证号
        name: '', // 姓名
        sex: '', // 性别
        sexStr: '',
        phone: '', // 联系电话
        birthday: '', // 出生日期
        temperature: '', // 体温
        photo: '',
        address: ''
      }, // 表单
      photo: '', // 图片路径
      defaultPhoto: require('@/assets/global_images/photo.png'), // 默认图片路径
      textMap: {
        create: '来访人员登记',
        detail: '详情'
      }, // 表头显示标题
      rules: {
        idCard: [{ required: true, trigger: ['blur', 'change'], validator: validateIDCard }],
        name: [{ required: true, message: '姓名必填', trigger: ['blur', 'change'] }],
        sex: [{ required: true, message: '性别必选', trigger: ['blur', 'change'] }],
        phone: [{ required: true, trigger: ['blur', 'change'], validator: phoneValidator }],
        temperature: [{ required: true, trigger: ['blur', 'change'], validator: temValidator }]
      }, // 前端校验规则
      sexList: [],
      btnLoading: true // 保存按钮是否不允许点击
    }
  },
  watch: {
    'dataForm.idCard': function(val) {
      this.dataForm.birthday = getBirthdayByIdNO(val)
      this.dataForm.sex = getSexByIdNO(val)
    }
  },
  created() {
    // 初始化性别字典值列表
    getSexType().then(response => {
      this.sexList = response.data
    })
  },
  methods: {
    readCamera() {
      if(this.btnCamera === '读取摄像头'){
        this.cameraImgFile()
      }else{
        this.getAPhoto()
      }
    },
    closeDialog(){
      var mediaStreamTrack =  this.stream.getTracks()[0];
      mediaStreamTrack.stop();
    },
    getAPhoto() {
      //绘制canvas图形
      let video = document.getElementsByTagName("video")[0]
      var canvas = document.getElementsByTagName('canvas')[0]
      var context = canvas.getContext('2d')
      context.clearRect(0, 0, context.width, context.height);
      context.drawImage(video, 0, 0,200,150);
      this.showVideo = false
      //把canvas图像转为img图片
      this.photo = canvas.toDataURL("image/png");
      var mediaStreamTrack =  this.stream.getTracks()[0];
      mediaStreamTrack.stop();
      this.btnCamera = '读取摄像头'
    },
    // 拍照上传获取video
    cameraImgFile() {
      let _this = this;

      // 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
      if (navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {};
      }
      // 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
      // 因为这样可能会覆盖已有的属性。这里我们只会在没有getUserMedia属性的时候添加它。
      if (navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = function(constraints) {
          // 首先,如果有getUserMedia的话,就获得它
          var getUserMedia =
            navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

          // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
          if (!getUserMedia) {
            return Promise.reject(
              new Error("getUserMedia is not implemented in this browser")
            );
          }
          // 否则,为老的navigator.getUserMedia方法包裹一个Promise
          return new Promise(function(resolve, reject) {
            getUserMedia.call(navigator, constraints, resolve, reject);
          });
        };
      }
      navigator.mediaDevices
        .getUserMedia({ video: true, audio: false })
        .then(function(stream) {
          _this.stream = stream;
          _this.videoShow = true;
          // 旧的浏览器可能没有srcObject
          _this.$nextTick(() => {
            let video = document.getElementsByTagName("video")[0]
            if ("srcObject" in video) {
              video.srcObject = stream;
            } else {
              // 防止在新的浏览器里使用它,应为它已经不再支持了
              video.src = window.URL.createObjectURL(stream);
            }
            _this.showVideo = true
            _this.btnCamera = '拍照'
            video.onloadedmetadata = function(e) {
              video.play();
            };
          });
        })
        .catch(function(err) {
          _this.videoShow = false;
          _this.$message.warning("未发现可拍照设备或出现其他错误!");
        });
    },
    // 初始化对话框
    initDialog: function(dialogStatus, dialogFormVisible, row = null) {
      this.btnLoading = false
      this.dialogStatus = dialogStatus
      this.dialogFormVisible = dialogFormVisible
      this.showVideo = false
      this.btnCamera = '读取摄像头'
      this.resetForm()

      if (dialogStatus === 'create') { // 如果是新增,清除验证
        this.isEditMode = true
        this.readCard = false
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
        })
      } else if (dialogStatus === 'detail') {
        this.isEditMode = false

        this.dataForm = {
          idCard: row.idCard,
          name: row.name,
          phone: row.phone,
          temperature: row.temperature,
          address: row.address
        }

        this.dataForm.birthday = getBirthdayByIdNO(row.idCard)
        this.dataForm.sex = getSexByIdNO(row.idCard)

        this.photo = row.photo
      }
    },
    // 清除数据
    resetForm() {
      this.dataForm = {
        idCard: '', // 身份证号
        name: '', // 姓名
        sex: '', // 性别
        sexStr: '',
        phone: '', // 联系电话
        birthday: '', // 出生日期
        temperature: '', // 体温
        photo: '',
        address: ''
      }

      this.photo = ''
      this.btnLoading = false
      this.readCard = false

      this.isEditMode = true
      this.readCard = false
    },
    readIDCard() {
      this.resetForm()
      this.canRead = true
      const that = this
      this.ws = that.$root.ws
      if (this.ws === null) {
        this.ws = new WebSocket(that.$root.wsURL)
        // 注册各类回调
        this.ws.onopen = function() {
          that.ws.send('ReadIdCard')
        }
        this.ws.onclose = function() {
          that.$message.info('与ICS连接断开')
          that.$root.ws = null
        }
        this.ws.onerror = function() {
          that.$message.error('与ICS通信发生错误')
        }
        that.$root.ws = this.ws
      } else {
        this.ws.send('ReadIdCard')
      }
      this.ws.onmessage = function(receiveMsg) {
        that.canRead = false
        const data = JSON.parse(receiveMsg.data)
        console.log(data)
        if (data !== '' && data.message !== 'fail') {
          that.dataForm.idCard = data.IdCardNo
          that.dataForm.name = data.Name
          that.photo = data.Photo.replace('bmp', 'png')
          that.dataForm.photo = data.Photo.replace('bmp', 'png')
          that.dataForm.address = data.Address
          that.dataForm.sexStr = data.Sex

          // 读过身份证了
          that.readCard = true
        } else {
          that.$message.warning('读卡失败')
        }
      }
    },
    // 保存数据
    saveData: function() {
      this.btnLoading = true
      this.visitorCheckedIn()
    },
    // 新增数据
    visitorCheckedIn: function() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          const list = this.$parent.dataForm.visitorBaseDTOList
          let isChecked = false
          // 遍历父组件的visitorBaseDTOList,检查是否已经登记过
          list.forEach(item => {
            if (item.idCard === this.dataForm.idCard) {
              isChecked = true
            }
          })

          if (isChecked === true) {
            this.$message.error('该身份证已经登记过,请检查')

            this.$nextTick(() => {
              this.btnLoading = false
              this.readCard = false
            })
          } else {
            console.log(this.dataForm)
            // 发送信号让父组件添加
            this.$emit('checked', this.dataForm)

            this.$confirm('新增成功,是否继续新增?', '提示', {
              confirmButtonText: '是',
              cancelButtonText: '否',
              type: 'info'
            }).then(() => {
              this.resetForm()
              this.$nextTick(() => {
                this.$refs['dataForm'].clearValidate()
              })
            }).catch(() => {
              this.dialogFormVisible = false
            })
          }
        } else {
          this.btnLoading = false
        }
      })
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .el-select{
    width: 100%;
  }
  .el-date-editor{
    width: 100%;
  }
  .dialog-footer {
    margin-top: 10px;
    text-align: center;
  }
</style>