| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- /* eslint-disable no-inner-declarations */
- process.on('message', async (message, setHandle) => {
- try {
- const [dllPath, port] = require('path').join(message).split('|')
- process.send({ rescode: 0, msg: [dllPath, port] })
- const ffi = require('ffi')
- const ref = require('ref')
- const Struct = require('ref-struct')
- const RefArray = require('ref-array')
- const bufferTrim = require('buffertrim')
- const rescode = {
- 65536: 'success',
- 65537: 'fail',
- 66306: 'timeout',
- 66305: 'cancel'
- }
- const Sodo_RequestCardAndQrcode = Struct({
- transType: 'char',
- transDate: RefArray(ref.types.char, 3),
- transTime: RefArray(ref.types.char, 3),
- transAmt: 'int',
- transNo: RefArray(ref.types.char, 4),
- transOutBuf: RefArray(ref.types.char, 4096),
- lenTransOutbuf: 'int'
- })
- const CardInfo = Struct({
- recvBuf: RefArray(ref.types.char, 4096),
- lenRecv: 'int'
- })
- const SfzInfo = Struct({
- cmdOp1: ref.types.byte,
- cmdOp2: ref.types.byte,
- dataSend: RefArray(ref.types.char, 1024),
- lendataSend: 'int',
- recvBuf: RefArray(ref.types.byte, 4096),
- lenRecv: 'int'
- })
- let program = ffi.Library(dllPath, {
- Sodo_InitSerialPort: ['void', ['int', 'int']],
- // Sodo_InitHttps: ["void", ["int"]],
- Sodo_Start: ['int', []],
- Sodo_Stop: ['int', []],
- // Sodo_Stop: ["int", []],
- Sodo_SB_Process: ['int', [ref.refType(CardInfo)]],
- Sodo_SB_Psam_Process_GetAllInfo: ['int', ['int*', 'int*', 'int']],
- '_Sodo_Sfz_Process@4': ['int', [ref.refType(SfzInfo)]],
- '_Sodo_RequestCardAndQrcode@4': [
- 'int',
- [ref.refType(Sodo_RequestCardAndQrcode)]
- ]
- })
- function search () {
- try {
- const cardAndQrcode = new Sodo_RequestCardAndQrcode()
- cardAndQrcode.transType = 0x60
- cardAndQrcode.transDate = [0x20, 0x12, 0x12]
- cardAndQrcode.transNo = [0x11, 0x22, 0x33, 0x44]
- cardAndQrcode.transAmt = 1
- const ret = program['_Sodo_RequestCardAndQrcode@4'](cardAndQrcode.ref())
- if (rescode[ret] === 'timeout' || rescode[ret] === 'cancel') {
- process.send({ rescode: 0, msg: '连接超时或设备出错' })
- exit()
- return
- }
- if (rescode[ret] === 'success') {
- process.send({ rescode: 0, ret, message: '查询成功' })
- const transOutBuf = bufferTrim
- .trimEnd(Buffer.from(cardAndQrcode.transOutBuf))
- .toString()
- process.send({ rescode: 2, ret, transOutBuf })
- const res = isJSON(transOutBuf) ? JSON.parse(transOutBuf) : {}
- console.log('寻卡结果', res)
- process.send({ rescode: 2, msg: '寻卡结果', data: res })
- let id
- switch (res.cardType) {
- case '1': // 社保卡
- id = getSBCard()
- break
- case '2': // 身份证
- id = getSFZCard()
- break
- case '187': // 扫码
- id = getQRcode(res)
- break
- }
- console.log('id', id)
- }
- setTimeout(() => {
- search()
- }, 500)
- } catch (e) {
- process.send(e)
- }
- }
- function getSBCard () {
- // console.log("sb");
- const cardInfo = new CardInfo()
- const ret0 = program.Sodo_SB_Process(cardInfo.ref())
- console.log('[ ret0 ]', ret0)
- console.log('cardInfo', cardInfo, Buffer.from(cardInfo.recvBuf).toString())
- const res = Buffer.alloc(512)
- const inp = Buffer.alloc(512)
- const ret = program.Sodo_SB_Psam_Process_GetAllInfo(res.ref(), inp.ref(), 4)
- if (rescode[ret] !== 'success') return
- const data = bufferTrim
- .trimEnd(Buffer.from(res))
- .toString()
- .trim()
- .split('|')
- // 返回:卡片发行机构代码|社保卡卡号|卡片识别码|卡复位的信息|卡片版本|发行日期|有效日期
- const params = {
- qrcode_info: data[2], // 必填,社保卡使用卡识别码,电子社保卡使用二维码原始字符串, (应该扫码或者读卡机自动获取)
- card_type: '01', // 社保卡01 , 二维码04
- card_number: data[1], // 9位社保卡号(当介质类型为社保卡时必填)
- card_version: data[4], // 卡规范版本
- publish_date: data[5], // 发卡日期
- expiry_date: data[6], // 卡有效期
- card_rest_info: data[3] // 卡复位信息
- }
- console.log('[ params ]', params)
- process.send({
- rescode: 1,
- msg: '社保卡',
- data: params,
- cardInfo: bufferTrim.trimEnd(Buffer.from(cardInfo.recvBuf)).toString()
- })
- return params
- }
- function getSFZCard () {
- const cardInfo = new SfzInfo()
- cardInfo.cmdOp1 = 0x03
- cardInfo.cmdOp2 = 0x00
- const ret = program['_Sodo_Sfz_Process@4'](cardInfo.ref())
- console.log('ret', ret)
- const idStr = Buffer.from(cardInfo.recvBuf)
- .slice(7, 263)
- .toString('ucs2')
- if (
- !idStr
- .slice(61, 79)
- .trim()
- .replace(/\0/g, '').length
- ) { return }
- // if (!bufferTrim.trim()) return;
- console.log('%c [ idStr ]-109', idStr)
- const res = {
- name: idStr.slice(0, 15).trim(),
- sex: getSex(idStr.slice(15, 16)),
- nation: getNation(idStr.slice(16, 18)),
- idNum: idStr.slice(61, 79).trim(),
- address: idStr.slice(26, 61).trim(),
- begin: idStr.slice(94, 102).trim(),
- end: idStr.slice(102, 110).trim()
- }
- process.send({ rescode: 1, msg: '身份证', res })
- console.log('%c [ res ]-112', res)
- }
- function getQRcode (res) {
- const qrcode = Buffer.from(res.ID, 'base64').toString()
- const params = {
- qrcode_info: qrcode,
- card_type: '04'
- }
- console.log('params', params)
- process.send({ rescode: 1, msg: '扫码', data: params })
- return params
- }
- function isJSON (str) {
- try {
- JSON.parse(str)
- } catch (e) {
- return false
- }
- return true
- }
- function getSex (code) {
- switch (parseInt(code)) {
- case 0:
- return '未知的性别'
- case 1:
- return '男'
- case 2:
- return '女'
- case 9:
- return '未说明的性别'
- }
- return '未定义的性别'
- }
- function getNation (code) {
- switch (parseInt(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 '基诺'
- }
- }
- function exit () {
- process.kill(process.pid)
- process.exit(0)
- }
- return new Promise((resolve, reject) => {
- program.Sodo_InitSerialPort(parseInt(port), 115200)
- console.log('已执行初始化串口', port)
- const ret = program.Sodo_Start()
- if (rescode[ret] !== 'success') {
- console.log('打开串口失败')
- process.send({ rescode: 0, msg: '打开串口失败' })
- exit()
- } else {
- process.send({ rescode: 0, ret })
- try {
- search()
- } catch (e) {
- process.send(e)
- }
- }
- })
- } catch (e) {
- process.send({ rescode: 0, e })
- }
- })
|