diff --git a/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue b/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue index 2f003f25e..e5e5fc449 100644 --- a/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue +++ b/apps/web-antd/src/views/mall/trade/delivery/pickUpOrder/index.vue @@ -2,16 +2,20 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table'; import type { MallOrderApi } from '#/api/mall/trade/order'; -import { onMounted, ref } from 'vue'; +import { h, onMounted, ref } from 'vue'; -import { Page } from '@vben/common-ui'; +import { Page, prompt } from '@vben/common-ui'; -import { Card } from 'ant-design-vue'; +import { Card, Input, message } from 'ant-design-vue'; -import { useVbenVxeGrid } from '#/adapter/vxe-table'; -import { getOrderPage, getOrderSummary } from '#/api/mall/trade/order'; +import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; +import { + getOrderByPickUpVerifyCode, + getOrderPage, + getOrderSummary, +} from '#/api/mall/trade/order'; import { SummaryCard } from '#/components/summary-card'; -import { DeliveryTypeEnum, fenToYuan } from '#/utils'; +import { DeliveryTypeEnum, fenToYuan, TradeOrderStatusEnum } from '#/utils'; import { useGridColumns, useGridFormSchema } from './data'; @@ -24,6 +28,115 @@ async function getOrderSum() { summary.value = res; } +/** 核销 */ +async function handlePickup(pickUpVerifyCode?: string) { + if (!pickUpVerifyCode) { + pickUpVerifyCode = await prompt({ + component: () => { + return h(Input, {}); + }, + content: '请输入核销码', + title: '核销订单', + modelPropName: 'value', + }).then(async (val) => { + if (val) { + return val; + } + }); + } + if (!pickUpVerifyCode) { + return; + } + const data = await getOrderByPickUpVerifyCode(pickUpVerifyCode); + if (data?.deliveryType !== DeliveryTypeEnum.PICK_UP.type) { + message.error('未查询到订单'); + return; + } + if (data?.status !== TradeOrderStatusEnum.UNDELIVERED.status) { + message.error('订单不是待核销状态'); + } +} + +const port = ref(''); +const ports = ref([]); +const reader = ref(''); +const serialPort = ref(false); // 是否连接扫码枪 + +/** 连接扫码枪 */ +async function connectToSerialPort() { + try { + // 判断浏览器支持串口通信 + if ( + 'serial' in navigator && + navigator.serial !== null && + typeof navigator.serial === 'object' && + 'requestPort' in navigator.serial + ) { + // 提示用户选择一个串口 + port.value = await (navigator.serial as any).requestPort(); + } else { + message.error('浏览器不支持扫码枪连接,请更换浏览器重试'); + return; + } + + // 获取用户之前授予该网站访问权限的所有串口。 + ports.value = await (navigator.serial as any).getPorts(); + + // 等待串口打开 + await (port.value as any).open({ + baudRate: 9600, + dataBits: 8, + stopBits: 2, + }); + + message.success('成功连接扫码枪'); + serialPort.value = true; + readData(); + } catch (error) { + // 处理连接串口出错的情况 + console.error('Error connecting to serial port:', error); + } +} + +/** 监听扫码枪输入 */ +async function readData() { + reader.value = (port.value as any).readable.getReader(); + let data = ''; // 扫码数据 + // 监听来自串口的数据 + while (true) { + const { value, done } = await (reader.value as any).read(); + if (done) { + // 允许稍后关闭串口 + (reader.value as any).releaseLock(); + break; + } + // 获取发送的数据 + const serialData = new TextDecoder().decode(value); + data = `${data}${serialData}`; + if (serialData.includes('\r')) { + // 读取结束 + const codeData = data.replace('\r', ''); + data = ''; // 清空下次读取不会叠加 + console.warn(`二维码数据:${codeData}`); + // 处理拿到数据逻辑 + handlePickup(codeData); + } + } +} + +async function cutPort() { + if (port.value === '') { + message.warning('请先连接或打开扫码枪'); + } else { + await (reader.value as any).cancel(); + await (port.value as any).close(); + port.value = ''; + console.warn('断开扫码枪连接'); + message.success('已成功断开扫码枪连接'); + serialPort.value = false; + } +} + const [Grid, gridApi] = useVbenVxeGrid({ formOptions: { schema: useGridFormSchema(), @@ -101,6 +214,27 @@ onMounted(() => { /> - + + +