| | |
| | | <template> |
| | | <div class="login-container"> |
| | | <div class="login-logo"> |
| | | <span>岱特智能科技</span> |
| | | </div> |
| | | <div class="login-content" :class="{ 'login-content-mobile': tabsActiveName === 'mobile' }"> |
| | | <el-row :gutter="0"> |
| | | <el-col :xs="0" :sm="12" :md="12" :lg="12" :xl="12"> |
| | | <div class="login-content-image"> |
| | | <div></div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12"> |
| | | <div class="login-content-main"> |
| | | <div class="login-content-title"> |
| | | <div class="login-content-logo"></div> |
| | | <div class="login-title">胜透血液透析管理平台</div> |
| | | <div class="login-welcome">WELCOME欢迎登陆</div> |
| | | </div> |
| | | <div> |
| | | <Account /> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <div class="login-copyright"> |
| | | <div class="mb5 login-copyright-company"></div> |
| | | <div class="login-copyright-msg"></div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import { toRefs, reactive, computed } from 'vue'; |
| | | import Account from '@/views/login/component/account.vue'; |
| | | export default { |
| | | name: 'loginIndex', |
| | | components: { Account }, |
| | | setup() { |
| | | const state = reactive({ |
| | | tabsActiveName: 'account', |
| | | isTabPaneShow: true, |
| | | isScan: false, |
| | | }); |
| | | return { |
| | | ...toRefs(state), |
| | | }; |
| | | }, |
| | | |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .login-container { |
| | | width: 100%; |
| | | height: 100%; |
| | | background: url('@/assets/imgs/login/login-background.jpg') no-repeat; |
| | | background-size: 100% 100%; |
| | | .login-logo { |
| | | position: absolute; |
| | | top: 30px; |
| | | left: 50%; |
| | | height: 50px; |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 20px; |
| | | color: var(--color-primary); |
| | | letter-spacing: 2px; |
| | | width: 90%; |
| | | transform: translateX(-50%); |
| | | } |
| | | .login-content { |
| | | width: 848px; |
| | | // padding: 20px; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%) translate3d(0, 0, 0); |
| | | background-color: rgba(255, 255, 255, 0.99); |
| | | // border: 5px solid var(--color-primary-light-8); |
| | | border-radius: 10px; |
| | | transition: height 0.2s linear; |
| | | // height: 480px; |
| | | overflow: hidden; |
| | | z-index: 1; |
| | | .login-content-image { |
| | | padding: 40px 20px; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: #F1F7FF |
| | | } |
| | | .login-content-image div { |
| | | width: 100%; |
| | | height: 100%; |
| | | background: url('@/assets/imgs/login/login.jpg') no-repeat; |
| | | background-size: 100% 100%; |
| | | } |
| | | .login-content-main { |
| | | margin: 75px 50px; |
| | | // margin: 0 auto; |
| | | // width: 80%; |
| | | .login-content-title { |
| | | color: #333; |
| | | font-weight: 500; |
| | | font-size: 22px; |
| | | text-align: left; |
| | | // letter-spacing: 4px; |
| | | // margin: 15px 0 30px; |
| | | white-space: nowrap; |
| | | z-index: 5; |
| | | // position: relative; |
| | | // transition: all 0.3s ease; |
| | | .login-content-logo { |
| | | text-align: left; |
| | | width: 40px; |
| | | height: 30px; |
| | | background: url('@/assets/imgs/login/favicon.svg') no-repeat; |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | } |
| | | .login-title { |
| | | display: inline-block; |
| | | width: 224px; |
| | | height: 30px; |
| | | font-size: 21px; |
| | | font-family: PingFangSC-Medium, PingFang SC; |
| | | font-weight: 500; |
| | | color: #232426; |
| | | line-height: 30px; |
| | | letter-spacing: 1px; |
| | | vertical-align: middle; |
| | | } |
| | | .login-welcome { |
| | | width: 149px; |
| | | height: 20px; |
| | | font-size: 14px; |
| | | font-family: PingFangSC-Medium, PingFang SC; |
| | | font-weight: 500; |
| | | color: #AAAAAA; |
| | | line-height: 20px; |
| | | } |
| | | } |
| | | } |
| | | .login-content-main-sacn { |
| | | // position: absolute; |
| | | // top: 0; |
| | | // right: 0; |
| | | // width: 50px; |
| | | // height: 50px; |
| | | overflow: hidden; |
| | | cursor: pointer; |
| | | transition: all ease 0.3s; |
| | | &-delta { |
| | | position: absolute; |
| | | width: 35px; |
| | | height: 70px; |
| | | z-index: 2; |
| | | top: 2px; |
| | | right: 21px; |
| | | background: var(--el-color-white); |
| | | transform: rotate(-45deg); |
| | | } |
| | | &:hover { |
| | | opacity: 1; |
| | | transition: all ease 0.3s; |
| | | color: var(--color-primary); |
| | | } |
| | | i { |
| | | width: 47px; |
| | | height: 50px; |
| | | display: inline-block; |
| | | font-size: 48px; |
| | | position: absolute; |
| | | right: 2px; |
| | | top: -1px; |
| | | } |
| | | } |
| | | } |
| | | .login-content-mobile { |
| | | height: 418px; |
| | | } |
| | | .login-copyright { |
| | | position: absolute; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | bottom: 30px; |
| | | text-align: center; |
| | | color: var(--color-whites); |
| | | font-size: 12px; |
| | | opacity: 0.8; |
| | | .login-copyright-company { |
| | | white-space: nowrap; |
| | | } |
| | | .login-copyright-msg { |
| | | @extend .login-copyright-company; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | <teleport to="body"> |
| | | <div class="mask"> |
| | | <el-header class="go"> |
| | | <div> |
| | | 请把头移动到摄像头能拍到的位置,不要动 ! |
| | | </div> |
| | | <div class="box"> |
| | | <video id="videoCamera" class="canvas" :width="videoWidth" :height="videoHeight" autoPlay></video> |
| | | <canvas id="canvasCamera" class="canvas" :width="300" :height="300"></canvas> |
| | | </div> |
| | | <div class="footer"> |
| | | <el-button @click="getCompetence" icon="el-icon-video-camera"> 打开摄像头 </el-button> |
| | | <el-button @click="drawImage" icon="el-icon-camera"> 拍照 </el-button> |
| | | <el-button @click="stopNavigator" icon="el-icon-switch-button"> 关闭摄像头 </el-button> |
| | | <el-button @click="resetCanvas" icon="el-icon-refresh"> 重置 </el-button> |
| | | </div> |
| | | </el-header> |
| | | </div> |
| | | </teleport> |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import { ref, reactive, inject, toRefs, nextTick } from "vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | const loading = ref(false); |
| | | const os = ref(false); //控制摄像头开关 |
| | | let thisVideo = ref(""); |
| | | let thisContext = ref(""); |
| | | let thisCancas = ref(""); |
| | | const videoWidth = ref(500); |
| | | const videoHeight = ref(500); |
| | | const postOptions = ref([]); |
| | | const certCtl = ref(""); |
| | | const mask = ref(true); |
| | | |
| | | //查询参数 |
| | | const queryParams = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | imgSrc: undefined, |
| | | }); |
| | | const closedPhono = ref(null); |
| | | |
| | | const emit = defineEmits(["closed"]); |
| | | const props = defineProps({ |
| | | visible: { type: Boolean }, |
| | | }); |
| | | const { visible } = toRefs(props); |
| | | const handleChange = (val) => { |
| | | console.log(visible); |
| | | }; |
| | | |
| | | //调用摄像头权限 |
| | | const getCompetence = () => { |
| | | nextTick(() => { |
| | | os.value = false; |
| | | thisCancas = document.getElementById("canvasCamera"); |
| | | thisContext = thisCancas.getContext("2d"); |
| | | thisVideo = document.getElementById("videoCamera"); |
| | | closedPhono.value = thisVideo; |
| | | if (navigator.mediaDevices === undefined) { |
| | | navigator.mediaDevices = {}; |
| | | } |
| | | |
| | | if (navigator.mediaDevices.getUserMedia === undefined) { |
| | | navigator.mediaDevices.getUserMedia = function (constraints) { |
| | | // 首先获取现存的getUserMedia(如果存在) |
| | | let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia; |
| | | if (!getUserMedia) { |
| | | return Promise.reject(new Error("getUserMedia is not implemented in this browser")); |
| | | } |
| | | return new Promise(function (resolve, reject) { |
| | | getUserMedia.call(navigator, constraints, resolve, reject); |
| | | }); |
| | | }; |
| | | } |
| | | |
| | | const constraints = { |
| | | audio: false, |
| | | video: { width: videoWidth.value, height: videoHeight.value, transform: "scaleX(-1)" }, |
| | | }; |
| | | |
| | | navigator.mediaDevices |
| | | .getUserMedia(constraints) |
| | | .then(function (stream) { |
| | | if ("srcObject" in thisVideo) { |
| | | thisVideo.srcObject = stream; |
| | | } else { |
| | | thisVideo.src = window.URL.createObjectURL(stream); |
| | | } |
| | | thisVideo.onloadedmetadata = function (e) { |
| | | thisVideo.play(); |
| | | }; |
| | | }) |
| | | .catch((err) => { |
| | | ElMessage.error("没有开启摄像头权限或浏览器版本不兼容"); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | //绘制图片 |
| | | const drawImage = () => { |
| | | getCompetence(); |
| | | thisCancas = document.getElementById("canvasCamera"); |
| | | thisContext = thisCancas.getContext("2d"); |
| | | thisVideo = document.getElementById("videoCamera"); |
| | | thisContext.drawImage(thisVideo, 0, 0, 300, 300); |
| | | //获取图片地址 |
| | | queryParams.imgSrc = thisCancas.toDataURL('image/png'); |
| | | console.log(queryParams.imgSrc); |
| | | }; |
| | | |
| | | //清空画布 |
| | | const clearCanvas = (id) => { |
| | | let c = document.getElementById(id); |
| | | let cxt = c.getContext("2d"); |
| | | cxt.clearRect(0, 0, 500, 500); |
| | | |
| | | }; |
| | | |
| | | //重置画布 |
| | | const resetCanvas = () => { |
| | | queryParams.imgSrc = ""; |
| | | clearCanvas("canvasCamera"); |
| | | }; |
| | | |
| | | //关闭摄像头 |
| | | const stopNavigator = () => { |
| | | // thisVideo = document.getElementById("videoCamera"); |
| | | if (closedPhono.value && closedPhono.value !== null) { |
| | | thisVideo.srcObject.getTracks()[0].stop(); |
| | | os.value = true; |
| | | } else { |
| | | ElMessage.error("没有开启摄像头权限或浏览器版本不兼容"); |
| | | } |
| | | }; |
| | | defineExpose({ |
| | | stopNavigator, |
| | | }); |
| | | </script> |
| | | <style scoped> |
| | | .footer { |
| | | width: 959px; |
| | | height: 50px; |
| | | background-color: white; |
| | | justify-content: space-between; |
| | | float: left; |
| | | margin-top: 217px; |
| | | z-index: 1999; |
| | | } |
| | | |
| | | |
| | | .mask { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | bottom: 0; |
| | | right: 0; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | z-index: 999; |
| | | } |
| | | .closeBtn { |
| | | float: right; |
| | | } |
| | | .box { |
| | | width: 959px; |
| | | height: 700px; |
| | | margin-top: 10px; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | /* float: left !important; */ |
| | | padding-top: 100px; |
| | | text-align: center; |
| | | } |
| | | .go { |
| | | width: 1000px; |
| | | height: 800px; |
| | | background-color: white; |
| | | position: absolute; |
| | | left: 50%; |
| | | top: 50%; |
| | | transform: translate(-50%, -50%); |
| | | display: inline-block; |
| | | } |
| | | |
| | | </style> |