| | |
| | | </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] |