uniapp微信小程序调用nfc

61 阅读2分钟
// 核心工具函数:将ArrayBuffer转换为十六进制字符串
export function arrayBufferToHex(buffer) {
    // 将ArrayBuffer转为Uint8Array(便于遍历每个字节)
    const uint8Array = new Uint8Array(buffer);
 
    // 每个字节转为两位十六进制,不足两位补0,最后拼接成字符串
    return Array.from(uint8Array)
        .map(byte => byte.toString(16).padStart(2, '0')) // 确保每个字节占两位
        .join('')
        .toUpperCase(); // 转为大写(UID通常以大写展示)
}
 
export const stringToBuffer = function (str) {
    // 首先将字符串转为16进制
 
    if (!str) {
        return new Uint8Array().buffer;
    }
    let val = ""
    for (let i = 0; i < str.length; i++) {
        if (val === '') {
            val = str.charCodeAt(i).toString(16)
        } else {
            val += ',' + str.charCodeAt(i).toString(16)
        }
    }
 
 
    // 将16进制转化为ArrayBuffer
 
 
    return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
 
 
        return parseInt(h, 16)
 
 
    })).buffer
 
 
}

const prepareSeal = async (seal, position) => {
    // 调用拍照
    const photoUrl = await takePhoto()
 
    if (!photoUrl) return
 
    try {
        // 1. 获取 NFC 适配器
        adapter.value = wx.getNFCAdapter()
        toast.info('请使用手机触碰铅封')
 
        // 2. 清理旧的监听,避免重复触发
        if (discoveredListener.value) {
            adapter.value.offDiscovered(discoveredListener.value)
            discoveredListener.value = null
        }
 
        // 3. 开始发现 NFC 标签
        adapter.value.startDiscovery({
            success: () => {
                console.log('NFC 监听已开启')
 
                // 定义发现标签后的回调函数
                discoveredListener.value = async (tagRes: any) => {
                    console.log('发现 NFC 标签:', tagRes)
 
                    // 3.1 获取 UID
                    const uidBuffer = tagRes.id
                    const uid = arrayBufferToHex(uidBuffer)
                    console.log('标签 UID:', uid)
 
                    try {
                        // 3.2 调用后端接口,提交 UID 及相关数据
                        const data = {
                            transportOrderId: transportOrderId.value,
                            vehicleNumber: vehicleNumber.value,
                            chipUid: uid,
                            applySealPosition: `${position}号口`,
                            applySealImage: photoUrl,
                            userId: uni.getStorageSync('userInfo').userId,
                        }
 
                        const res: any = await nfcSealApi(data)
 
                        if (res.code === 200) {
                            console.log('接口响应成功:', res)
 
                            // 3.3 获取 NDEF 实例
                            const ndef = adapter.value.getNdef(tagRes)
                            if (!ndef) {
                                toast.error('该标签不支持 NDEF 写入')
                                return
                            }
 
                            // 3.4 连接 NDEF
                            ndef.connect({
                                success: () => {
                                    console.log('NDEF 连接成功')
 
                                    // 3.5 写入 NDEF 文本记录
                                    ndef.writeNdefMessage({
                                        records: [{
                                            id: stringToBuffer('1'),
                                            payload: stringToBuffer(res.data),
                                            type: stringToBuffer('T'), // 文本类型
                                            tnf: 1 // NFC Forum Well Known Type
                                        }],
                                        success: async () => {
                                            toast.success('写入成功')
                                            console.log('写入成功:', res.data)
 
                                            ndef.close()
                                            await init(transportOrderId.value)
                                        },
                                        fail: (err: any) => {
                                            toast.error('写入失败')
                                            console.error('写入失败', err)
                                            ndef.close()
                                        },
                                    })
                                },
                                fail: (err: any) => {
                                    toast.error('NDEF 连接失败')
                                    console.error('NDEF 连接失败:', err)
                                },
                            })
                        } else {
                            toast.error(res?.msg || '施封失败,请重新施封')
                        }
                    } catch (error: any) {
                        toast.error(error?.data?.msg || '施封失败,请重新施封')
                        console.error('接口调用异常:', error)
                    } finally {
                        // 3.6 清理监听和发现
                        if (discoveredListener.value) {
                            adapter.value.offDiscovered(discoveredListener.value)
                            discoveredListener.value = null
                        }
                        adapter.value.stopDiscovery()
                        console.log('NFC 监听已关闭')
                    }
                }
 
                // 注册标签监听
                adapter.value.onDiscovered(discoveredListener.value)
            },
            fail: (err: any) => {
                console.error('NFC 连接失败:', err)
                toast.error('NFC 连接失败')
                adapter.value.stopDiscovery()
            },
        })
    } catch (err) {
        console.error('NFC 初始化失败:', err)
        toast.error('NFC 初始化失败')
    }
}