<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 setup name="FaceLogin">
|
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
|
import faceManager from "./faceManager.js";
|
import { uKeyLogin } from "@/api/user";
|
import { useUKeyStore } from "@/store/ukey";
|
import { storeToRefs } from 'pinia';
|
import useElement from '@/hooks/useElement.js';
|
import { useRoute, useRouter } from 'vue-router';
|
import { getToken, removeToken, setToken, getUname, setUname, removeUname, getUrole, setUrole, removeUrole } from '@/utils/auth';
|
const ukeyStore = useUKeyStore();
|
const { isIn, connect, id } = storeToRefs(ukeyStore);
|
const route = useRoute();
|
const router = useRouter();
|
|
const { $loading, $confirm, $message } = useElement();
|
// import const_num from "@/assets/js/const/const_num";
|
// import RSA from "@/assets/js/tools/RSA";
|
const props = defineProps({
|
faceShow: {
|
type: Boolean,
|
default: false
|
}
|
});
|
const status = ref(true);
|
const faceDetect = ref("请将正脸对准摄像头");
|
const imageBase64 = ref("");
|
const newstream = ref("");
|
const intTime = ref(null);
|
const postTime = ref(null);
|
const setTime = ref(null);
|
const redirect = ref(undefined);
|
const otherQuery = ref({});
|
const video = ref(null);
|
const canvas = ref(null);
|
|
watch(
|
() => route.path,
|
(_route) => {
|
const query = _route.query;
|
if (query) {
|
redirect.value = query.redirect;
|
otherQuery.value = getOtherQuery(query);
|
}
|
},
|
{ immediate: true }
|
);
|
|
onMounted(() => {
|
faceChange();
|
});
|
|
onBeforeUnmount(() => {
|
status.value = false;
|
clearVideo();
|
});
|
|
function getOtherQuery(query) {
|
return Object.keys(query).reduce((acc, cur) => {
|
if (cur !== 'redirect') {
|
acc[cur] = query[cur];
|
}
|
return acc;
|
}, {});
|
}
|
|
function clearVideo() {
|
clearInterval(intTime.value);
|
clearInterval(postTime.value);
|
clearTimeout(setTime.value);
|
for (let track of newstream.value.getTracks()) {
|
track.stop();
|
}
|
}
|
|
function getImg() {
|
let _video = video.value;
|
let _canvas = canvas.value;
|
let _context = _canvas.getContext("2d");
|
_context.drawImage(_video, 0, 0, 480, 320);
|
// 获取图片base64链接
|
imageBase64.value = _canvas.toDataURL("image/png");
|
}
|
|
function faceChange() {
|
faceDetect.value = "请将正脸对准摄像头";
|
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
|
//调用用户媒体设备, 访问摄像头
|
getUserMedia(
|
{ video: { width: 480, height: 320 } },
|
success,
|
error
|
);
|
} else {
|
alert("不支持访问用户媒体");
|
}
|
}
|
|
function getUserMedia(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);
|
}
|
}
|
|
function success(stream) {
|
//兼容webkit核心浏览器
|
let CompatibleURL = window.URL || window.webkitURL;
|
//将视频流设置为video元素的源
|
newstream.value = stream;
|
video.value.srcObject = stream;
|
video.value.play();
|
intTime.value = setInterval(() => {
|
getImg();
|
}, 0);
|
setTimeout(() => {
|
facePost();
|
}, 0);
|
}
|
|
function error(_error) {
|
console.log(`访问用户媒体设备失败${_error.name}, ${_error.message}`);
|
}
|
|
function facePost() {
|
if (isIn.value) {
|
faceDetect.value = "请先插入ukey";
|
setTime.value = setTimeout(() => {
|
facePost();
|
}, 500);
|
} else if (!imageBase64.value) {
|
faceDetect.value = "人脸识别中...";
|
setTime.value = setTimeout(() => {
|
facePost();
|
}, 500);
|
} else {
|
faceManager
|
.faceVerify('"' + imageBase64.value + '"', id.value)
|
.then((result) => {
|
let res = result;
|
if (res.code == 1 && res.data) {
|
faceDetect.value = '匹配成功';
|
let user = res.data2[0];
|
setTimeout(() => {
|
setUname(user.uname);
|
setToken('admin');
|
setUrole(user.urole);
|
router.push({path: redirect.value || '/', query: otherQuery.value});
|
}, 1000);
|
} else {
|
faceDetect.value = res.msg;
|
if (status.value == true) {
|
setTime.value = setTimeout(() => {
|
facePost();
|
}, 3000);
|
}
|
}
|
}).catch((err) => {
|
faceDetect.value = '网络链接失败';
|
if (status.value == true) {
|
setTime.value = setTimeout(() => {
|
facePost();
|
}, 3000);
|
}
|
});
|
}
|
}
|
|
function onLogin () {
|
faceManager.getUserName().then((res) => {
|
let { code, data } = res;
|
if (code == 1) {
|
uKeyLoginFn(data.uname, data.usnid);
|
}
|
}).catch((err) => {
|
console.log(err);
|
});
|
}
|
|
function uKeyLoginFn(username, password) {
|
uKeyLogin(username, password, id.value, true).then((res) => {
|
handleLogin(res, username);
|
}).catch((err) => {
|
console.log(err);
|
loading.value = false;
|
faceDetect.value = "网络异常";
|
facePost();
|
});
|
}
|
|
function handleLogin(res, username) {
|
let rs = res.data;
|
if (rs.code == 1) {
|
$message.success("登录成功");
|
sessionStorage.setItem("username", username);
|
sessionStorage.setItem("userId", rs.data);
|
router.push("/home");
|
// 设置用户的权限
|
// store.dispatch("user/getPermits");
|
} else {
|
faceDetect.value = rs.msg;
|
facePost();
|
}
|
}
|
|
</script>
|
<style lang="scss" scoped>
|
.text {
|
text-align: center;
|
padding: 10px 0;
|
}
|
</style>
|