chenhaozhe
2025-07-15 85693d40e9868172b36c77876410abb13dbc7273
蓝牙打印机组件 添加 批量打印功能, 完成 采购订单生成条码 打印
6个文件已修改
401 ■■■■ 已修改文件
components/blueToothConnector/blueToothConnector.vue 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/labelPrinterComponent/labelPrinterComponent.vue 116 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/caigoudingdan/generate.vue 192 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/index/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/common.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/blueToothConnector/blueToothConnector.vue
@@ -56,7 +56,8 @@
            return {
                discoveredDevices: [], // 查询到的设备
                connectedDeviceId: "",
                readSuccess: false
                readSuccess: false,
                clock: null,
            };
        },
        methods: {
@@ -173,22 +174,27 @@
                });
            },
            async checkReadSuccess(count) {
                // 批量插入时,如果前一次发送成功,则清除前一次的时钟
                if (this.clock != null) {
                    this.clock.stop();
                    this.clock = null;
                }
                let that = this
                return new Promise((resolve, reject) => {
                    let currentCount = 0;
                    let clock = new CommonUtils.timeClock(() => {
                    that.clock = new CommonUtils.timeClock(() => {
                        currentCount++;
                        if (this.readSuccess == true) {
                            clock.stop();
                            that.clock.stop();
                            resolve(true);
                        } else if (currentCount >= count) {
                            clock.stop();
                            that.clock.stop();
                            reject(new Error('读取超时'));
                        }
                    }, 2000);
                    // 启动时钟
                    clock.start();
                    that.clock.start();
                });
            },
            async sendMessage(cmd) {
@@ -196,7 +202,7 @@
                uni.showLoading({
                    title: "发送中..."
                })
                console.log("msg: " + cmd);
                // console.log("msg: " + cmd);
                let toast = (msg) => {
                    uni.showToast({
                        icon: 'none',
@@ -207,23 +213,29 @@
                        uni.hideLoading()
                    }, 3000)
                }
                const result = blueToothTool.sendByteData(cmd);
                if (!result) {
                    return toast("发送失败,请重试...")
                }
                this.checkReadSuccess(5)
                .then((res) => {
                    if(res === true) {
                        toast('发送成功!!!')
                let that = this
                return new Promise((resolve, reject) => {
                    const result = blueToothTool.sendByteData(cmd);
                    if (!result) {
                        toast("发送失败,请重试...")
                        reject(false)
                    }
                    that.checkReadSuccess(5)
                        .then((res) => {
                            if (res === true) {
                                toast('发送成功!!!')
                                resolve(true)
                            }
                        })
                        .catch((err) => {
                            toast('设备异常,请检查设备状态...')
                            reject(false)
                        })
                        .finally(() => {
                            that.readSuccess = false
                        })
                })
                .catch((err) => {
                    toast('设备异常,请检查设备状态...')
                })
                .finally(() => {
                    this.readSuccess = false
                })
            },
            uint8ArrayToSignedArray(uint8Array) {
                let signedArray = new Array(uint8Array.length);
@@ -256,10 +268,10 @@
                    console.log("搜索完成");
                },
                readDataCallback: (dataByteArr) => {
                    /* if(that.receiveDataArr.length >= 200) {
                        that.receiveDataArr = [];
                    }
                    that.receiveDataArr.push.apply(that.receiveDataArr, dataByteArr); */
                    // if(that.receiveDataArr.length >= 200) {
                    //     that.receiveDataArr = [];
                    // }
                    // that.receiveDataArr.push.apply(that.receiveDataArr, dataByteArr);
                    this.readSuccess = true
                    console.log("读取完成" + dataByteArr);
                },
components/labelPrinterComponent/labelPrinterComponent.vue
@@ -28,6 +28,9 @@
    import {
        CStatus
    } from '@psdk/cpcl';
    import {
        CommonUtils
    } from '../../utils/common';
    export default {
        name: "lablePrinterComponent",
@@ -60,6 +63,45 @@
            popupCloseHandler() {
            },
            async batchPrint(commandList) {
                let vm = this;
                let binarys = [];
                for (let command of commandList) {
                    switch (vm.printMode) {
                        case "tspl":
                            let tspl = await vm.$printer.tspl().clear();
                            tspl.raw(Raw.text(command))
                            console.log("print command:\n" + tspl.command().string())
                            binarys.push(tspl.command().binary());
                            break;
                        case "cpcl":
                            let cpcl = await vm.$printer.cpcl().clear();
                            cpcl.raw(Raw.text(command))
                            console.log("print command:\n" + cpcl.command().string())
                            binarys.push(cpcl.command().binary());
                            break;
                        case "esc":
                            let esc = await vm.$printer.esc().clear();
                            esc.raw(Raw.text(command))
                            console.log("print command:\n" + esc.command().string())
                            binarys.push(esc.command().binary());
                            break;
                        default:
                            return uni.showToast({
                                icon: 'none',
                                title: 'printMode类型错误!'
                            })
                    }
                }
                for(let binary of binarys){
                    let sendSuccess = await this.blueToothConnector.sendMessage(binary);
                    console.log("发送是否成功: ", sendSuccess)
                    if(sendSuccess === false) {
                        return
                    }
                }
            },
            async execPrint() {
                // 检查蓝牙连接
                let btStatus = bluetoothTool.getBluetoothStatus()
@@ -74,48 +116,54 @@
                    this.showToast("无设备连接!")
                    return
                }
                try {
                    if (typeof this.printInfo === 'function') {
                        // 传入的printInfo是函数,直接执行
                        let msg = await this.printInfo()
                        this.blueToothConnector.sendMessage(msg)
                    } else if (typeof this.printInfo === 'string') {
                        // 传入的参数是字符串,则根据打印模式调用不同的打印API
                        // 这里的字符串需要对应打印模式
                        let printStr = this.printInfo.replace(/\n/g, "\r\n")
                        let vm = this;
                        let binary = null;
                        switch (vm.printMode) {
                            case "tspl":
                                const tspl = await vm.$printer.tspl().clear();
                                tspl.raw(Raw.text(printStr))
                                console.log("print command:\n" + tspl.command().string())
                                binary = tspl.command().binary();
                                await vm.blueToothConnector.sendMessage(binary);
                                break;
                            case "cpcl":
                                const cpcl = await vm.$printer.cpcl().clear();
                                cpcl.raw(Raw.text(printStr))
                                console.log("print command:\n" + cpcl.command().string())
                                binary = cpcl.command().binary();
                                await vm.blueToothConnector.sendMessage(binary);
                                break;
                            case "esc":
                                const esc = await vm.$printer.esc().clear();
                                esc.raw(Raw.text(printStr))
                                console.log("print command:\n" + esc.command().string())
                                binary = esc.command().binary();
                                await vm.blueToothConnector.sendMessage(binary);
                                break;
                            default:
                                return uni.showToast({
                                    icon: 'none',
                                    title: 'printMode类型错误!'
                                })
                        if (CommonUtils.isJson(this.printInfo) === true) {
                            // 如果需要批量传输,需要传JSON
                            let commandList = JSON.parse(this.printInfo)
                            for (let command of commandList) {
                                command.replace(/\n/g, "\r\n")
                            }
                            this.batchPrint(commandList)
                        } else {
                            let printStr = this.printInfo.replace(/\n/g, "\r\n")
                            let vm = this;
                            let binary = null;
                            switch (vm.printMode) {
                                case "tspl":
                                    const tspl = await vm.$printer.tspl().clear();
                                    tspl.raw(Raw.text(printStr))
                                    console.log("print command:\n" + tspl.command().string())
                                    binary = tspl.command().binary();
                                    await vm.blueToothConnector.sendMessage(binary);
                                    break;
                                case "cpcl":
                                    const cpcl = await vm.$printer.cpcl().clear();
                                    cpcl.raw(Raw.text(printStr))
                                    console.log("print command:\n" + cpcl.command().string())
                                    binary = cpcl.command().binary();
                                    await vm.blueToothConnector.sendMessage(binary);
                                    break;
                                case "esc":
                                    const esc = await vm.$printer.esc().clear();
                                    esc.raw(Raw.text(printStr))
                                    console.log("print command:\n" + esc.command().string())
                                    binary = esc.command().binary();
                                    await vm.blueToothConnector.sendMessage(binary);
                                    break;
                                default:
                                    return uni.showToast({
                                        icon: 'none',
                                        title: 'printMode类型错误!'
                                    })
                            }
                        }
                    } else {
                        uni.showToast({
pages.json
@@ -464,6 +464,18 @@
                    }
                },
                {
                    "path": "pages/caigoudingdan/generate",
                    "style": {
                        "navigationBarTitleText": "条码生成"
                    }
                },
                {
                    "path": "pages/caigoudingdan/caigoudingdan",
                    "style": {
                        "navigationBarTitleText": "采购订单"
                    }
                },
                {
                    "path" : "pages/MJGL/shangmudan/table",
                    "style" : 
                    {
pages/caigoudingdan/generate.vue
@@ -46,13 +46,14 @@
            </view>
            <view class="buttons">
                <button class="btn-b" size="mini" type="default" @tap="getList()">条码生成</button>
                <button class="btn-c" size="mini" type="default" @tap="search">打印</button>
                <button class="btn-c" :disabled="codeGenComplete == false" size="mini" type="default"
                    @tap="search">打印</button>
            </view>
        </view>
        <view style="width: 100%;height: 16rpx;background-color: #e5e5e5;"></view>
        <view class="list" v-for="(item,index) in listData" :key="index" @tap="toSon(item)">
        <view class="list" v-for="(item,index) in listData" :key="index">
            <uni-card :title="item.物料代码" :extra="'No. ' + Number(index+1)" style="margin: 10px;">
                <view class="card-detail">
                    <view class="detail">
@@ -70,11 +71,14 @@
                </view>
            </uni-card>
        </view>
        <labelPrinterComponentVue ref="labelPrinter" :printInfo="printInfo" :printMode="'cpcl'">
        </labelPrinterComponentVue>
        <view class="over" v-if="listData.length == 0">暂无数据</view>
        <view class="over" v-if="listData.length != 0">已到底</view>
        <view>
            <labelPrinterComponentVue ref="labelPrinter" :printInfo="printInfo" :printMode="'cpcl'">
            </labelPrinterComponentVue>
        </view>
    </view>
</template>
@@ -85,6 +89,10 @@
    import {
        CommonUtils
    } from "../../utils/common";
    import {
        nextTick
    } from "vue";
    import labelPrinterComponentVue from "@/components/labelPrinterComponent/labelPrinterComponent.vue"
    export default {
        data() {
            return {
@@ -95,6 +103,7 @@
                linterid: '',
                HEntryID: '',
                hmaterid: '',
                codeGenComplete: false,
                baseInfo: {
                    HBillNo: '',
                    HMainID: '',
@@ -109,10 +118,15 @@
                    HQty: '',
                    HMinQty: '',
                    HBQty: '',
                    HSupID: '',
                },
                sWhere: '',
                listData: [],
            }
        },
        components: {
            labelPrinterComponentVue
        },
        onLoad(e) {
            console.log(e)
@@ -125,8 +139,8 @@
            getData() {
                CommonUtils.doRequest(
                    "/Cg_POOrderBill/list", {
                        sWhere: ` and hmainid = ${this.linterid} and HMaterID  = ${this.hmaterid}`
                        ,user: this.userInfo.Czymc
                        sWhere: ` and hmainid = ${this.linterid} and HMaterID  = ${this.hmaterid}`,
                        user: this.userInfo.Czymc
                    },
                    (res) => {
                        console.log('采购订单: ', res)
@@ -144,7 +158,8 @@
                                HMaterName: data[0]['物料名称'],
                                HMaterModel: data[0]['规格型号'],
                                HQty: data[0]['数量'],
                                HMTONo: data[0]['计划跟踪号']
                                HMTONo: data[0]['计划跟踪号'],
                                HSupID: data[0]['HSupID']
                            }
                            this.listData = data
                        } else {
@@ -172,143 +187,25 @@
                if (this.$printer.isConnected() === false) {
                    this.$refs.labelPrinter.openPopup()
                } else {
                    // this.printInfo = async () => {
                    //     let cpcl = await this.$printer.cpcl().clear()
                    //         .page(new CPage({
                    //             width: 608,
                    //             height: 400
                    //         }))
                    //         .qrcode(new CQRCode({
                    //             x: 500,
                    //             y: 30,
                    //             width: 3,
                    //             content: this.generatedBarCode,
                    //             codeRotation: CCodeRotation.ROTATION_0,
                    //             level: CCorrectLevel.L
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 30,
                    //             content: "供应商: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 80,
                    //             content: "供应商料号: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 130,
                    //             content: "物料编码: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 180,
                    //             content: "物料分组: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 300,
                    //             y: 180,
                    //             content: "规格型号: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 230,
                    //             content: "数量: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 300,
                    //             y: 230,
                    //             content: "日期: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 280,
                    //             content: "检验员: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 300,
                    //             y: 280,
                    //             content: "计划跟踪号: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .text(new CText({
                    //             x: 30,
                    //             y: 330,
                    //             content: "检验结果: ",
                    //             font: CFont.TSS24
                    //         }))
                    //         .box(new CBox({
                    //             topLeftX: 260,
                    //             topLeftY: 320,
                    //             bottomRightX: 280,
                    //             bottomRightY: 340,
                    //             lineWidth: 4,
                    //         }))
                    //         .text(new CText({
                    //             x: 290,
                    //             y: 320,
                    //             content: "合格",
                    //             font: CFont.TSS24
                    //         }))
                    //         .box(new CBox({
                    //             topLeftX: 360,
                    //             topLeftY: 320,
                    //             bottomRightX: 380,
                    //             bottomRightY: 340,
                    //             lineWidth: 4,
                    //         }))
                    //         .text(new CText({
                    //             x: 390,
                    //             y: 320,
                    //             content: "不合格",
                    //             font: CFont.TSS24
                    //         }))
                    //         .box(new CBox({
                    //             topLeftX: 480,
                    //             topLeftY: 320,
                    //             bottomRightX: 500,
                    //             bottomRightY: 340,
                    //             lineWidth: 4,
                    //         }))
                    //         .text(new CText({
                    //             x: 510,
                    //             y: 320,
                    //             content: "特采",
                    //             font: CFont.TSS24
                    //         }))
                    //         .form(new CForm())
                    //         .print();
                    //     console.log(cpcl.command().string())
                    //     return cpcl.command().binary()
                    // }
                    // await this.$nextTick(() => {
                    //     this.$refs.labelPrinter.execPrint()
                    // })
                    this.printInfo = `! 0 200 200 400 1
                    let printContent = []
                    let printInfoBuffer = []
                    let count = 0
                    for (let listOne of this.listData) {
                        printContent.push(`! 0 200 200 400 1
PAGE-WIDTH 608
SETQRVER 3
B QR 500 30 M 2 U 3
LA,${this.generatedBarCode}
LA,${listOne['条码编号']}
ENDQR
T 24 0 30 30 供应商:
T 24 0 30 30 供应商: ${listOne['供应商']}
T 24 0 30 80 供应商料号:  
T 24 0 30 130 物料编码:
T 24 0 30 180 物料分组:
T 24 0 300 180 规格型号:
T 24 0 30 230 数量:
T 24 0 300 230 日期:
T 24 0 30 130 物料编码: ${listOne['物料代码']}
T 24 0 30 180 物料分组: ${listOne['托号']}
T 24 0 300 180 规格型号: ${listOne['规格型号']}
T 24 0 30 230 数量:  ${listOne['数量']}
T 24 0 300 230 日期: ${listOne['日期'].split(" ")[0]}
T 24 0 30 280 检验员: 
T 24 0 300 280 计划跟踪号:
T 24 0 300 280 计划跟踪号: ${listOne['计划跟踪号']}
T 24 0 30 330 检验结果: 
BOX 260 330 280 350 4
T 24 0 290 330 合格
@@ -317,9 +214,18 @@
BOX 480 330 500 350 4
T 24 0 510 330 特采
FORM
PRINT`
PRINT`)
                        count++;
                        if (count == 10) {
                            printInfoBuffer.push(printContent.join("\r\n"))
                            count = 0
                            printContent = []
                        }
                    }
                    printInfoBuffer.push(printContent.join("\r\n"))
                    this.printInfo = JSON.stringify(printInfoBuffer)
                    printInfoBuffer = []
                    await this.$nextTick(() => {
                        this.$refs.labelPrinter.execPrint()
@@ -358,6 +264,7 @@
                                icon: 'none'
                            })
                        }
                        this.codeGenComplete = true
                    },
                    fail: (res) => {
                        console.log(res);
@@ -427,6 +334,11 @@
            font-size: 28rpx;
        }
        button[disabled] {
            background-color: #acacac;
            color: #fff;
        }
        .btn-a {
            background-color: #acacac;
            color: #fff;
pages/index/index.vue
@@ -166,7 +166,7 @@
                    },
                    {
                        img: '../../static/icon/icon16.png',
                        text: '条码打印',
                        text: '来料条码打印',
                        url: '/pages/tiaomadaying/tiaomadaying',
                        id: 28,
                    },
@@ -175,7 +175,13 @@
                        text: '上模单',
                        url: '/pages/MJGL/shangmudan/table',
                        id: 29,
                    }
                    },
                    {
                        img: '../../static/icon/icon16.png',
                        text: '采购订单',
                        url: '/pages/caigoudingdan/caigoudingdan',
                        id: 30,
                    },
                ]
            }
        },
utils/common.js
@@ -88,6 +88,15 @@
        return /^\d+$/.test(str);
    }
    
    isJson(str) {
        try{
            JSON.parse(str)
            return true
        }catch{
            return false
        }
    }
    timeClock(callback, delay) {
        let timeoutId;
        let isRunning = false;