UNPKG

@luoxiao123/bankcard-reader-start

Version:
187 lines (165 loc) 5.35 kB
/** * @luoxiao123/bankcard-reader-start * 实达三合一读卡器 读银行卡 * * @version 0.0.6 * @author luoxiao * @license MIT * @link https://github.com/luoxiao-xy/node-bankcard-reader-start#readme */ import { DTypes } from 'win32-def'; import { parseDeviceOpts } from '@waiting/bankcard-reader-base'; export { initialOpts } from '@waiting/bankcard-reader-base'; import { info } from '@waiting/log'; import { validateDllFile, setPathDirectory } from '@waiting/shared-core'; import { Library } from 'ffi'; const config = { appDir: '', }; const dllFuncs = { star_InitConnect: [DTypes.INT, [DTypes.INT, DTypes.INT, DTypes.CHAR, DTypes.CHAR, DTypes.INT]], star_Open: [DTypes.INT, [DTypes.INT, DTypes.INT, DTypes.CHAR]], star_Close: [DTypes.INT, []], star_GetDevInfo: [DTypes.INT, [DTypes.PSTR, DTypes.LPINT]], star_ICGetInfo: [DTypes.INT, [DTypes.INT, DTypes.PSTR, DTypes.PSTR, DTypes.INT]], star_ReadMagCardNo: [DTypes.INT, [DTypes.INT, DTypes.INT, DTypes.PSTR, DTypes.LPINT, DTypes.INT]], }; function connectDevice(device) { if (device && device.inUse) { device.deviceOpts.debug && info('Cautiton: connectDevice() device in use'); return false } const openRet = device.apib.star_Open(0, 9600, '0'); device.deviceOpts.debug && info(`open com ret: ${openRet}`); return openRet === 0 ? true : false } function disconnectDevice(device) { const closeRet = device.apib.star_Close(); device.deviceOpts.debug && info(`disconnectDevice at port: ${device.openPort}, ret: ${closeRet} `); device.inUse = false; return closeRet === 0 ? true : false } /** 检查端口是否已打开 */ function isDevicePortOpen(device) { const szDevInfo = Buffer.alloc(64); const iInfoLen = Buffer.alloc(64); const ret = device.apib.star_GetDevInfo(szDevInfo, iInfoLen); // 使用获取设备信息接口来检查是否连接成功 device.deviceOpts.debug && info(`isPortOpen: ${ret}`); info(`设备信息: ${szDevInfo}`); info(`设备信息长度: ${iInfoLen}`); return ret === 0 ? true : false } function findDeviceList(deviceOpts, apib) { const arr = []; info('开始获取实达设备列表'); const device = findDevice(deviceOpts, apib); arr.push(device); return arr } function findDevice(deviceOpts, apib) { const device = { apib, deviceOpts, inUse: false, openPort: 0, }; const openRet = connectDevice(device); if (openRet && !isDevicePortOpen(device)) { device.inUse = true; device.openPort = 0; deviceOpts.debug && info(`Found device at serial/usb port: ${0}`); disconnectDevice(device); } return device } /** 读取银行卡 磁条卡 */ function readMC(device) { const szCardNo = Buffer.alloc(64); const iCardNoLen = Buffer.alloc(64); if (device.deviceOpts.debug) { info('starting reading 磁条卡 ...'); } const code = device.apib.star_ReadMagCardNo(23, 0, szCardNo, iCardNoLen, 5); let cardno = ''; if (code === 0) { // 卡号可能重复数字 ...1234557\u0000557 cardno = parseBuffer(szCardNo); } if (device.deviceOpts.debug) { info(`readDataBase code: ${code}`); info(`readDataBase bufLen: ${szCardNo.byteLength}`); info('readDataBase buf: '); info(szCardNo); info(`readDataBase cardno: ${cardno}`); } return cardno } /** 读取银行卡 支持 接触、非接触 IC卡 */ function readIC(device) { const buf = Buffer.alloc(64); if (device.deviceOpts.debug) { info('starting reading IC卡 ...'); } const code = device.apib.star_ICGetInfo(2, Buffer.from('124|A'), buf, 1); let cardno = ''; if (code === 0) { // 卡号可能重复数字 ...1234557\u0000557 const bufstr = parseBuffer(buf); cardno = bufstr ? bufstr.substring(4) : ''; } if (device.deviceOpts.debug) { info(`readDataBase code: ${code}`); info(`readDataBase bufLen: ${buf.byteLength}`); info('readDataBase buf: '); info(buf); info(`readDataBase cardno: ${cardno}`); } return cardno } /** 转换Buffer */ function parseBuffer(buf) { const bufstr = buf.toString('utf8').trim().replace(/\0+$/g, ''); return bufstr } async function init(options) { const deviceOpts = parseDeviceOpts(options); const { debug } = deviceOpts; info('开始实达设备'); if (debug) { info(deviceOpts); } await validateDllFile(deviceOpts.dllTxt); if (deviceOpts.dllSearchPath) { setPathDirectory(deviceOpts.dllSearchPath); } const apib = Library(deviceOpts.dllTxt, dllFuncs); const devices = findDeviceList(deviceOpts, apib); if (devices && devices.length) { return devices } else { throw new Error('未找到读卡设备') } } /** Read card data */ function read(device) { const ret = { cardno: '', }; try { ret.cardno = readIC(device) || readMC(device) || ''; } catch (err) { ret.cardno = ''; } try { disconnectDevice(device); } catch (ex) { throw ex } return Promise.resolve(ret) } // base directory of this module config.appDir = __dirname + '/..'; export { init, read };