|  |  | 
 |  |  |           </div> | 
 |  |  |         </div> | 
 |  |  |       </el-form-item> | 
 |  |  |       <el-form-item> | 
 |  |  |         <div><el-button type="primary" @click="openCamera">采集</el-button></div> | 
 |  |  |       </el-form-item> | 
 |  |  |     </el-form> | 
 |  |  |     <!--  --> | 
 |  |  |     <el-dialog title="拍摄" :visible.sync="paisheModal" width="760px" :close-on-click-modal="false" | 
 |  |  |       :close-on-press-escape="false" append-to-body @close="closeCamera"> | 
 |  |  |       <video v-show="isShowCamera" id="videoCamera" :width="videoWidth" :height="videoHeight" /> | 
 |  |  |       <canvas v-show="!isShowCamera" id="canvasCamera" style="display: none" :width="videoWidth" | 
 |  |  |         :height="videoHeight" /> | 
 |  |  |       <span slot="footer"> | 
 |  |  |         <div> | 
 |  |  |           <el-button @click="closeCamera">取消</el-button> | 
 |  |  |           <el-button v-show="blobFileCamera" type="primary" @click="resetCamera">重拍</el-button> | 
 |  |  |           <el-button v-show="blobFileCamera" :loading="cameraLoading" type="primary" | 
 |  |  |             @click="enterCamera">开始裁剪</el-button> | 
 |  |  |           <el-button v-show="!blobFileCamera" type="primary" @click="setImage">拍摄</el-button> | 
 |  |  |         </div> | 
 |  |  |       </span> | 
 |  |  |     </el-dialog> | 
 |  |  |     <!--  --> | 
 |  |  |     <el-dialog append-to-body :close-on-click-modal="false" title="上传图片" :visible.sync="isShowCropper" width="1000px" | 
 |  |  |       class="icon-dialog-wrapper dialong-com-style"> | 
 |  |  |       <ImageCropper ref="iconShot" v-if="isShowCropper" :imgSrc="blobFileCamera"> | 
 |  |  |       </ImageCropper> | 
 |  |  |       <span slot="footer" class="dialog-footer"> | 
 |  |  |         <el-button v-if="loading">取 消</el-button> | 
 |  |  |         <el-button v-else @click="isShowCropper = false">取 消</el-button> | 
 |  |  |         <el-button :loading="loading" type="primary" @click="uploadIcon">确 定</el-button> | 
 |  |  |       </span> | 
 |  |  |     </el-dialog> | 
 |  |  |   </GlobalWindow> | 
 |  |  | </template> | 
 |  |  |  | 
 |  |  | 
 |  |  | import GlobalWindow from '@/components/common/GlobalWindow' | 
 |  |  | import UploadAvatarImage from '@/components/common/UploadAvatarImage' | 
 |  |  | import UploadFaceImg from '@/components/common/UploadFaceImg' | 
 |  |  | import ImageCropper from '@/components/common/ImageCropper' | 
 |  |  | import { checkMobile, validIdCardNo, validIdCardNoNew } from '@/utils/form' | 
 |  |  | import { allList } from '@/api/business/position' | 
 |  |  | import { upload } from '@/api/system/common' | 
 |  |  | export default { | 
 |  |  |   name: 'OperaCompanyWindow', | 
 |  |  |   extends: BaseOpera, | 
 |  |  |   components: { GlobalWindow, UploadAvatarImage, UploadFaceImg }, | 
 |  |  |   components: { GlobalWindow, UploadAvatarImage, UploadFaceImg, ImageCropper }, | 
 |  |  |   data() { | 
 |  |  |     return { | 
 |  |  |       isShowCamera: false, | 
 |  |  |       paisheModal: false, | 
 |  |  |       cameraLoading: false, | 
 |  |  |       videoWidth: 700, | 
 |  |  |       videoHeight: 525, | 
 |  |  |       mediaStreamCamera: '', | 
 |  |  |       blobFileCamera: '', | 
 |  |  |       isShowCropper: false, | 
 |  |  |       loading: false, | 
 |  |  |       // 以上是拍摄 | 
 |  |  |       uploadData: { | 
 |  |  |         folder: 'member' | 
 |  |  |       }, | 
 |  |  | 
 |  |  |     }) | 
 |  |  |   }, | 
 |  |  |   methods: { | 
 |  |  |     openCamera() { | 
 |  |  |       this.paisheModal = true | 
 |  |  |       this.isShowCamera = true | 
 |  |  |       const that = this | 
 |  |  |       this.$nextTick(() => { | 
 |  |  |         var mediaOpts = { audio: false, video: true } | 
 |  |  |         navigator.mediaDevices | 
 |  |  |           .getUserMedia(mediaOpts) | 
 |  |  |           .then(function (stream) { | 
 |  |  |             that.mediaStreamCamera = stream | 
 |  |  |             const video = document.querySelector('#videoCamera') | 
 |  |  |             if ('srcObject' in video) { | 
 |  |  |               video.srcObject = stream | 
 |  |  |             } else { | 
 |  |  |               video.src = | 
 |  |  |                 (window.URL && window.URL.createObjectURL(stream)) || stream | 
 |  |  |             } | 
 |  |  |             video.play() | 
 |  |  |           }) | 
 |  |  |           .catch(function (err) { | 
 |  |  |             console.log(err) | 
 |  |  |           }) | 
 |  |  |       }) | 
 |  |  |     }, | 
 |  |  |     // 重拍 | 
 |  |  |     resetCamera() { | 
 |  |  |       this.isShowCamera = true | 
 |  |  |       this.blobFileCamera = '' | 
 |  |  |       this.openCamera() | 
 |  |  |     }, | 
 |  |  |     // 关闭相机 | 
 |  |  |     closeCamera() { | 
 |  |  |       this.mediaStreamCamera.getVideoTracks().forEach(function (track) { | 
 |  |  |         track.stop() | 
 |  |  |       }) | 
 |  |  |       this.paisheModal = false | 
 |  |  |     }, | 
 |  |  |     // 点击拍摄 | 
 |  |  |     setImage() { | 
 |  |  |       const that = this | 
 |  |  |       that.isShowCamera = false | 
 |  |  |       const video = document.querySelector('#videoCamera') | 
 |  |  |       const canvas = document.querySelector('#canvasCamera') | 
 |  |  |       canvas | 
 |  |  |         .getContext('2d') | 
 |  |  |         .drawImage(video, 0, 0, that.videoWidth, that.videoHeight) | 
 |  |  |       this.mediaStreamCamera.getVideoTracks().forEach(function (track) { | 
 |  |  |         track.stop() | 
 |  |  |       }) | 
 |  |  |       const dataurl = canvas.toDataURL('image/jpg') | 
 |  |  |       // this.blobFileCamera = that.base64ToFile(dataurl, 'camera') | 
 |  |  |       this.blobFileCamera = dataurl | 
 |  |  |     }, | 
 |  |  |     // 确认拍摄 | 
 |  |  |     enterCamera() { | 
 |  |  |       this.isShowCropper = true | 
 |  |  |       this.paisheModal = false | 
 |  |  |       this.isShowCamera = true | 
 |  |  |     }, | 
 |  |  |     uploadIcon () { | 
 |  |  |       // 获取裁剪后的图片 | 
 |  |  |       this.$refs.iconShot.getImagecropper().getCropBlob((fileData) => { // 获取当前裁剪好的数据 | 
 |  |  |         // 注此时的data是一个Blob数据,部分接口接收的是File转化的FormData数据 | 
 |  |  |         console.log(fileData) | 
 |  |  |         const formData = new FormData() | 
 |  |  |  | 
 |  |  |         formData.append('folder', 'member') | 
 |  |  |         formData.append( | 
 |  |  |             'file', | 
 |  |  |             fileData | 
 |  |  |         ) | 
 |  |  |         this.loading = true | 
 |  |  |         upload(formData).then(res => { | 
 |  |  |           this.loading = false | 
 |  |  |           console.log(res) | 
 |  |  |           // this.file.imgurl = res.imgaddr | 
 |  |  |           // this.file.imgurlfull = res.url | 
 |  |  |           this.$message.success('上传成功') | 
 |  |  |           // this.imageSrc = res.url | 
 |  |  |           // this.updateImg = false | 
 |  |  |           this.form.faceImg = res.imgaddr | 
 |  |  |           this.form.faceImgFull = res.url | 
 |  |  |           // this.$emit('uploadSuccess', { imgurl: res.imgaddr, imgurlfull: res.url, name: res.originname }) | 
 |  |  |           // this.$emit('uploadEnd') | 
 |  |  |         }, () => { | 
 |  |  |           this.loading = false | 
 |  |  |         }) | 
 |  |  |       }) | 
 |  |  |     }, | 
 |  |  |     base64ToFile(base64, fileName) { | 
 |  |  |       // 将base64按照 , 进行分割 将前缀  与后续内容分隔开 | 
 |  |  |       const data = base64.split(',') | 
 |  |  |       // 利用正则表达式 从前缀中获取图片的类型信息(image/png、image/jpeg、image/webp等) | 
 |  |  |       const type = data[0].match(/:(.*?);/)[1] | 
 |  |  |       // 从图片的类型信息中 获取具体的文件格式后缀(png、jpeg、webp) | 
 |  |  |       const suffix = type.split('/')[1] | 
 |  |  |       // 使用atob()对base64数据进行解码  结果是一个文件数据流 以字符串的格式输出 | 
 |  |  |       const bstr = window.atob(data[1]) | 
 |  |  |       // 获取解码结果字符串的长度 | 
 |  |  |       let n = bstr.length | 
 |  |  |       // 根据解码结果字符串的长度创建一个等长的整形数字数组 | 
 |  |  |       // 但在创建时 所有元素初始值都为 0 | 
 |  |  |       const u8arr = new Uint8Array(n) | 
 |  |  |       // 将整形数组的每个元素填充为解码结果字符串对应位置字符的UTF-16 编码单元 | 
 |  |  |       while (n--) { | 
 |  |  |         // charCodeAt():获取给定索引处字符对应的 UTF-16 代码单元 | 
 |  |  |         u8arr[n] = bstr.charCodeAt(n) | 
 |  |  |       } | 
 |  |  |       // 利用构造函数创建File文件对象 | 
 |  |  |       // new File(bits, name, options) | 
 |  |  |       const file = new File([u8arr], `${fileName}.${suffix}`, { | 
 |  |  |         type: type | 
 |  |  |       }) | 
 |  |  |       // 将File文件对象返回给方法的调用者 | 
 |  |  |       return file | 
 |  |  |     }, | 
 |  |  |     handleChangeCompany(value) { | 
 |  |  |       if (this.form.company && this.form.company.length > 1) { | 
 |  |  |         this.form.companyId = this.form.company[this.form.company.length - 1] |