一、原生插件
二、封装方法
idCardUtils.js
export const idCardRepCode = (rep) => {
switch (rep) {
case '000090':
return "操作成功"
break;
case '00009F':
return "返回找卡成功信息"
break;
case '000010':
return "接收业务终端数据的校验和错"
break;
case '000011':
return "接收业务终端数据的长度错"
break;
case '000021':
return "接收业务终端的命令错误,包括命令中的各种数值或逻辑搭配错误"
break;
case '000024':
return "无法识别的错误"
break;
case '000031':
return "卡认证机具失败"
break;
case '000032':
return "机具认证卡失败"
break;
case '000033':
return "信息验证错误"
break;
case '000040':
return "错误的卡"
break;
case '000041':
return "读卡操作失败"
break;
case '000047':
return "取随机数失败"
break;
case '000060':
return "身份证阅读器自检失败,不能接收命令"
break;
case '000066':
return "身份证阅读器没经过授权无法使用"
break;
case '000080':
return "找卡不成功"
break;
case '000081':
return "选卡不成功"
break;
case '000091':
return "该项无内容"
break;
default:
break;
}
}
export const parseHexValue = (highHex, lowHex) => {
var highValue = parseInt(highHex, 16);
var lowValue = parseInt(lowHex, 16);
return (highValue << 8) | lowValue;
}
export const formatDate = (dateString) => {
if(dateString.length==2){
return dateString
}else{
const year = dateString.slice(0, 4);
const month = dateString.slice(4, 6);
const day = dateString.slice(6, 8);
return `${year}-${month}-${day}`;
}
}
export const EthnicTranslation = (code) => {
switch (code) {
case 1:
return "汉";
case 2:
return "蒙古";
case 3:
return "回";
case 4:
return "藏";
case 5:
return "维吾尔";
case 6:
return "苗";
case 7:
return "彝";
case 8:
return "壮";
case 9:
return "布依";
case 10:
return "朝鲜";
case 11:
return "满";
case 12:
return "侗";
case 13:
return "瑶";
case 14:
return "白";
case 15:
return "土家";
case 16:
return "哈尼";
case 17:
return "哈萨克";
case 18:
return "傣";
case 19:
return "黎";
case 20:
return "傈僳";
case 21:
return "佤";
case 22:
return "畲";
case 23:
return "高山";
case 24:
return "拉祜";
case 25:
return "水";
case 26:
return "东乡";
case 27:
return "纳西";
case 28:
return "景颇";
case 29:
return "柯尔克孜";
case 30:
return "土";
case 31:
return "达斡尔";
case 32:
return "仫佬";
case 33:
return "羌";
case 34:
return "布朗";
case 35:
return "撒拉";
case 36:
return "毛南";
case 37:
return "仡佬";
case 38:
return "锡伯";
case 39:
return "阿昌";
case 40:
return "普米";
case 41:
return "塔吉克";
case 42:
return "怒";
case 43:
return "乌孜别克";
case 44:
return "俄罗斯";
case 45:
return "鄂温克";
case 46:
return "德昂";
case 47:
return "保安";
case 48:
return "裕固";
case 49:
return "京";
case 50:
return "塔塔尔";
case 51:
return "独龙";
case 52:
return "鄂伦春";
case 53:
return "赫哲";
case 54:
return "门巴";
case 55:
return "珞巴";
case 56:
return "基诺";
case 97:
return "其他";
case 98:
return "外国血统中国籍人士";
default:
return "";
}
}
idCard.js
import {
formatDate,
idCardRepCode,
parseHexValue,
EthnicTranslation
} from './idCardUtils.js'
let andoridModule = uni.requireNativePlugin('Chen-HelloWorld');
let iconv = require('iconv-lite');
var idCard = uni.requireNativePlugin('Zhimi-SerialPort');
/* 中控身份证模块 */
export default {
idCardHexStr: '',
isIDflag: false,
idCardHexStrLength: null,
idCardInIt() {
let that = this;
that.open()
//设置接收数据buffer大小,默认512 如果数据比较大可以设置
idCard.setMaxBufferSize(102400);
//设置接收数据格式
idCard.setReceiveStringData(false); //字符串
idCard.setReceiveByteData(false); //字节数字
idCard.setReceiveHexData(true); //十六进制
//设置串口数据回调
idCard.setDataCallback(function(res) {
let data = res.data.replace(new RegExp(' ', 'g'), '');
let CMD = "AAAAAA9669";
let readCardAgain = ["选卡不成功", "读卡操作失败"];
if (data.includes(CMD)) {
let reply = idCardRepCode(data.slice(14, 20));
console.warn("****下位机应答****", reply);
readCardAgain.includes(reply) && that.sendHexData1();
reply.includes("返回找卡成功信息") && that.sendHexData2();
data.includes("AAAAAA9669000C0000900000000000000000") && that.sendHexData3();
if (parseHexValue(data.slice(10, 12), data.slice(12, 14)) >= 1200) {
that.isIDflag = true;
that.idCardHexStrLength = parseHexValue(data.slice(10, 12), data.slice(12, 14));
}
}
if (that.isIDflag) {
that.idCardHexStr = that.idCardHexStr + data;
if (that.idCardHexStr.length >= that.idCardHexStrLength * 2) {
let isIdCard = 'AAAAAA9669050800009001000400'
let hex = that.idCardHexStr.slice(isIdCard.length, that.idCardHexStr.length)
that.hexTohexArray(hex)
}
}
});
},
open() {
//打开串口
var path = "/dev/ttyS3"; //串口地址
var baudrate = 115200; //波特率
var flags = 0; //标记
idCard.open(path, baudrate, flags, function(res) {
console.log(res);
});
},
close() {
//关闭串口
idCard.close();
},
sendHexData1() {
//找卡
var data = "AA AA AA 96 69 00 03 20 01 22";
idCard.sendHexData(data);
this.idCardHexStr = ''
this.isIDflag = false;
},
sendHexData2() {
//选卡
var data = "AA AA AA 96 69 00 03 20 02 21";
idCard.sendHexData(data);
},
sendHexData3() {
//读卡
var data = "AA AA AA 96 69 00 03 30 01 32";
idCard.sendHexData(data);
},
// hex转hex数组
hexTohexArray(hex) {
let that = this;
const bytes = [];
for (let i = 0; i < hex.length - 1; i += 2) {
let index = Math.floor(i / 2);
const obj = hex.substring(i, i + 2)
bytes[index] = '0x' + obj;
}
that.parseIDCard(bytes, hex)
},
parseIDCard(bytes, hex) {
let that = this;
let Info = {};
let pages = getCurrentPages();
let page = pages[pages.length - 1]; //上一个页面
Info["name"] = iconv.decode(Buffer.from(bytes.slice(0, 30)), 'UTF-16LE').replace(/\s+/g, '');
Info["sex"] = iconv.decode(Buffer.from(bytes.slice(30, 32)), 'UTF-16LE').replace(/\s+/g, '') == '1' ? "男" : "女";
Info["nation"] = EthnicTranslation(Number(iconv.decode(Buffer.from(bytes.slice(32, 36)), 'UTF-16LE').replace(/\s+/g, '')));
Info["beborn"] = formatDate(iconv.decode(Buffer.from(bytes.slice(36, 52)), 'UTF-16LE').replace(/\s+/g, ''));
Info["address"] = iconv.decode(Buffer.from(bytes.slice(52, 122)), 'UTF-16LE').replace(/\s+/g, '');
Info["id"] = iconv.decode(Buffer.from(bytes.slice(122, 158)), 'UTF-16LE').replace(/\s+/g, '');
Info["organization"] = iconv.decode(Buffer.from(bytes.slice(158, 188)), 'UTF-16LE').replace(/\s+/g, '');
Info["validFrom"] = formatDate(iconv.decode(Buffer.from(bytes.slice(188, 204)), 'UTF-16LE').replace(/\s+/g, ''));
Info["expiryDate"] = formatDate(iconv.decode(Buffer.from(bytes.slice(204, 220)), 'UTF-16LE').replace(/\s+/g, ''));
andoridModule.mathAdd({
photoByte: hex.slice(512, 2560)
}, res => {
Info["image"] = `data:image/jpeg;base64,${res}`;
try {
page.$vm.pushInfo(Info);
} catch (e) {
console.log(e)
//TODO handle the exception
}
});
},
}
三、页面使用
<template>
<view>
<button @click="idCardShow">读取身份证信息</button>
<view>{{info.name}}</view>
<view>{{info.sex}}</view>
<view>{{info.nation}}</view>
<view>{{info.beborn}}</view>
<view>{{info.address}}</view>
<view>{{info.id}}</view>
<view>{{info.organization}}</view>
<view>{{info.validFrom}}-{{info.expiryDate}}</view>
<image style="width: 100px;height: 150px;" :src="info.image" mode="widthFix"></image>
</view>
</template>
<script>
import idCard from './idCard'
export default {
data() {
return {
info: {
image: ''
}
}
},
onLoad() {
idCard.idCardInIt();
setInterval(()=>idCard.sendHexData1(),2000)
},
methods: {
idCardShow() {
// idCard.sendHexData1()
},
pushInfo(info) {
this.info = info;
console.log(info)
}
}
}
</script>
<style>
button {
margin-bottom: 10px;
}
</style>