| | |
| | | "parserOptions": { |
| | | "parser": "babel-eslint" |
| | | }, |
| | | "rules": {} |
| | | "rules": { |
| | | "no-debugger":"off" |
| | | } |
| | | }, |
| | | "browserslist": [ |
| | | "> 1%", |
| | |
| | | </a-tabs> |
| | | <div> |
| | | <a-checkbox :checked="true" >自动登录</a-checkbox> |
| | | <a @click="faceLogin()">人脸登录</a> |
| | | <a style="float: right">忘记密码</a> |
| | | </div> |
| | | <a-form-item> |
| | |
| | | </a-form-item> |
| | | </a-form> |
| | | </div> |
| | | // 人脸登录弹窗 |
| | | <a-modal v-model="faceVisible" title="人脸登录"> |
| | | <template #footer> |
| | | <a-button key="back" @click="{faceVisible = false}">关闭</a-button> |
| | | </template> |
| | | <face-login |
| | | v-if="faceVisible" |
| | | :visible.sync="faceVisible" |
| | | @success="faceSuccess" |
| | | ></face-login> |
| | | </a-modal> |
| | | </common-layout> |
| | | </template> |
| | | |
| | | <script> |
| | | import CommonLayout from '@/layouts/CommonLayout' |
| | | import faceLogin from "./components/face/FaceLogin.vue"; |
| | | import {login, getRoutesConfig} from '@/services/user' |
| | | import {setAuthorization} from '@/utils/request' |
| | | import {loadRoutes} from '@/utils/routerUtil' |
| | |
| | | |
| | | export default { |
| | | name: 'Login', |
| | | components: {CommonLayout}, |
| | | components: {CommonLayout,faceLogin}, |
| | | data () { |
| | | return { |
| | | |
| | | faceVisible:false, |
| | | logging: false, |
| | | error: '', |
| | | form: this.$form.createForm(this) |
| | |
| | | methods: { |
| | | ...mapMutations('account', ['setUser', 'setPermissions', 'setRoles']), |
| | | onSubmit (e) { |
| | | |
| | | e.preventDefault() |
| | | this.form.validateFields((err) => { |
| | | if (!err) { |
| | |
| | | } else { |
| | | this.error = loginRes.message |
| | | } |
| | | }, |
| | | // 人脸登录 |
| | | faceLogin:function(){ |
| | | let vm = this; |
| | | vm.faceVisible = true; |
| | | console.log("人脸登录") |
| | | }, |
| | | // 人脸验证成功回调 |
| | | faceSuccess:function(){ |
| | | console.log("验证成功") |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <template> |
| | | <!-- 人脸登陆弹窗 --> |
| | | <div> |
| | | <video ref="video" width="480" height="320" style="display: none"></video> |
| | | <canvas ref="canvas" width="480" height="320"></canvas> |
| | | <p class="text">{{ faceDetect }}</p> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | props: { |
| | | faceShow: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | status: true, |
| | | faceDetect: "请将正脸对准摄像头", |
| | | imageBase64: "", |
| | | newstream: "", |
| | | intTime: null, |
| | | postTime: null, |
| | | setTime: null |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.faceChange(); |
| | | }, |
| | | destroyed: function() { |
| | | this.status = false; |
| | | this.clearVideo(); |
| | | }, |
| | | methods: { |
| | | // 关闭摄像头 |
| | | clearVideo: function() { |
| | | // 关闭定时器 |
| | | clearInterval(this.intTime); |
| | | clearInterval(this.postTime); |
| | | clearTimeout(this.setTime); |
| | | // 关闭摄像头 |
| | | for (let track of this.newstream.getTracks()) { |
| | | track.stop(); |
| | | } |
| | | }, |
| | | // 获取图片 |
| | | getImg: function() { |
| | | let vm = this; |
| | | let video = vm.$refs.video; |
| | | let canvas = vm.$refs.canvas; |
| | | let context = canvas.getContext("2d"); |
| | | context.drawImage(video, 0, 0, 480, 320); |
| | | // 获取图片base64链接 |
| | | vm.imageBase64 = canvas.toDataURL("image/png"); |
| | | }, |
| | | // 人脸检测 |
| | | faceChange: function() { |
| | | let vm = this; |
| | | // 恢复提示语 |
| | | vm.faceDetect = "请将正脸对准摄像头"; |
| | | // vm.faceShow = true; |
| | | if ( |
| | | navigator.mediaDevices.getUserMedia || |
| | | navigator.getUserMedia || |
| | | navigator.webkitGetUserMedia || |
| | | navigator.mozGetUserMedia |
| | | ) { |
| | | //调用用户媒体设备, 访问摄像头 |
| | | this.getUserMedia( |
| | | { video: { width: 480, height: 320 } }, |
| | | this.success, |
| | | this.error |
| | | ); |
| | | } else { |
| | | alert("不支持访问用户媒体"); |
| | | } |
| | | }, |
| | | //访问用户媒体设备的兼容方法 |
| | | getUserMedia: function(constraints, success, error) { |
| | | if (navigator.mediaDevices.getUserMedia) { |
| | | //最新的标准API |
| | | navigator.mediaDevices |
| | | .getUserMedia(constraints) |
| | | .then(success) |
| | | .catch(error); |
| | | } else if (navigator.webkitGetUserMedia) { |
| | | //webkit核心浏览器 |
| | | navigator.webkitGetUserMedia(constraints, success, error); |
| | | } else if (navigator.mozGetUserMedia) { |
| | | //firfox浏览器 |
| | | navigator.mozGetUserMedia(constraints, success, error); |
| | | } else if (navigator.getUserMedia) { |
| | | //旧版API |
| | | navigator.getUserMedia(constraints, success, error); |
| | | } |
| | | }, |
| | | // 成功回调 |
| | | success: function(stream) { |
| | | let vm = this; |
| | | //兼容webkit核心浏览器 |
| | | // let CompatibleURL = window.URL || window.webkitURL; |
| | | //将视频流设置为video元素的源 |
| | | // console.log(stream); |
| | | // stream = stream; |
| | | this.newstream = stream; |
| | | //video.src = CompatibleURL.createObjectURL(stream); |
| | | let video = this.$refs.video; |
| | | video.srcObject = stream; |
| | | video.play(); |
| | | this.intTime = setInterval(() => { |
| | | vm.getImg(); |
| | | }, 0); |
| | | // 回调验证人脸图片 |
| | | // setTimeout(function() { |
| | | // vm.facePost(); |
| | | // }, 0); |
| | | }, |
| | | error: function(error) { |
| | | console.log(error); |
| | | console.log(`访问用户媒体设备失败${error.name}, ${error.message}`); |
| | | }, |
| | | } |
| | | }; |
| | | </script> |
| | | <style lang="less" scoped> |
| | | .text { |
| | | text-align: center; |
| | | padding: 10px 0; |
| | | } |
| | | </style> |