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(() => {
/>
-
+
+
+
+
+