|
|
|
@ -180,6 +180,26 @@
|
|
|
|
|
</div>
|
|
|
|
|
</span>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
<el-dialog
|
|
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
title="录入人脸"
|
|
|
|
|
:visible.sync="dialogFaceVisible"
|
|
|
|
|
width="400px"
|
|
|
|
|
@close="handleCancel"
|
|
|
|
|
>
|
|
|
|
|
<div>
|
|
|
|
|
<div class="face-content">
|
|
|
|
|
<video id="video" width="200px" height="200px" style="transform:rotateY(180deg)" autoplay />
|
|
|
|
|
<canvas id="canvas" width="200px" height="200px" style="transform:rotateY(180deg)" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="name">程小红</div>
|
|
|
|
|
<div class="code">工号:779</div>
|
|
|
|
|
<div class="result">
|
|
|
|
|
请稍后,<br>
|
|
|
|
|
正在为您录入人脸信息..
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
@ -187,6 +207,10 @@
|
|
|
|
|
import UserForm from '@/components/UserForm'
|
|
|
|
|
import { get_user_list, add, update, del, get_module_list, get_user_power_list, add_user_power, get_role_name_list } from '@/api/user/user'
|
|
|
|
|
import stringify from '@/utils/stringify'
|
|
|
|
|
import { userMedia } from '@/utils'
|
|
|
|
|
require('tracking/build/tracking-min.js')
|
|
|
|
|
require('tracking/build/data/face-min.js')
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'User',
|
|
|
|
|
components: { UserForm },
|
|
|
|
@ -236,7 +260,11 @@ export default {
|
|
|
|
|
standard_module_id: [],
|
|
|
|
|
consumables_module_id: [],
|
|
|
|
|
instrument_module_id: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 人脸识别
|
|
|
|
|
dialogFaceVisible: false,
|
|
|
|
|
videoObj: null,
|
|
|
|
|
trackerTask: null
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
@ -244,6 +272,9 @@ export default {
|
|
|
|
|
this.getRoleList()
|
|
|
|
|
this.getModelList()
|
|
|
|
|
},
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
this.handleCancel()
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
getModelList() {
|
|
|
|
|
get_module_list().then(res => {
|
|
|
|
@ -283,7 +314,6 @@ export default {
|
|
|
|
|
this['isIndeterminate_' + t] = false
|
|
|
|
|
},
|
|
|
|
|
handleCheckedCitiesChange(value, t) {
|
|
|
|
|
console.log(value)
|
|
|
|
|
const checkedCount = value.length
|
|
|
|
|
this.$set(this, 'checkAll_' + t, checkedCount === this[t + 'Options'].length)
|
|
|
|
|
this['isIndeterminate_' + t] = checkedCount > 0 && checkedCount < this[ t + 'Options'].length
|
|
|
|
@ -331,7 +361,8 @@ export default {
|
|
|
|
|
this.dialogVisible = true
|
|
|
|
|
},
|
|
|
|
|
handleFace(index, row) {
|
|
|
|
|
|
|
|
|
|
this.dialogFaceVisible = true
|
|
|
|
|
this.openCamera()
|
|
|
|
|
},
|
|
|
|
|
handleRole(index, row) {
|
|
|
|
|
this.roleDialogVisible = true
|
|
|
|
@ -409,6 +440,65 @@ export default {
|
|
|
|
|
consumables_module_id: [],
|
|
|
|
|
instrument_module_id: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/*
|
|
|
|
|
人脸识别相关
|
|
|
|
|
*/
|
|
|
|
|
openCamera() {
|
|
|
|
|
// 有可能触发一些其他的按钮会重新获取
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
const canvas = document.getElementById('canvas')
|
|
|
|
|
const context = canvas.getContext('2d')
|
|
|
|
|
this.videoObj = document.getElementById('video')
|
|
|
|
|
// eslint-disable-next-line no-undef
|
|
|
|
|
const tracker = new tracking.ObjectTracker('face') // 检测人脸
|
|
|
|
|
tracker.setInitialScale(4)
|
|
|
|
|
tracker.setStepSize(2)
|
|
|
|
|
tracker.setEdgesDensity(0.1)
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-undef
|
|
|
|
|
this.trackerTask = tracking.track('#video', tracker, { camera: true })
|
|
|
|
|
|
|
|
|
|
const constraints = {
|
|
|
|
|
video: { width: 200, height: 200 },
|
|
|
|
|
audio: false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userMedia(constraints, this.success, this.error)
|
|
|
|
|
|
|
|
|
|
tracker.on('track', (event) => {
|
|
|
|
|
event.data.forEach((rect) => {
|
|
|
|
|
// 绘制到 canvas
|
|
|
|
|
context.drawImage(this.videoObj, 0, 0, canvas.width, canvas.height)
|
|
|
|
|
context.font = '16px Helvetica'
|
|
|
|
|
context.strokeStyle = '#1890ff'
|
|
|
|
|
context.strokeRect(rect.x, rect.y, rect.width, rect.height)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (event.data.length !== 0) {
|
|
|
|
|
// 有人脸数据了,此时就可以截取图片传递给后端
|
|
|
|
|
// canvas 调用 toDataURL
|
|
|
|
|
const base64Img = canvas.toDataURL('image/jpeg')
|
|
|
|
|
console.log(base64Img)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleCancel() {
|
|
|
|
|
this.videoObj.srcObject.getTracks()[0].stop()
|
|
|
|
|
this.trackerTask.stop()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 成功显示
|
|
|
|
|
success(stream) {
|
|
|
|
|
this.videoObj.srcObject = stream
|
|
|
|
|
this.videoObj.play()
|
|
|
|
|
},
|
|
|
|
|
// 失败抛出错误,可能用户电脑没有摄像头,或者摄像头权限没有打开
|
|
|
|
|
error(error) {
|
|
|
|
|
// 可以在这里面提示用户
|
|
|
|
|
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -439,6 +529,38 @@ export default {
|
|
|
|
|
float: right;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
video,canvas{
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 100px;
|
|
|
|
|
left: 120px;
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
border: 1px solid #707070;
|
|
|
|
|
}
|
|
|
|
|
.face-content{
|
|
|
|
|
text-align: center;
|
|
|
|
|
height: 18.75rem;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
.name{
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 30px;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
|
|
|
|
.code{
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
color: #409EFF;
|
|
|
|
|
margin-top: 1rem;
|
|
|
|
|
}
|
|
|
|
|
.result {
|
|
|
|
|
margin-top: 1rem;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: #C0C4CC;
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|