需求:身份证阅读器在浏览器上接入读取身份证信息
JAVA后端身份证图片合成https://blog.csdn.net/Ajie246862/article/details/125259692
1. 身份证阅读器
出于成本问题,我们接入的山东信通身份证阅读器。
电脑接入USB
2. 读取插件
信通一般会发送公安部身份证读取插件
3. VUE端组件
<template>
<div>
<el-button type="success" :loading="loading" @click="readCert">身份证阅读器</el-button>
<object id="CertCtl" type="application/cert-reader" width="0" height="0">
<p style="color:#FF0000;">读卡器不可用</p>
</object>
</div>
</template>
<script>
export default {
name: 'IdcardReader',
data() {
return {
loading: false,
}
},
methods: {
/** 身份证阅读器读取数据 */
readCert() {
this.loading = true;
const CertCtl = document.getElementById("CertCtl");
try {
let connect = JSON.parse(CertCtl.connect());
if (connect.isCloud != 1) {
this.loading = false;
return this.$emit('data', { flag: false, msg: connect.errorMsg });
}
let status = JSON.parse(CertCtl.getStatus());
if (connect.isCloud != 1) {
this.loading = false;
return this.$emit('data', { flag: false, msg: connect.errorMsg });
}
let result = JSON.parse(CertCtl.readCert());
if (connect.isCloud != 1) {
this.loading = false;
return this.$emit('data', { flag: false, msg: connect.errorMsg });
}
let res = result.resultContent;
this.$confirm('是否获取身份证正反面样例图片?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 头像编码转文件对象
const file = this.convertAvatar(`data:image/gif;base64,${res.identityPic}`, 'avatar.png');
let formData = new FormData();
formData.append('file', file);
// 上传身份证信息、获取身份证正反面图片
idcardPic(formData, this.convertAvatarForm(res)).then((response) => {
this.loading = false;
// 将最终数据返回到需要页面
return this.$emit('data', { flag: true, info: this.convertForm(res, response.data, true) });
}).catch(() => {
this.loading = false;
});
}).catch(() => {
this.loading = false;
return this.$emit('data', { flag: true, info: this.convertForm(res, null, false) });
});
// 断开设备
CertCtl.disconnect()
} catch(e) {
this.loading = false;
this.$notify({
title: '警告',
message: `控件不可用,可能未正确安装控件及驱动,
或者控件未启用
(浏览器版本要求:谷歌(4.2以下);火狐(5.6以下)。`,
type: 'warning'
});
}
},
/** 头像base64转文件对象 */
convertAvatar(url, filename) {
let arr = url.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while(n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type:mime});
},
/** 返回数据对象 */
convertForm(data, urls, flag) {
if (data) {
if (flag) {
return {
idcardFront: urls.face, // 身份证正面
idcardBack: urls.back, // 身份证反面
idcard: data.certNumber, // 身份证号
name: data.partyName, // 姓名
sex: data.gender == 1 ? '0' : '1',
nation: data.nation, // 民族
address: data.certAddress, // 地址
birthday: this.parseDate(data.bornDay), // 生日
};
} else {
return {
idcard: data.certNumber, // 身份证号
name: data.partyName, // 姓名
sex: data.gender == 1 ? '0' : '1',
nation: data.nation, // 民族
address: data.certAddress, // 地址
birthday: this.parseDate(data.bornDay), // 生日
};
}
}
},
/** 上传获取图片数据对象 */
convertAvatarForm(data) {
if (data) {
let date = data.bornDay;
let begin = data.effDate;
let end = data.expDate;
let sex = data.gender == 1 ? '男' : '女';
let lssueTime = `${begin.substr(0, 4)}.${begin.substr(4, 2)}.${begin.substr(6, 2)}`;
let invalidTime = `${end.substr(0, 4)}.${end.substr(4, 2)}.${end.substr(6, 2)}`;
return `/idcard/pic?name=${data.partyName}&sex=${sex}&nation=${data.nation}&year=${date.substr(0, 4)}&month=${date.substr(4, 2)}&day=${date.substr(6, 2)}&address=${data.certAddress}&idcard=${data.certNumber}&lssueOffice=${data.certOrg}&lssueTime=${lssueTime}&invalidTime=${invalidTime}`;
}
}
},
}
</script>