| | |
| | | { |
| | | "name": "admin_manage", |
| | | "version": "2.2.5", |
| | | "version": "1.0.5", |
| | | "private": true, |
| | | "scripts": { |
| | | "serve": "vue-cli-service serve --mode dev", |
| | |
| | | des: '电池信息配置中点击编辑可以远程修改ip', |
| | | value: false, |
| | | }, |
| | | dischargeByFace: { |
| | | label: '启动放电添加人脸识别', |
| | | des: '启动充放电测试使用人脸识别', |
| | | value: true, |
| | | }, |
| | | } |
| | |
| | | <div class="flex-box-border border-bottom-right"></div> |
| | | <div class="flex-box-header" v-if="!noHeader" :class="{'no-header-bg':noHeaderBg}"> |
| | | <flex-layout direction="row" no-bg> |
| | | <div slot="header"> |
| | | <i class="iconfont el-icon-fold"></i> |
| | | <span class="header-text">{{title}}</span> |
| | | </div> |
| | | <div class="flex-header-tools"><slot name="tools"></slot></div> |
| | | <div slot="header"> |
| | | <i class="iconfont el-icon-fold"></i> |
| | | <span class="header-text">{{ title }}</span> |
| | | </div> |
| | | <div class="flex-header-tools"> |
| | | <slot name="tools"></slot> |
| | | </div> |
| | | </flex-layout> |
| | | |
| | | |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .flex-box { |
| | | position: relative; |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100%; |
| | | } |
| | | .flex-box-border{ |
| | | position: absolute; |
| | | display: inline-block; |
| | | z-index: 9; |
| | | } |
| | | .flex-box-border.border-top-left { |
| | | top: 0; |
| | | left: 0; |
| | | border-top: 2px solid #00FEFF; |
| | | border-left: 2px solid #00FEFF; |
| | | } |
| | | .flex-box-border.border-top-right { |
| | | top: 0; |
| | | right: 0; |
| | | border-top: 2px solid #00FEFF; |
| | | border-right: 2px solid #00FEFF; |
| | | } |
| | | .flex-box-border.border-bottom-left { |
| | | bottom: 0; |
| | | left: 0; |
| | | border-bottom: 2px solid #00FEFF; |
| | | border-left: 2px solid #00FEFF; |
| | | } |
| | | .flex-box-border.border-bottom-right { |
| | | bottom: 0; |
| | | right: 0; |
| | | border-bottom: 2px solid #00FEFF; |
| | | border-right: 2px solid #00FEFF; |
| | | } |
| | | .flex-box-header { |
| | | position: relative; |
| | | padding: 12px 0; |
| | | font-size: 14px; |
| | | color: #00fefe; |
| | | font-weight: bold; |
| | | } |
| | | .flex-box-header.no-header-bg { |
| | | background: none; |
| | | padding: 8px 0; |
| | | } |
| | | .flex-header-tools { |
| | | position: absolute; |
| | | top: 8px; |
| | | right: 16px; |
| | | } |
| | | .flex-box-header .iconfont { |
| | | font-size: 10px; |
| | | margin-right: 8px; |
| | | margin-left: 16px; |
| | | transform: rotate(90deg); |
| | | } |
| | | .header-text { |
| | | font-weight: bold; |
| | | } |
| | | .flex-box-body { |
| | | position: relative; |
| | | flex: 1; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | } |
| | | .flex-box { |
| | | position: relative; |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100%; |
| | | } |
| | | |
| | | .flex-box-border { |
| | | position: absolute; |
| | | display: inline-block; |
| | | z-index: 9; |
| | | } |
| | | |
| | | .flex-box-border.border-top-left { |
| | | top: 0; |
| | | left: 0; |
| | | border-top: 2px solid #00FEFF; |
| | | border-left: 2px solid #00FEFF; |
| | | } |
| | | |
| | | .flex-box-border.border-top-right { |
| | | top: 0; |
| | | right: 0; |
| | | border-top: 2px solid #00FEFF; |
| | | border-right: 2px solid #00FEFF; |
| | | } |
| | | |
| | | .flex-box-border.border-bottom-left { |
| | | bottom: 0; |
| | | left: 0; |
| | | border-bottom: 2px solid #00FEFF; |
| | | border-left: 2px solid #00FEFF; |
| | | } |
| | | |
| | | .flex-box-border.border-bottom-right { |
| | | bottom: 0; |
| | | right: 0; |
| | | border-bottom: 2px solid #00FEFF; |
| | | border-right: 2px solid #00FEFF; |
| | | } |
| | | |
| | | .flex-box-header { |
| | | position: relative; |
| | | padding: 12px 0; |
| | | font-size: 14px; |
| | | color: #00fefe; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .flex-box-header.no-header-bg { |
| | | background: none; |
| | | padding: 8px 0; |
| | | } |
| | | |
| | | .flex-header-tools { |
| | | position: absolute; |
| | | top: 8px; |
| | | right: 16px; |
| | | z-index: 9; |
| | | } |
| | | |
| | | .flex-box-header .iconfont { |
| | | font-size: 10px; |
| | | margin-right: 8px; |
| | | margin-left: 16px; |
| | | transform: rotate(90deg); |
| | | } |
| | | |
| | | .header-text { |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .flex-box-body { |
| | | position: relative; |
| | | flex: 1; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="face-check"> |
| | | <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> |
| | | import faceManager from '@/assets/js/apis/faceManager/faceManager.js' |
| | | import {uKeyLogin} from "@/assets/js/api"; |
| | | export default { |
| | | name: 'checkFace', |
| | | 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 = '请将正脸对准摄像头' |
| | | 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}`); |
| | | }, |
| | | // 请求后台验证人脸 |
| | | facePost: function () { |
| | | if(!this.$store.state.ukey.isIn) { |
| | | this.faceDetect = '请先插入ukey'; |
| | | this.setTime = setTimeout(() => { |
| | | this.facePost(); |
| | | }, 500); |
| | | }else { |
| | | let vm = this; |
| | | faceManager.faceVerify({fileData: vm.imageBase64}).then(res => { |
| | | let result = JSON.parse(res.data.result); |
| | | if (result.code == 1) { |
| | | vm.faceDetect = "匹配成功"; |
| | | setTimeout(() => { |
| | | vm.onLogin(); |
| | | }, 1000); |
| | | |
| | | } else { |
| | | vm.faceDetect = result.msg; |
| | | if (vm.status == true) { |
| | | this.setTime = setTimeout(() => { |
| | | this.facePost(); |
| | | }, 3000); |
| | | } |
| | | } |
| | | }).catch(err => { |
| | | vm.faceDetect = '网络链接失败'; |
| | | if (vm.status == true) { |
| | | this.setTime = setTimeout(() => { |
| | | this.facePost(); |
| | | }, 3000); |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | // 登陆设置sessionStorage |
| | | onLogin: function () { |
| | | let vm = this; |
| | | faceManager.getUserName().then(res => { |
| | | let result = JSON.parse(res.data.result); |
| | | if (result.code == 1) { |
| | | let loginUser = sessionStorage.getItem('username'); |
| | | let loginId = sessionStorage.getItem('userId'); |
| | | if(loginUser==result.data.UName && loginId == result.data.USnId) { |
| | | this.$emit('checkSuccess'); |
| | | }else { |
| | | vm.faceDetect = '人脸和登录用户不匹配'; |
| | | this.setTime = setTimeout(() => { |
| | | this.facePost(); |
| | | }, 3000); |
| | | } |
| | | } |
| | | }).catch(err => { |
| | | console.log(err); |
| | | }) |
| | | }, |
| | | uKeyLogin(username, password) { |
| | | // ukey登录 |
| | | uKeyLogin(username, password, this.$store.state.ukey.id).then(res=>{ |
| | | // 对结果进行处理 |
| | | this.handleLogin(res, username); |
| | | }).catch(error => { |
| | | // 关闭等待 |
| | | this.loading = false; |
| | | console.log(error); |
| | | this.faceDetect = "网络异常"; |
| | | this.facePost(); |
| | | }); |
| | | }, |
| | | handleLogin(res, username) { |
| | | let rs = JSON.parse(res.data.result); |
| | | if (rs.code == 1) { |
| | | this.$message.success("登录成功"); |
| | | sessionStorage.setItem('username', username); |
| | | sessionStorage.setItem('userId', rs.data); |
| | | this.$router.push("/home"); |
| | | // 设置用户的权限 |
| | | this.$store.dispatch('user/getPermits'); |
| | | } else { |
| | | this.faceDetect = rs.msg; |
| | | this.facePost(); |
| | | } |
| | | }, |
| | | }, |
| | | } |
| | | </script> |
| | | <style lang="less" scoped> |
| | | .face-check { |
| | | background-color: #FFFFFF; |
| | | } |
| | | .text { |
| | | text-align: center; |
| | | } |
| | | </style> |
| | |
| | | </div> |
| | | <div class="form-footer"> |
| | | <!-- <three-btn>清除告警</three-btn> --> |
| | | <three-btn :disabled="!startTestFlag" @click="confirmStartTest">启动测试</three-btn> |
| | | <three-btn :disabled="!startTestFlag" @click="startTestCheck">启动测试</three-btn> |
| | | <three-btn @click="getParams(true)">读取</three-btn> |
| | | <three-btn :disabled="!setTestFlag" @click="submitFrom">设定</three-btn> |
| | | </div> |
| | | <el-dialog |
| | | title="人脸校验" width="480px" |
| | | :visible.sync="setFaceShow" |
| | | :close-on-click-modal="false" top="0" |
| | | :modal="false" |
| | | class="dialog-center" |
| | | :modal-append-to-body="false" :destroy-on-close="true"> |
| | | <check-face @check-success="setFaceSuccess"></check-face> |
| | | </el-dialog> |
| | | <el-dialog |
| | | title="人脸校验" width="480px" |
| | | :visible.sync="startFaceShow" |
| | | :close-on-click-modal="false" top="0" |
| | | :modal="false" |
| | | class="dialog-center" |
| | | :modal-append-to-body="false" :destroy-on-close="true"> |
| | | <check-face @check-success="startFaceSuccess"></check-face> |
| | | </el-dialog> |
| | | </el-form> |
| | | </template> |
| | | |
| | |
| | | import { |
| | | testVal |
| | | } from '../../../assets/js/tools' |
| | | import CheckFace from "@/components/checkFace"; |
| | | |
| | | import config from "@/assets/js/config"; |
| | | |
| | | export default { |
| | | components: {CheckFace}, |
| | | props: { |
| | | batt: { |
| | | type: Object, |
| | |
| | | rules.MonomerVol_Low.max = (batt.MonVolStd*1.2).toHold(1); |
| | | rules.MonomerVol_Low.msg = "取值范围"+rules.MonomerVol_Low.min+"~"+rules.MonomerVol_Low.max+"(保留一位小数)"; |
| | | return { |
| | | setFaceShow: false, |
| | | startFaceShow: false, |
| | | cmd: cmd, // 操作命令 |
| | | testType: testType, // 测试类型 |
| | | startTestFlag: false, // 启动测试的状态 |
| | |
| | | this.$layer.confirm("确认修改参数", {icon: 3, title: '系统提示'}, (index)=>{ |
| | | // 关闭确认框 |
| | | this.$layer.close(index); |
| | | this.setParams(); |
| | | this.setParamsCheck(); |
| | | }); |
| | | |
| | | } else { |
| | |
| | | return false; |
| | | } |
| | | }); |
| | | }, |
| | | setParamsCheck() { |
| | | if(config.dischargeByFace.value) { |
| | | this.setFaceShow = true; |
| | | }else { |
| | | this.setParams(true); |
| | | } |
| | | }, |
| | | // 设置参数 |
| | | setParams() { |
| | |
| | | // 提示信息 |
| | | this.$layer.msg('设置失败,设置请求异常!'); |
| | | }); |
| | | }, |
| | | startTestCheck() { |
| | | if(config.dischargeByFace.value) { |
| | | this.startFaceShow = true; |
| | | }else { |
| | | this.confirmStartTest(); |
| | | } |
| | | }, |
| | | // 确认框 |
| | | confirmStartTest() { |
| | |
| | | this.$layer.msg('启动测试失败,启动测试请求异常!'); |
| | | }); |
| | | }, |
| | | // 清除告警 |
| | | clearWarning() { |
| | | |
| | | } |
| | | setFaceSuccess() { |
| | | this.setFaceShow = false; |
| | | this.setParams(); |
| | | }, |
| | | startFaceSuccess() { |
| | | this.startFaceShow = false; |
| | | this.startTest(); |
| | | }, |
| | | }, |
| | | computed: { |
| | | otherParams() { |
| | |
| | | </div> |
| | | <div class="form-footer"> |
| | | <!-- <three-btn>清除告警</three-btn> --> |
| | | <three-btn :disabled="!startTestFlag" @click="startTest">启动测试</three-btn> |
| | | <three-btn :disabled="!startTestFlag" @click="startTestCheck">启动测试</three-btn> |
| | | <three-btn @click="getParams(true)">读取</three-btn> |
| | | <three-btn :disabled="!setTestFlag" @click="submitFrom">设定</three-btn> |
| | | </div> |
| | | <el-dialog |
| | | title="人脸校验" width="480px" |
| | | :visible.sync="setFaceShow" |
| | | :close-on-click-modal="false" top="0" |
| | | :modal="false" |
| | | class="dialog-center" |
| | | :modal-append-to-body="false" :destroy-on-close="true"> |
| | | <check-face @check-success="setFaceSuccess"></check-face> |
| | | </el-dialog> |
| | | <el-dialog |
| | | title="人脸校验" width="480px" |
| | | :visible.sync="startFaceShow" |
| | | :close-on-click-modal="false" top="0" |
| | | :modal="false" |
| | | class="dialog-center" |
| | | :modal-append-to-body="false" :destroy-on-close="true"> |
| | | <check-face @check-success="startFaceSuccess"></check-face> |
| | | </el-dialog> |
| | | </el-form> |
| | | </template> |
| | | |
| | |
| | | import { |
| | | const_9100 |
| | | } from "@/assets/js/const" |
| | | import config from "@/assets/js/config"; |
| | | import checkFace from "@/components/checkFace"; |
| | | export default { |
| | | name: "BtsDischargeParams", |
| | | components: { |
| | | checkFace |
| | | }, |
| | | props: { |
| | | batt: { |
| | | type: Object, |
| | |
| | | rules.MonomerVol_Low.msg = "取值范围"+rules.MonomerVol_Low.min+"~"+rules.MonomerVol_Low.max+"(保留一位小数)"; |
| | | |
| | | return { |
| | | setFaceShow: false, |
| | | startFaceShow: false, |
| | | cmd: cmd, // 操作命令 |
| | | startTestFlag: false, // 启动测试的状态 |
| | | setTestFlag: false, // 设置参数的状态 |
| | |
| | | // 校验通过 |
| | | if (valid) { |
| | | // 设置参数 |
| | | this.setParams(); |
| | | this.setParamsCheck(); |
| | | } else { |
| | | this.$layer.msg('存在校验未通过的数据!'); |
| | | return false; |
| | | } |
| | | }); |
| | | }, |
| | | setParamsCheck() { |
| | | if(config.dischargeByFace.value) { |
| | | this.setFaceShow = true; |
| | | }else { |
| | | this.setParams(true); |
| | | } |
| | | }, |
| | | // 设置参数 |
| | | setParams() { |
| | |
| | | // 提示信息 |
| | | this.$layer.msg('设置失败,设置请求异常!'); |
| | | }); |
| | | }, |
| | | startTestCheck() { |
| | | if(config.dischargeByFace.value) { |
| | | this.startFaceShow = true; |
| | | }else { |
| | | this.confirmStartTest(); |
| | | } |
| | | }, |
| | | // 确认框 |
| | | confirmStartTest() { |
| | | this.$layer.prompt({title: '输入启动口令,并确认', formType: 2, area: ['300px', '180px']}, (pass, index) => { |
| | | // 请求后台校验密码 |
| | | this.$apis.login.checkUserPwd(pass).then(res=>{ |
| | | let rs = JSON.parse(res.data.result); |
| | | if(rs.code == 1) { |
| | | // 关闭弹出框 |
| | | this.$layer.close(index); |
| | | this.$layer.msg("密码检测通过,启动测试"); |
| | | // 启动测试 |
| | | this.startTest(); |
| | | }else { |
| | | this.$layer.msg("启动口令错误!"); |
| | | } |
| | | }).catch(error=>{ |
| | | console.log(error); |
| | | this.$layer.msg("网络请求异常"); |
| | | }); |
| | | }); |
| | | |
| | | }, |
| | | // 启动 |
| | | startTest() { |
| | |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | }, |
| | | setFaceSuccess() { |
| | | this.setFaceShow = false; |
| | | this.setParams(); |
| | | }, |
| | | startFaceSuccess() { |
| | | this.startFaceShow = false; |
| | | this.startTest(); |
| | | }, |
| | | }, |
| | | computed: { |
| | | otherParams() { |
| | |
| | | <el-row :gutter="layout.gutter" class="full-height"> |
| | | <el-col :span="layout.span" class="full-height"> |
| | | <flex-box title="1路交流输入电压"> |
| | | <i class="flex-box-tools-icon el-icon-s-tools" slot="tools"></i> |
| | | <e-chart-wrapper ref="acOneInputVol"></e-chart-wrapper> |
| | | </flex-box> |
| | | </el-col> |
| | |
| | | padding-top: 8px; |
| | | padding-bottom: 8px; |
| | | } |
| | | .flex-box-tools-icon { |
| | | font-size: 20px; |
| | | cursor: pointer; |
| | | } |
| | | .flex-box-tools-icon:active { |
| | | color: #FF0000; |
| | | } |
| | | </style> |