UNPKG

@waiting/idcard-reader-bp8903

Version:
111 lines (103 loc) 3.85 kB
import { composite, formatBaseData, initialDataBase, initialIDData, parseCompositeOpts, parseDeviceOpts, testWrite, validateDllFile, } from '@waiting/idcard-reader-base' import { info } from '@waiting/log' import { fileExists, isFileExists, join, } from '@waiting/shared-core' import * as ffi from 'ffi' import { of, } from 'rxjs' import { catchError, delay, map, mergeMap, retry, tap, timeout, } from 'rxjs/operators' import { dllFuncs, } from './config' import { disconnectDevice, findDeviceList, readAll } from './device' export async function init(options) { const deviceOpts = parseDeviceOpts(options) const compositeOpts = parseCompositeOpts(options) // 先清空 解决头像图片生成可能失败问题 // compositeOpts.fontHwxhei = '' // compositeOpts.fontOcrb = '' // compositeOpts.fontSimhei = '' const { debug } = deviceOpts if (debug) { info(compositeOpts) info(deviceOpts) } await validateDllFile(deviceOpts.dllTxt) // 允许 未指定照片解码dll if (deviceOpts.dllImage && compositeOpts.useComposite && !await isFileExists(deviceOpts.dllImage)) { throw new Error('File not exists: ' + deviceOpts.dllImage) } await testWrite(deviceOpts.imgSaveDir) const apib = ffi.Library(deviceOpts.dllTxt, dllFuncs) const devices = findDeviceList(deviceOpts, compositeOpts, apib) if (devices && devices.length) { return devices } else { throw new Error('未找到读卡设备') } } /** Read card data */ export function read(device) { if (device.openPort) { try { disconnectDevice(device) } catch (ex) { throw ex } const text$ = of(readAll(device)).pipe(timeout(2000)) const iddata$ = text$.pipe(retry(device.deviceOpts.findCardRetryTimes), map(text => { const base = pickFields(text) const imagePath = device.compositeOpts.useComposite ? genAvatarPath(device.deviceOpts.imgSaveDir, base.idc) : '' const ret = Object.assign({}, initialIDData, { base, imagePath }) return ret })) const ret$ = iddata$.pipe(delay(device.compositeOpts.useComposite ? 300 : 0), tap(() => { disconnectDevice(device) }), mergeMap(data => { return fileExists(data.imagePath).pipe(map(path => { data.imagePath = path return data })) }), mergeMap(data => { return !device.compositeOpts.useComposite || !data.imagePath ? of(data) : composite(data.imagePath, data.base, device.compositeOpts).pipe(map(imgPath => { data.compositePath = imgPath return data })) }), timeout(20000), catchError((err) => { disconnectDevice(device) throw err })) return ret$.toPromise() } else { throw new Error('设备端口未指定') } } /** Pick fields from origin text */ function pickFields(text) { const base = Object.assign({}, initialDataBase) if (!text || !text.length) { return base } /** 姓名|身份证号|性别|民族|出生年月|住址|签发机关|起始日期|截至日期 */ const arr = text.split('|') if (arr.length === 9) { base.name = arr[0].trim() base.idc = arr[1] base.genderName = arr[2] base.nationName = arr[3] base.birth = arr[4] base.address = arr[5].trim() base.regorg = arr[6].trim() base.startdate = arr[7] base.enddate = arr[8] } return formatBaseData(base) } export function genAvatarPath(imgSaveDir, idc) { const path = join(imgSaveDir, `${idc}.bmp`) return path }