ssts-hospital-web-master项目实战记录三十:项目迁移-核心模块实现(RealDeviceDriver)
记录时间:2024-03-16
一、RealDeviceDriver模块实现
service/device-driver/log-device-info.ts
import {
LogTerminalInfoDir,
ConfigLogDBDeviceFunction,
ConfigLogDBDeviceEvent
} from '@/config'
import {
LogCustomInfo,
LogTerminalDeviceFunctionData,
LogTerminalDeviceEventData,
LogTerminalDeviceStatusInfo
} from '@/common'
import { useSystemStore } from '@/store'
// 记录LogDeviceInfo日志
const LogDeviceInfo = function (deviceName: string, info: string) {
return LogCustomInfo(
LogTerminalInfoDir,
'LogTerminalInfo',
info,
deviceName,
null
)
}
// 记录设备函数日志
const LogDeviceFunctionInfo = function (
deviceName: string,
functionName: string,
params: Array<string>,
ret: any,
outMsg: string
) {
const info = `${deviceName}.${functionName}->params=[${params}],ret=[${ret}],OutMsg=[${outMsg}]`
const log = LogCustomInfo(
LogTerminalInfoDir,
'LogTerminalInfo',
info,
deviceName,
null
)
const config = ConfigLogDBDeviceFunction
if (config != undefined && config[deviceName] != undefined) {
const deviceConfig = config[deviceName]
if (
deviceConfig[functionName] != undefined &&
deviceConfig[functionName] != undefined &&
deviceConfig[functionName]['flag'] == '1'
) {
const systemStore = useSystemStore()
const dict = systemStore.dict
const terminalIp = dict.terminalIp
// 业务流水号未定义时,业务流水号=终端Ip
const businessTrace = dict.businessTrace ? dict.businessTrace : terminalIp
const devPageName = window.location.href
LogTerminalDeviceFunctionData(
terminalIp,
businessTrace,
devPageName,
deviceName,
functionName,
params.toString(),
ret,
outMsg
)
}
}
return log
}
// 记录设备事件日志
const LogDeviceEventInfo = function (
EventName: string,
param: string,
eventId: string,
resendMsg: string,
devPageName: string
) {
const info = `${resendMsg}EventId=${eventId},DeviceTarget=${devPageName},${EventName}->[${param}]`
LogCustomInfo(LogTerminalInfoDir, 'LogTerminalInfo', info, null, 'EVT')
let deviceName = null
let devEventName = null
if (EventName.indexOf('_') > -1) {
deviceName = EventName.split('_')[0]
devEventName = EventName.split('_')[1]
} else {
deviceName = 'Device'
devEventName = EventName
}
const config = ConfigLogDBDeviceEvent
if (config[deviceName] != undefined) {
const deviceConfig = config[deviceName]
if (
deviceConfig[devEventName] != undefined &&
deviceConfig[devEventName]['flag'] == '1'
) {
const systemStore = useSystemStore()
const dict = systemStore.dict
const terminalIp = dict.terminalIp
//业务流水号未定义时,业务流水号=终端Ip
const businessTrace = dict.businessTrace ? dict.businessTrace : terminalIp
if (resendMsg != '') {
devEventName = resendMsg
}
const devEventParam = param
if (typeof LogTerminalDeviceEventData != 'undefined') {
LogTerminalDeviceEventData(
terminalIp,
businessTrace,
devPageName,
deviceName,
devEventName,
devEventParam
)
}
}
}
}
//记录设备状态更新日志
const LogDeviceStatusInfo = function (deviceName: string, status: string) {
const info = `${deviceName}->status=[${status}]`
LogCustomInfo(LogTerminalInfoDir, 'LogTerminalInfo', info, deviceName, null)
const systemStore = useSystemStore()
const dict = systemStore.dict
const currentStatus =
dict.deviceStatusList[dict.deviceNameList.indexOf(deviceName)]
LogTerminalDeviceStatusInfo(deviceName, status, currentStatus)
}
export {
LogDeviceInfo,
LogDeviceFunctionInfo,
LogDeviceEventInfo,
LogDeviceStatusInfo
}
service/device-driver/ezware/ez-web-socket.ts
import { hydate } from '@/common'
// 定义获取guid的函数
const GetGuid = function () {
let guid = ''
for (let i = 1; i <= 32; i++) {
const n = Math.floor(Math.random() * 16.0).toString(16)
guid += n
if (i == 8 || i == 12 || i == 16 || i == 20) guid += '-'
}
return guid
}
// 定义消息类型枚举
enum EZMessageType {
init = 1,
method,
signal,
propertyUpdate,
propertySet,
response
}
// 定义连接状态枚举
enum ConnectionStatus {
idle = 0,
ready,
err,
closed
}
// 定义flag对象的类型
interface Flag {
socketReady?: ConnectionStatus // 内部属性,不能通过getter和setter访问
status: ConnectionStatus // 公开属性,可以通过getter和setter访问
idleCall?: () => void // 回调函数类型
errCall?: () => void
readyCall?: () => void
closedCall?: () => void
}
// 定义请求包装对象
interface RequestWrapper {
resolve: (value: any) => void
reject: (reason: any) => void
data: any
}
// 重连延迟时间,比如3000毫秒
const RECONNECT_DELAY = 3000
// 初始化flag对象
const flag: Flag = {
status: ConnectionStatus.idle
}
// 创建回调映射
const callbackMap: { [key in ConnectionStatus]: keyof Flag | undefined } = {
[ConnectionStatus.idle]: 'idleCall',
[ConnectionStatus.err]: 'errCall',
[ConnectionStatus.ready]: 'readyCall',
[ConnectionStatus.closed]: 'closedCall'
}
// 使用Object.defineProperty为flag对象添加getter和setter
Object.defineProperty(flag, 'socketReady', {
set(val: ConnectionStatus) {
console.log(`set flag.socketReady ${val}`)
this.status = val // 更新status属性的值
const callbackName = callbackMap[val]
if (callbackName && typeof this[callbackName] === 'function') {
this[callbackName]() // 调用相应的回调函数
}
}
})
// OnSocketReady
function OnSocketReady(func: () => void): void {
console.log('flag.status ' + flag.status)
if (flag.status === ConnectionStatus.ready) {
console.log('call func in socket ready')
func()
} else {
console.log('socket not ready')
// 等待WebSocket准备好
new Promise<void>((resolve) => {
// 当WebSocket准备好时,调用resolve
if (flag.readyCall) {
flag.readyCall()
} else {
flag.readyCall = resolve
}
}).then(() => {
console.log('WebSocket is now ready, calling func')
func()
})
}
}
// OnSocketError
const OnSocketError = function (func: () => void): void {
console.log('flag.status ' + flag.status)
if (
flag.status === ConnectionStatus.err ||
flag.status === ConnectionStatus.closed
) {
console.log('call func in socket err')
func()
} else {
console.log('socket still on')
// 等待WebSocket出错或关闭
new Promise<void>((resolve) => {
if (flag.errCall) {
// 如果已经有回调,直接调用
flag.errCall()
} else {
// 否则,设置回调
flag.errCall = resolve
}
}).then(() => {
console.log('WebSocket is now in error state, calling func')
func()
})
}
}
class EZWebSocket {
private promisePool: {
[token: string]: RequestWrapper
} = {}
public initPool: { [key: string]: any }
public wsclient: WebSocket
constructor(wsUrl: string) {
this.promisePool = {}
this.initPool = {}
this.wsclient = new WebSocket(wsUrl)
this.setupWebSocketListeners()
}
private setupWebSocketListeners() {
this.wsclient.onopen = (e) => {
console.log('open ws connection succeed. ', e)
flag.socketReady = ConnectionStatus.ready
}
this.wsclient.onerror = (e) => {
console.error('ws connection error! ', e)
flag.socketReady = ConnectionStatus.err
this.handleWebSocketError(e) // 添加额外的错误处理逻辑
}
this.wsclient.onclose = (e) => {
console.log('ws connection closed. ', e)
this.handleWebSocketClose(e) // 添加额外的关闭处理逻辑,如尝试重连等
}
this.wsclient.onmessage = (e) => {
try {
const data = JSON.parse(e.data)
this.handleMessage(data)
} catch (error) {
console.error('Error parsing WebSocket message:', error)
}
}
}
private handleMessage(data: any) {
switch (data.type) {
case EZMessageType.init:
this.handleInit(data)
break
case EZMessageType.response:
this.handleResponse(data)
break
case EZMessageType.signal:
this.handleSignal(data)
break
case EZMessageType.propertyUpdate:
this.handlePropertyUpdate(data)
break
default:
console.log('Received unknown message type:', JSON.stringify(data))
break
}
}
private handleWebSocketError(event: Event) {
console.error('WebSocket error occurred:', event)
}
private handleWebSocketClose(event: CloseEvent) {
console.log('WebSocket connection closed:', event)
// 清理promisePool
for (const token of Object.keys(this.promisePool)) {
delete this.promisePool[token]
}
// 尝试重新连接WebSocket
setTimeout(() => {
this.reconnectWebSocket()
}, RECONNECT_DELAY)
}
private reconnectWebSocket() {
if (this.wsclient.readyState === WebSocket.CLOSED) {
console.log(
hydate(new Date()).format('HH:mm:ss.SSS') +
' Attempting to reconnect WebSocket...'
)
this.wsclient = new WebSocket(this.wsclient.url)
this.setupWebSocketListeners() // 重新设置事件监听器
}
}
private handleInit(obj: {
Device: string
Methods?: any[]
Signals?: any[]
Properties?: any[]
}): void {
const dev = obj.Device
if (typeof dev === 'string') {
const req = this.initPool[dev]
if (req !== undefined) {
req.send = this.send.bind(this)
const methods = obj.Methods
if (Array.isArray(methods)) {
for (const method of methods) {
if (typeof method.Name === 'string') {
req[method.Name] = (args: any) => {
const para = {
Device: dev,
token: GetGuid(),
Method: method.Name,
Params: args
}
console.log('invokeMethod:', JSON.stringify(para))
return this.send(para)
}
}
}
}
}
}
}
private handleResponse(obj: { token: string; Return: any }): void {
const token = obj.token
if (typeof token === 'string') {
const req = this.promisePool[token]
if (req !== undefined) {
if (req.resolve) req.resolve(obj.Return)
delete this.promisePool[token]
}
}
}
private handleSignal(obj: {
LogicalName: string
Method: string
Params?: any
}): void {
console.log('signal:', JSON.stringify(obj))
if (
this.initPool[obj.LogicalName] &&
typeof this.initPool[obj.LogicalName][obj.Method] === 'function'
) {
this.initPool[obj.LogicalName][obj.Method](obj.Params)
}
}
private handlePropertyUpdate(obj: {
LogicalName: string
Property: string
Value: any
}): void {
console.log('property:', JSON.stringify(obj))
if (this.initPool[obj.LogicalName]) {
this.initPool[obj.LogicalName][obj.Property] = obj.Value
}
}
public close() {
this.wsclient.close()
console.log('wsclient close')
}
public send(data: any): Promise<any> {
data.token = GetGuid()
return new Promise((resolve, reject) => {
this.promisePool[data.token] = { data, resolve, reject }
this.wsclient.send(JSON.stringify(data))
console.log('wsclient send : ' + JSON.stringify(data))
})
}
}
export { OnSocketReady, OnSocketError, EZMessageType, EZWebSocket }
service/device-driver/ezware/real-device-driver.ts
import { BillValidatorStatusConfig, StatusMapConfig } from '@/config'
import { RealDeviceDriverType, DeviceType, NamedStatusMap } from '@/types'
import { Xor, StringToAscii } from '@/common'
import {
LogDeviceInfo,
LogDeviceStatusInfo,
LogDeviceFunctionInfo
} from '../log-device-info'
import { useEZWare } from './function-ws'
import { DeviceDriver as dd } from '../device-driver'
const RealDeviceDriver: RealDeviceDriverType = {
EventFunction: function (EventName, param) {
// console.log('RealDeviceDriver:EventFunction', EventName, param)
dd.EventFunction(EventName, param)
},
EventResult: function (EventName, param) {
// console.log('RealDeviceDriver:EventResult', EventName, param)
dd.EventResult(EventName, param)
},
FnCall: async function (
device: DeviceType,
fnName: string,
params: Array<string>
) {
const deviceId = device.id
const deviceName = device.name
if (!deviceId || !deviceName || !fnName) {
console.log('FnCall failed! ', device, fnName, params)
return
}
// 连接设备前设置参数
if (fnName == 'OpenConnection') {
await driver[deviceId].setParams(deviceName, params[0])
}
// 调用方法
const result = await driver[deviceId][fnName](...params)
await LogDeviceFunctionInfo(
deviceName,
fnName,
params,
result, // JSON.stringify(result),
''
)
if (fnName == 'GetStatus' || fnName == 'GetCardUnit') {
const statusResult = await this.handleStatusResult(device, fnName, result)
// 事件回调状态
const EventName = `${deviceName}_${fnName}`
this.EventResult(EventName, statusResult)
} else {
// 事件回调结果
const EventName = `${deviceName}_${fnName}`
this.EventResult(EventName, result)
}
return result
},
handleStatusResult: async function (device, fnName, result) {
let statusResult = {}
try {
const deviceType = device.type
const deviceId = device.id
const deviceName = device.name
if (deviceId && deviceName && fnName == 'GetStatus') {
if (
['CRD', 'IDC', 'PTR', 'BCR', 'SIU', 'PIN'].includes(deviceType) &&
result
) {
const jsonData = JSON.parse(result)
this[deviceId].status = this.changeStStatus(
deviceName,
StatusMapConfig.StDeviceStatusMap,
jsonData.Device
)
LogDeviceStatusInfo(deviceName, this[deviceId].status)
if (['CRD', 'IDC', 'PTR'].includes(deviceType)) {
if (jsonData.Media) {
const mediaKey = jsonData.Media == '' ? 'EMPTY' : jsonData.Media
this[deviceId].media = this.changeStStatus(
deviceName,
StatusMapConfig.StMediaStatusMap,
`${deviceType}_${mediaKey}`
)
}
}
if (deviceType == 'CRD') {
if (jsonData.Dispenser) {
this[deviceId].dispenser = this.changeStStatus(
deviceName,
StatusMapConfig.StDispenserStatusMap,
jsonData.Dispenser
)
}
}
if (deviceType === 'PTR') {
if (jsonData.PaperSupplyDetails) {
const paperNameList = [
'UpperSupply',
'LowerSupply',
'ExternalSupply',
'AuxiliarySupply'
]
const statusArray = new Array(paperNameList.length).fill('')
paperNameList.forEach((paperName, index) => {
statusArray[index] = this.changeStStatus(
deviceName,
StatusMapConfig.StPaperStatusMap,
jsonData.PaperSupplyDetails[paperName]
)
})
this[deviceId].papers = statusArray.join(',')
LogDeviceStatusInfo(`${deviceName}Papers`, this[deviceId].papers)
}
}
dd[deviceId].status = this[deviceId].status
if (this[deviceId].media) {
dd[deviceId].media = this[deviceId].media
}
if (this[deviceId].dispenser) {
dd[deviceId].dispenser = this[deviceId].dispenser
}
if (this[deviceId].papers) {
dd[deviceId].papers = this[deviceId].papers
}
} else if (['BV'].includes(deviceType) && result) {
try {
dd[deviceId].statusCode =
typeof result === 'string' ? result : result.toString() // 确保 result 是字符串
dd[deviceId].status = this.changeStStatus(
deviceName,
StatusMapConfig.StBillValidatorStatusMap,
dd[deviceId].statusCode
)
LogDeviceStatusInfo(deviceName, this[deviceId].status)
} catch (error) {
console.error('Error setting status for bill validator:', error)
}
}
statusResult = {
status: dd[deviceId].status,
media: dd[deviceId].media,
dispenser: dd[deviceId].dispenser,
papers: dd[deviceId].papers
}
} else if (deviceId && deviceName && fnName == 'GetCardUnit') {
if (['CRD'].includes(deviceType) && result) {
const jsonData = JSON.parse(result)
if (Array.isArray(jsonData) && jsonData.length > 0) {
const statusArray = new Array(jsonData.length).fill('')
for (const i in jsonData) {
const cardUnitStatus = this.changeStStatus(
deviceName,
StatusMapConfig.StCardUnitStatusMap,
jsonData[i].Status
)
statusArray[i] = cardUnitStatus
}
this[deviceId].cardUnit = statusArray.join(',')
LogDeviceStatusInfo(
`${deviceName}CardUnit`,
this[deviceId].cardUnit
)
}
dd[deviceId].cardUnit = this[deviceId].cardUnit
}
statusResult = {
cardUnit: dd[deviceId].cardUnit
}
}
} catch (e) {
console.log('handleStatusResult', e)
}
return statusResult
},
changeStStatus: function (
deviceName,
namedStatusMap: NamedStatusMap,
statusKey
) {
// 获取状态
const status = namedStatusMap.value[statusKey] || ''
// 格式化信息
const info = `${namedStatusMap.name}:${statusKey}->${status}`
// 记录日志信息
LogDeviceInfo(deviceName, info)
return status
},
changeStCardUnit: function (deviceName, Type, StCardUnitStatus) {
// 获取状态
let status = StatusMapConfig.StCardUnitStatusMap[StCardUnitStatus] || ''
// 根据特定条件调整状态
if (StCardUnitStatus === 'FULL') {
status = Type === 'SUPPLY' ? '0' : '1'
} else if (StCardUnitStatus === 'EMPTY') {
status = Type === 'SUPPLY' ? '1' : '0'
} else if (StCardUnitStatus === 'UNKNOWN') {
status = '3'
}
// 格式化信息
const info = `changeStCardUnit:Type[${Type}],${StCardUnitStatus}->${status}`
// 记录日志信息
LogDeviceInfo(deviceName, info)
return status
},
m1: {
sectorNo: '',
sectorPwd: '',
blockNo: ''
},
cardDispenser: {
type: 'CRD',
id: 'cardDispenser',
name: 'CardDispenser',
status: '',
dispenser: '',
media: '',
cardUnit: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [action])
},
async getCardUnit() {
return await RealDeviceDriver.FnCall(this, 'GetCardUnit', [])
},
async setCardUnit(
number,
name,
type,
count,
initialCount,
resultainCount,
threshold
) {
const jsonData = {
number,
name,
type,
count,
initialCount,
resultainCount,
threshold
}
return await RealDeviceDriver.FnCall(this, 'SetCardUnit', [
JSON.stringify(jsonData)
])
},
async dispenseCard(num, present) {
return await RealDeviceDriver.FnCall(this, 'Dispense', [num, present])
},
async moveCard(pos) {
return await RealDeviceDriver.FnCall(this, 'MoveCard', [pos])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'Eject', [])
},
async retainCard(num) {
return await RealDeviceDriver.FnCall(this, 'Retain', [num])
}
},
cardDispenserReader: {
type: 'IDC',
id: 'cardDispenserReader',
name: 'CardDispenserReader',
status: '',
media: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'Reset', [action])
},
async resetCount() {
return await RealDeviceDriver.FnCall(this, 'ResetCount', [])
},
async readRawData(track, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadRawData', [
track,
timeout
])
},
async cancelReadRawData() {
return await RealDeviceDriver.FnCall(this, 'CancelReadRawData', [])
},
async writeRawData(track1, track2, track3, chip, cardPTR) {
return await RealDeviceDriver.FnCall(this, 'WriteRawData', [
track1,
track2,
track3,
chip,
cardPTR
])
},
async chipPower(type) {
return await RealDeviceDriver.FnCall(this, 'ChipPower', [type])
},
async chipIO(protocol, data) {
return await RealDeviceDriver.FnCall(this, 'ChipIO', [protocol, data])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'EjectCard', [])
},
async retainCard() {
return await RealDeviceDriver.FnCall(this, 'RetainCard', [])
},
readM1Card: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard1: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard2: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readTrack2FromChip: function (): Promise<string> {
throw new Error('Function not implemented.')
},
readICDataFromChip: function (
tellerNoAsii: string,
tradeType: string,
amt: string
): Promise<string[]> {
console.log(tellerNoAsii, tradeType, amt)
throw new Error('Function not implemented.')
}
},
cardReader: {
type: 'IDC',
id: 'cardReader',
name: 'CardReader',
status: '',
media: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'Reset', [action])
},
async resetCount() {
return await RealDeviceDriver.FnCall(this, 'ResetCount', [])
},
async readRawData(track, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadRawData', [
track,
timeout
])
},
async cancelReadRawData() {
return await RealDeviceDriver.FnCall(this, 'CancelReadRawData', [])
},
async writeRawData(track1, track2, track3, chip, cardPTR) {
return await RealDeviceDriver.FnCall(this, 'WriteRawData', [
track1,
track2,
track3,
chip,
cardPTR
])
},
async chipPower(type) {
return await RealDeviceDriver.FnCall(this, 'ChipPower', [type])
},
async chipIO(protocol, data) {
return await RealDeviceDriver.FnCall(this, 'ChipIO', [protocol, data])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'EjectCard', [])
},
async retainCard() {
return await RealDeviceDriver.FnCall(this, 'RetainCard', [])
},
readM1Card: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard1: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard2: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readTrack2FromChip: function (): Promise<string> {
throw new Error('Function not implemented.')
},
readICDataFromChip: function (
tellerNoAsii: string,
tradeType: string,
amt: string
): Promise<string[]> {
console.log(tellerNoAsii, tradeType, amt)
throw new Error('Function not implemented.')
}
},
ssCardReader: {
type: 'IDC',
id: 'ssCardReader',
name: 'SSCardReader',
status: '',
media: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'Reset', [action])
},
async resetCount() {
return await RealDeviceDriver.FnCall(this, 'ResetCount', [])
},
async readRawData(track, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadRawData', [
track,
timeout
])
},
async cancelReadRawData() {
return await RealDeviceDriver.FnCall(this, 'CancelReadRawData', [])
},
async writeRawData(track1, track2, track3, chip, cardPTR) {
return await RealDeviceDriver.FnCall(this, 'WriteRawData', [
track1,
track2,
track3,
chip,
cardPTR
])
},
async chipPower(type) {
return await RealDeviceDriver.FnCall(this, 'ChipPower', [type])
},
async chipIO(protocol, data) {
return await RealDeviceDriver.FnCall(this, 'ChipIO', [protocol, data])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'EjectCard', [])
},
async retainCard() {
return await RealDeviceDriver.FnCall(this, 'RetainCard', [])
},
readM1Card: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard1: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard2: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readTrack2FromChip: function (): Promise<string> {
throw new Error('Function not implemented.')
},
readICDataFromChip: function (
tellerNoAsii: string,
tradeType: string,
amt: string
): Promise<string[]> {
console.log(tellerNoAsii, tradeType, amt)
throw new Error('Function not implemented.')
}
},
idCardReader: {
type: 'IDC',
id: 'idCardReader',
name: 'IDCardReader',
status: '',
media: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'Reset', [action])
},
async resetCount() {
return await RealDeviceDriver.FnCall(this, 'ResetCount', [])
},
async readRawData(track, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadRawData', [
track,
timeout
])
},
async cancelReadRawData() {
return await RealDeviceDriver.FnCall(this, 'CancelReadRawData', [])
},
async writeRawData(track1, track2, track3, chip, cardPTR) {
return await RealDeviceDriver.FnCall(this, 'WriteRawData', [
track1,
track2,
track3,
chip,
cardPTR
])
},
async chipPower(type) {
return await RealDeviceDriver.FnCall(this, 'ChipPower', [type])
},
async chipIO(protocol, data) {
return await RealDeviceDriver.FnCall(this, 'ChipIO', [protocol, data])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'EjectCard', [])
},
async retainCard() {
return await RealDeviceDriver.FnCall(this, 'RetainCard', [])
},
readM1Card: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard1: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard2: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readTrack2FromChip: function (): Promise<string> {
throw new Error('Function not implemented.')
},
readICDataFromChip: function (
tellerNoAsii: string,
tradeType: string,
amt: string
): Promise<string[]> {
console.log(tellerNoAsii, tradeType, amt)
throw new Error('Function not implemented.')
}
},
icCardReader: {
type: 'IDC',
id: 'icCardReader',
name: 'ICCardReader',
status: '',
media: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'Reset', [action])
},
async resetCount() {
return await RealDeviceDriver.FnCall(this, 'ResetCount', [])
},
async readRawData(track, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadRawData', [
track,
timeout
])
},
async cancelReadRawData() {
return await RealDeviceDriver.FnCall(this, 'CancelReadRawData', [])
},
async writeRawData(track1, track2, track3, chip, cardPTR) {
return await RealDeviceDriver.FnCall(this, 'WriteRawData', [
track1,
track2,
track3,
chip,
cardPTR
])
},
async chipPower(type) {
return await RealDeviceDriver.FnCall(this, 'ChipPower', [type])
},
async chipIO(protocol, data) {
return await RealDeviceDriver.FnCall(this, 'ChipIO', [protocol, data])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'EjectCard', [])
},
async retainCard() {
return await RealDeviceDriver.FnCall(this, 'RetainCard', [])
},
readM1Card: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard1: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard2: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readTrack2FromChip: function (): Promise<string> {
throw new Error('Function not implemented.')
},
readICDataFromChip: function (
tellerNoAsii: string,
tradeType: string,
amt: string
): Promise<string[]> {
console.log(tellerNoAsii, tradeType, amt)
throw new Error('Function not implemented.')
}
},
swCardReader: {
type: 'IDC',
id: 'swCardReader',
name: 'SWCardReader',
status: '',
media: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(action) {
return await RealDeviceDriver.FnCall(this, 'Reset', [action])
},
async resetCount() {
return await RealDeviceDriver.FnCall(this, 'ResetCount', [])
},
async readRawData(track, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadRawData', [
track,
timeout
])
},
async cancelReadRawData() {
return await RealDeviceDriver.FnCall(this, 'CancelReadRawData', [])
},
async writeRawData(track1, track2, track3, chip, cardPTR) {
return await RealDeviceDriver.FnCall(this, 'WriteRawData', [
track1,
track2,
track3,
chip,
cardPTR
])
},
async chipPower(type) {
return await RealDeviceDriver.FnCall(this, 'ChipPower', [type])
},
async chipIO(protocol, data) {
return await RealDeviceDriver.FnCall(this, 'ChipIO', [protocol, data])
},
async ejectCard() {
return await RealDeviceDriver.FnCall(this, 'EjectCard', [])
},
async retainCard() {
return await RealDeviceDriver.FnCall(this, 'RetainCard', [])
},
readM1Card: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard1: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readSSCard2: function (): Promise<string[]> {
throw new Error('Function not implemented.')
},
readTrack2FromChip: function (): Promise<string> {
throw new Error('Function not implemented.')
},
readICDataFromChip: function (
tellerNoAsii: string,
tradeType: string,
amt: string
): Promise<string[]> {
console.log(tellerNoAsii, tradeType, amt)
throw new Error('Function not implemented.')
}
},
receiptPrinter: {
type: 'PTR',
id: 'receiptPrinter',
name: 'ReceiptPrinter',
status: '',
media: '',
papers: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(mediaControl, resultractBinNumber) {
const jsonData = { mediaControl, resultractBinNumber }
return await RealDeviceDriver.FnCall(this, 'GetStatus', [
JSON.stringify(jsonData)
])
},
async printForm(formName, fields, mediaName) {
const jsonData = { formName, fields, mediaName }
return await RealDeviceDriver.FnCall(this, 'GetStatus', [
JSON.stringify(jsonData)
])
},
async printRawData(rawdata) {
return await RealDeviceDriver.FnCall(this, 'PrintRawData', [rawdata])
},
async eject(cut) {
return await RealDeviceDriver.FnCall(this, 'Eject', [cut])
}
},
labelPrinter: {
type: 'PTR',
id: 'labelPrinter',
name: 'LabelPrinter',
status: '',
media: '',
papers: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(mediaControl, resultractBinNumber) {
const jsonData = { mediaControl, resultractBinNumber }
return await RealDeviceDriver.FnCall(this, 'GetStatus', [
JSON.stringify(jsonData)
])
},
async printForm(formName, fields, mediaName) {
const jsonData = { formName, fields, mediaName }
return await RealDeviceDriver.FnCall(this, 'GetStatus', [
JSON.stringify(jsonData)
])
},
async printRawData(rawdata) {
return await RealDeviceDriver.FnCall(this, 'PrintRawData', [rawdata])
},
async eject(cut) {
return await RealDeviceDriver.FnCall(this, 'Eject', [cut])
}
},
documentPrinter: {
type: 'PTR',
id: 'documentPrinter',
name: 'DocumentPrinter',
status: '',
media: '',
papers: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset(mediaControl, resultractBinNumber) {
const jsonData = { mediaControl, resultractBinNumber }
return await RealDeviceDriver.FnCall(this, 'GetStatus', [
JSON.stringify(jsonData)
])
},
async printForm(formName, fields, mediaName) {
const jsonData = { formName, fields, mediaName }
return await RealDeviceDriver.FnCall(this, 'GetStatus', [
JSON.stringify(jsonData)
])
},
async printRawData(rawdata) {
return await RealDeviceDriver.FnCall(this, 'PrintRawData', [rawdata])
},
async eject(cut) {
return await RealDeviceDriver.FnCall(this, 'Eject', [cut])
}
},
barcode: {
type: 'BCR',
id: 'barcode',
name: 'Barcode',
status: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset() {
return await RealDeviceDriver.FnCall(this, 'Reset', [])
},
async readBarcode(type, timeout) {
return await RealDeviceDriver.FnCall(this, 'ReadBarcode', [type, timeout])
},
async cancelReadBarcode() {
return await RealDeviceDriver.FnCall(this, 'CancelReadBarcode', [])
}
},
siu: {
type: 'SIU',
id: 'siu',
name: 'SIU',
status: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset() {
return await RealDeviceDriver.FnCall(this, 'Reset', [])
},
async enableEvent() {
return await RealDeviceDriver.FnCall(this, 'EnableEvent', [])
},
async disableEvent() {
return await RealDeviceDriver.FnCall(this, 'DisableEvent', [])
},
async setGuidLight(item, common) {
return await RealDeviceDriver.FnCall(this, 'SetGuidLight', [item, common])
},
async setAuxiliary(item, common) {
return await RealDeviceDriver.FnCall(this, 'SetAuxiliary', [item, common])
},
async setIndicator(item, common) {
return await RealDeviceDriver.FnCall(this, 'SetIndicator', [item, common])
},
async setDoor(item, common) {
return await RealDeviceDriver.FnCall(this, 'SetDoor', [item, common])
}
},
pinPad: {
type: 'PIN',
id: 'pinPad',
name: 'PinPad',
status: '',
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async reset() {
return await RealDeviceDriver.FnCall(this, 'Reset', [])
},
async loadMasterKey(KeyValue) {
const jsonData = {
KeyName: 'MasterKey',
KeyValue: KeyValue,
Use: 'KEYENCKEY'
}
return await RealDeviceDriver.FnCall(this, 'ImportKey', [
JSON.stringify(jsonData)
])
},
async loadPinKey(KeyValue) {
const jsonData = {
KeyName: 'PinKey',
KeyValue: KeyValue,
EncKeyName: 'MainKey',
Use: 'FUNCTION'
}
return await RealDeviceDriver.FnCall(this, 'ImportKey', [
JSON.stringify(jsonData)
])
},
async loadMacKey(KeyValue) {
const jsonData = {
KeyName: 'MacKey',
KeyValue: KeyValue,
EncKeyName: 'MainKey',
Use: 'CRYPT,MACING'
}
return await RealDeviceDriver.FnCall(this, 'ImportKey', [
JSON.stringify(jsonData)
])
},
async getPin(MinLength, MaxLength, AutoEnd) {
const jsonData = {
MinLen: MinLength, // 最小输入六位
MaxLen: MaxLength, // 最大输入六位
AutoEnd: AutoEnd, // 达到最大输入位数后自动结束输入
ActiveKeys: 'NUMBERS,ENTER,CANCEL,CLEAR', // 激活数字键、确认键、取消键、清除键
TerminateKeys: 'ENTER,CANCEL' // 使用确认键、取消键来结束输入
}
return await RealDeviceDriver.FnCall(this, 'GetPin', [
JSON.stringify(jsonData)
])
},
async getPinBlock(Data) {
const jsonData = {
Format: 'ANSI',
CustomerData: Data,
PadChar: 0x00,
KeyName: 'PinKey'
}
return await RealDeviceDriver.FnCall(this, 'GetPinBlock', [
JSON.stringify(jsonData)
])
},
async cancelGetPin() {
return await RealDeviceDriver.FnCall(this, 'CancelGetPin', [])
},
async getData(MaxLength, AutoEnd) {
const jsonData = {
MaxKeys: MaxLength, // 最大输入六位
AutoEnd: AutoEnd, // 达到最大输入位数后自动结束输入
ActiveKeys: 'NUMBERS,ENTER,CANCEL,CLEAR', // 激活数字键、确认键、取消键、清除键
TerminateKeys: 'ENTER,CANCEL' // 使用确认键、取消键来结束输入
}
return await RealDeviceDriver.FnCall(this, 'GetData', [
JSON.stringify(jsonData)
])
},
async cancelGetData() {
return await RealDeviceDriver.FnCall(this, 'CancelGetData', [])
},
async getMac(Data) {
const nLen = 32
let mac = ''
// 原始需加密数据
let CodeStr = Data
// 不足nLen位补0
while (CodeStr.length % nLen !== 0) {
CodeStr += '0'
}
// 循环异或
const nCount = CodeStr.length / nLen
let xor_result = CodeStr.substring(0, nLen)
for (let i = 1; i < nCount; i++) {
const temp = CodeStr.substring(nLen * i, nLen * i + nLen)
xor_result = Xor(xor_result, temp)
}
const FirstPartToAscii = StringToAscii(xor_result.substring(0, nLen / 2))
const SecondPartToAscii = StringToAscii(
xor_result.substring(nLen / 2, nLen / 2 + nLen / 2)
)
const FirstMac = await this.encryptData('MacKey', FirstPartToAscii, 'ECB')
if (FirstMac !== undefined && FirstMac.length > 0) {
const XorLast = Xor(FirstMac, SecondPartToAscii)
const SecondMac = await this.encryptData('MacKey', XorLast, 'ECB')
if (SecondMac !== undefined && SecondMac.length > 0) {
mac = SecondMac
}
}
return mac
},
async initialize() {
return await RealDeviceDriver.FnCall(this, 'Initialize', [])
},
async encryptData(KeyName, Data, Algorithm) {
const jsonData = { KeyName, Data, Algorithm }
return await RealDeviceDriver.FnCall(this, 'Encrypt', [
JSON.stringify(jsonData)
])
},
async generateMac(Data) {
return await RealDeviceDriver.FnCall(this, 'GenerateMac', [Data])
}
},
billValidator: {
type: 'BV',
id: 'billValidator',
name: 'BillValidator',
status: '',
statusCode: '',
statusMsg: '',
statusList: BillValidatorStatusConfig,
async open(logicalName?) {
return await RealDeviceDriver.FnCall(this, 'OpenConnection', [
logicalName
])
},
async close() {
return await RealDeviceDriver.FnCall(this, 'CloseConnection', [])
},
async getStatus() {
return await RealDeviceDriver.FnCall(this, 'GetStatus', [])
},
async getCashUnitInfo() {
return await RealDeviceDriver.FnCall(this, 'GetCashUnitInfo', [])
},
async reset() {
return await RealDeviceDriver.FnCall(this, 'Reset', [])
},
async setNoteInfo(notes) {
return await RealDeviceDriver.FnCall(this, 'SetNoteInfo', [notes])
},
async cashInStart() {
return await RealDeviceDriver.FnCall(this, 'CashInStart', [])
},
async cashInEnd() {
return await RealDeviceDriver.FnCall(this, 'CashInEnd', [])
}
}
}
// 初始化对象
const driver = useEZWare(
RealDeviceDriver.EventFunction,
RealDeviceDriver.EventResult
)
export { RealDeviceDriver }
service/device-driver/ezware/index.ts
import { EventFunctionType, EventResultType } from '@/types'
import { EZWebSocket } from './ez-web-socket'
import BcrCommon from './bcr-common-device'
import BillValidator from './bill-validator-device'
import CamCommon from './cam-common-device'
import CamSignature from './cam-signature-device'
import CrdCommon from './crd-common-device'
import IdcContactless from './idc-contactless-device'
import IdcCrdMotor from './idc-crd-motor-device'
import IdcInductive from './idc-inductive-device'
import IdcInhalation from './idc-inhalition-device'
import IdcMotor from './idc-motor-device'
import IdcSscMotor from './idc-ssc-motor-device'
import IdcSwipe from './idc-swipe-device'
import PinCommon from './pin-common-device'
import PtrCheckPrinter from './ptr-check-printer-device'
import PtrCheckScanner from './ptr-check-scanner-device'
import PtrDocument from './ptr-document-device'
import PtrFinger from './ptr-finger-device'
import PtrLabel from './ptr-label-device'
import PtrPassbook from './ptr-passbook-device'
import PtrReceipt from './ptr-receipt-device'
import PtrScanner from './ptr-scanner-device'
import SiuCommon from './siu-common-device'
// 定义连接地址
const wsUrl = import.meta.env.VITE_APP_EZWAREWEBSOCKET_URL
export const useEZWare = (
globalEventFunction: EventFunctionType,
globalEventResult: EventResultType
) => {
const ezWebSocket = new EZWebSocket(wsUrl)
const bcrCommon = new BcrCommon(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const billValidator = new BillValidator(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const camCommon = new CamCommon(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const camSignature = new CamSignature(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const crdCommon = new CrdCommon(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcContactless = new IdcContactless(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcCrdMotor = new IdcCrdMotor(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcInductive = new IdcInductive(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcInhalation = new IdcInhalation(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcMotor = new IdcMotor(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcSscMotor = new IdcSscMotor(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const idcSwipe = new IdcSwipe(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const pinCommon = new PinCommon(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrChechPrinter = new PtrCheckPrinter(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrCheckScanner = new PtrCheckScanner(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrDocument = new PtrDocument(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrFinger = new PtrFinger(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrLabel = new PtrLabel(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrPassbook = new PtrPassbook(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrReceipt = new PtrReceipt(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const ptrScanner = new PtrScanner(
ezWebSocket,
globalEventFunction,
globalEventResult
)
const siuCommon = new SiuCommon(
ezWebSocket,
globalEventFunction,
globalEventResult
)
// 返回一个对象,该对象多个属性:barcode等
// barcode 属性的值来自变量 bcrCommon 的当前值
return {
barcode: bcrCommon,
billValidator: billValidator,
camCommon,
camSignature,
cardDispenser: crdCommon,
icCardReader: idcContactless,
cardDispenserReader: idcCrdMotor,
idCardReader: idcInductive, // 感应式身份证阅读器
idCardReader1: idcInhalation, // 插入式身份证阅读器:暂不使用,临时命名idCardReader1,使用时改为idCardReader
cardReader: idcMotor,
ssCardReader: idcSscMotor,
swCardReader: idcSwipe,
pinPad: pinCommon,
ptrChechPrinter,
ptrCheckScanner,
documentPrinter: ptrDocument,
ptrFinger,
labelPrinter: ptrLabel,
passbookPrinter: ptrPassbook,
receiptPrinter: ptrReceipt,
ptrScanner,
siu: siuCommon
}
}
二、调用示例
详见前文
三、运行测试
详见后文