更新记录
1.0.2(2026-10-14) 下载此版本
- 承接项目侧下沉:
pairable协议(ident / link / syncPairableLinks / 开线解析) - 新增
WiredDeviceBase(有线设备开线公共基类) formatPairIdentDesc:local 通道返回"local",不再含中文「本机」(本地化由项目 catalog)
1.0.1(2026-10-14) 下载此版本
- 边界收敛:PrintError / WeightError 下沉至能力包,core 仅保留通用设备错误
- 修正插件描述与 keywords(去掉打印 / BLE 域语义)
1.0.0(2026-10-14) 下载此版本
- 首次发布
- 提供设备框架核心:能力接口、状态机、注册表、会话管理与打印模型
平台兼容性
uni-app(5.06)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | √ | - | √ | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
pro-device-core — 设备框架核心
设备管理框架的基础层。提供连接状态机、设备注册表、会话管理器、传输层接口以及 ConnectableBase 基类。
不包含任何具体设备或传输层实现,各能力域由独立插件提供:
| 插件 | 职责 |
|---|---|
pro-device-core |
框架核心(本包) |
pro-device-print |
打印接口、画布模型、SDKPrinterBase |
pro-device-scale |
称重接口 IWeighable、ScaleDevice 类型 |
pro-device-scanner |
扫码接口 IScannable、ScannerDevice 类型 |
pro-device-terminal |
终端接口 TerminalDevice、TerminalCapabilities |
pro-device-adp-ble |
BLE 传输适配器 BLEAdapter |
pro-device-adp-uart |
板载 tty 串口 SerialAdapter(仅 Android) |
pro-device-adp-usb |
USB Host 串口 UsbSerialAdapter(仅 Android) |
pro-device-adp-sunmi |
商米 UTS 原生适配层 |
架构总览
┌──────────────────────────────────────────────────────────────┐
│ 业务层 (Vue / Pinia) │
└─────────────────────────────┬────────────────────────────────┘
│ useAppDeviceStore / createDeviceSession
┌─────────────────────────────▼────────────────────────────────┐
│ 项目层 src/devices/ │
│ DeviceRegistry · createDeviceSession() · detect*() │
│ 具体设备: GPrinterGPM421 / FayaBX380 / SunmiScanner ... │
└──────┬──────────────────────┬──────────────────────┬─────────┘
│ │ │
┌──────▼──────┐ ┌────────────▼──────┐ ┌───────────▼─────────┐
│pro-device │ │ pro-device-print │ │ pro-device-scale │
│ -core │ │ pro-device-adp-ble │ │ pro-device-scanner │
│ (本包) │ │ pro-device-adp-sunmi │ │ pro-device-terminal│
└─────────────┘ └───────────────────┘ └─────────────────────┘
快速上手
1. 最小示例:连接一台 BLE 打印机并打印
import { DeviceRegistry, DeviceSession } from '@/uni_modules/pro-device-core'
import { SDKPrinterBase } from '@/uni_modules/pro-device-print'
// 项目中实际通过 src/devices/index.ts 封装好的工厂函数调用,此处展示底层逻辑
type MyDeviceMap = { print: GPrinterGPM421 }
const registry = new DeviceRegistry<GPrinterGPM421>()
.registerModel('Gprinter', 'GP-M421', cfg => new GPrinterGPM421(cfg))
const session = new DeviceSession<MyDeviceMap>()
.setRegistry('print', registry)
// ── 连接 ──────────────────────────────────────────────────────
const printer = await session.acquire('print', {
brand: 'Gprinter',
model: 'GP-M421',
ident: 'AA:BB:CC:DD:EE:FF', // BLE MAC 地址或 deviceId
})
// ── 打印 ──────────────────────────────────────────────────────
const label = new HazardousWasteLabel({ chemName: '废矿物油', code: 'HW08-001' })
await printer.print(label)
// ── 清理(组件 onUnmounted) ─────────────────────────────────
await session.releaseAll()
核心 API
ConnectionState — 连接状态枚举
import { ConnectionState } from '@/uni_modules/pro-device-core'
ConnectionState.Disconnected // 'disconnected' 初始/断开后
ConnectionState.Connecting // 'connecting' 连接中
ConnectionState.Connected // 'connected' 已连接
ConnectionState.Disconnecting // 'disconnecting' 断开中
ConnectionState.Error // 'error' 连接失败
合法的状态跳转:
Disconnected → Connecting → Connected → Disconnecting → Disconnected
↘ ↗
Error → Connecting / Disconnected
ConnectableBase — 可连接设备基类
所有需要"连接/断开"能力的设备都应继承此类。它内嵌 ConnectionStateMachine,子类只需实现 connect() / disconnect()。
import { ConnectableBase } from '@/uni_modules/pro-device-core'
import type { IConnectable, Unsubscribe } from '@/uni_modules/pro-device-core'
export class MyDevice extends ConnectableBase {
// 当前连接状态(继承自基类)
// get state(): ConnectionState
async connect(): Promise<void> {
this._sm.transition(ConnectionState.Connecting)
await openHardware()
this._sm.transition(ConnectionState.Connected)
}
async disconnect(): Promise<void> {
this._sm.transition(ConnectionState.Disconnecting)
await closeHardware()
this._sm.forceSet(ConnectionState.Disconnected)
}
}
// ── 使用 ──────────────────────────────────────────────────────
const device = new MyDevice()
// 订阅状态变化
const unsub: Unsubscribe = device.onStateChange(state => {
console.log('状态变化:', state)
})
await device.connect() // → Connecting → Connected
console.log(device.state) // 'connected'
await device.disconnect() // → Disconnecting → Disconnected
unsub() // 取消订阅
DeviceRegistry<T> — 设备注册表
使用 matcher 断言函数匹配设备,支持模糊匹配。注册顺序决定优先级(先注册先匹配)。
import { DeviceRegistry } from '@/uni_modules/pro-device-core'
// 按型号前缀注册(推荐用于同型号系列)
const registry = new DeviceRegistry<MyPrinter>()
.registerModel('Gprinter', 'GP-M421', cfg => new GPrinterGPM421(cfg))
.registerModel('Xprinter', 'XP-P441B', cfg => new XPrinterXPP441B(cfg))
// 按品牌注册(同品牌共用实现)
registry.registerBrand('sunmi', cfg => new SunmiBuiltInPrinter(cfg))
// 完全自定义 matcher(例如匹配多个型号)
registry.register(
(brand, model) => brand === 'Faya' && ['BX380', 'E350', 'E360'].includes(model),
cfg => new FayaScale(cfg),
)
// ── 解析 ──────────────────────────────────────────────────────
const printer = registry.resolve({ brand: 'Gprinter', model: 'GP-M421', ident: '...' })
// ── 探测(不实例化) ──────────────────────────────────────────
if (registry.canResolve('sunmi', 'T2')) {
console.log('当前终端有内置打印机')
}
DeviceSession<TMap> — 设备会话管理器
统一管理多台设备的生命周期。TMap 由项目层传入,将设备类型键映射到对应实例类型。
import { DeviceSession } from '@/uni_modules/pro-device-core'
// 项目层类型映射(src/devices/index.ts 中定义)
type ProjectDeviceTypeMap = {
print: PrintDevice
scale: ScaleDevice
scanner: ScannerDevice
terminal: TerminalDevice
}
const session = new DeviceSession<ProjectDeviceTypeMap>()
.setRegistry('print', printRegistry)
.setRegistry('scale', scaleRegistry)
.setRegistry('scanner', scannerRegistry)
.setRegistry('terminal', terminalRegistry)
acquire(type, config) — 连接并获取设备
// 返回类型由 TMap 精确推导,无需类型断言
const printer = await session.acquire('print', { brand: 'Gprinter', model: 'GP-M421', ident: '...' })
const scale = await session.acquire('scale', { brand: 'Faya', model: 'BX380', ident: 'AA:BB:...' })
const scanner = await session.acquire('scanner', { brand: 'sunmi', model: 'T2' })
const terminal = await session.acquire('terminal', { brand: 'sunmi', model: 'T2' })
- 若设备已连接(相同
type|brand|model|ident),直接复用实例,不重复连接 - 非可连接设备(如
SunmiTerminal)自动走缓存,避免重复读取系统信息
release(device) — 断开指定设备
await session.release(printer) // 断开打印机,从会话移除
releaseAll() — 断开所有设备
// 在 onUnmounted 中调用,防止内存泄漏
onUnmounted(() => session.releaseAll())
完整 Vue 组件示例
import { onMounted, onUnmounted, ref } from 'vue'
import { createDeviceSession } from '@/devices'
const session = createDeviceSession()
const printer = ref<PrintDevice | null>(null)
onMounted(async () => {
try {
printer.value = await session.acquire('print', {
brand: 'Gprinter',
model: 'GP-M421',
ident: 'AA:BB:CC:DD:EE:FF',
})
} catch (e) {
uni.showToast({ title: '打印机连接失败', icon: 'none' })
}
})
onUnmounted(() => session.releaseAll())
ConnectionStateMachine — 状态机
通常通过 ConnectableBase._sm 使用,无需直接实例化。
import { ConnectionStateMachine } from '@/uni_modules/pro-device-core'
import { ConnectionState } from '@/uni_modules/pro-device-core'
const sm = new ConnectionStateMachine()
sm.transition(ConnectionState.Connecting) // 合法跳转
sm.forceSet(ConnectionState.Error) // 强制设置(用于外部事件,如蓝牙断连通知)
const unsub = sm.onStateChange(state => console.log(state))
unsub() // 取消订阅
ITransport — 传输层接口
BLEAdapter、SerialAdapter、UsbSerialAdapter 均满足此接口(结构类型,无 implements)。
连接 vs 断开(抹平通道差异)
| 语义 | 统一入口 | 说明 |
|---|---|---|
| 连接 | await open(config) |
resolve = 会话已建立;不需要再订 onConnect |
| 主动断开 | await close() |
不触发 onDisconnect |
| 意外断开 | onDisconnect(cb) |
BLE/USB:原生事件;tty:可用 SessionProbe 合成 |
import type { ITransport, TransportConfig, TransportDisconnectReason } from '@/uni_modules/pro-device-core'
import { SessionProbe, CallbackHub } from '@/uni_modules/pro-device-core'
// 设备基类只订统一断开,不关心来源是 native 还是 probe
transport.onDisconnect((reason: TransportDisconnectReason) => {
// remote | io-error | probe-timeout | unknown
})
| 方法 | 签名 | 说明 |
|---|---|---|
open(config) |
Promise<void> |
连接同步点 |
close() |
Promise<void> |
主动断开(不发 onDisconnect) |
send(data) |
Promise<void> |
发送 ArrayBuffer |
onReceive(cb) |
TransportUnsubscribe |
订阅数据接收 |
onDisconnect(cb) |
TransportUnsubscribe |
订阅意外断开(cb(reason) 必收原因) |
connected |
boolean |
当前连接状态 |
辅助:SessionProbe(会话探活)、CallbackHub(多订阅者)、TransportLinkCapability(native | probe | none)。
错误体系
core 只提供通用设备错误;打印 / 称重错误分别在能力包:
import {
DeviceError,
DeviceNotFoundError,
ConnectionError,
CommunicationError,
InvalidStateError,
} from '@/uni_modules/pro-device-core'
import { PrintError } from '@/uni_modules/pro-device-print'
import { WeightError } from '@/uni_modules/pro-device-scale'
try {
await session.acquire('print', { brand: 'Unknown', model: 'X1' })
} catch (e) {
if (e instanceof DeviceNotFoundError) {
console.error('未知设备', e.message)
}
}
try {
await device.connect()
} catch (e) {
if (e instanceof ConnectionError) {
console.error('连接失败', e.message, e.device, e.cause)
}
}
| 错误类 | 所在包 | 触发场景 |
|---|---|---|
DeviceNotFoundError |
core | registry.resolve() 无匹配条目 |
ConnectionError |
core | connect() / disconnect() 失败 |
CommunicationError |
core | 传输层读写失败 |
InvalidStateError |
core | 未连接断言 / 状态机非法跳转 |
PrintError |
pro-device-print | 打印失败 |
WeightError |
pro-device-scale | 称重失败 |
平台支持
本包为纯 TypeScript,无任何平台 API 调用,支持所有 uni-app 平台。

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 109
赞赏 0
下载 12681473
赞赏 1956
赞赏
京公网安备:11010802035340号