scanner in CustomerSelector.vue

This commit is contained in:
Timi
2026-09-09 17:49:37 +08:00
parent 809bfa8520
commit 8e77b114f9
17 changed files with 804 additions and 410 deletions
+20 -53
View File
@@ -7,7 +7,7 @@
class="keyword"
type="search"
borderless
placeholder="搜索订单号或客户"
placeholder="订单号或客户"
>
<template #suffix-icon>
<div class="actions">
@@ -15,8 +15,8 @@
size="extra-small"
theme="primary"
variant="outline"
:content="scannerVisible ? '关闭扫码' : '扫码'"
@click.stop="toggleScanner"
content="选择客户"
@click.stop="customerSelectorVisible = true"
/>
</div>
</template>
@@ -58,15 +58,6 @@
@refresh="refresh"
@scrolltolower="loadMore"
>
<div v-if="scannerVisible" class="scanner-wrap">
<code-scanner
visible
:status-text="scanStatus"
active-text="正在识别客户编码,请将条码或二维码移入取景框。"
@decode="handleDecodedText"
@status-change="handleScanStatusChange"
/>
</div>
<div v-if="list.length" class="items">
<sales-order-list-cell
class="item"
@@ -92,6 +83,11 @@
</t-pull-down-refresh>
</div>
<nav-bar-action-menu v-if="actions.length" :actions="actions" />
<customer-selector
v-model="customerId"
v-model:visible="customerSelectorVisible"
@change="handleCustomerChange"
/>
</template>
<script setup lang="ts">
@@ -100,7 +96,7 @@ import { Toolkit } from "timi-web";
import { useUserStore } from "timi-web-api";
import CustomerAPI from "@/api/CustomerAPI";
import SalesOrderAPI from "@/api/SalesOrderAPI";
import CodeScanner from "@/components/CodeScanner.vue";
import CustomerSelector from "@/components/CustomerSelector.vue";
import NavBarActionMenu from "@/components/NavBarActionMenu.vue";
import SalesOrderListCell from "@/pages/salesOrder/components/SalesOrderListCell.vue";
import { useNavBarStore } from "@/store/navBarStore";
@@ -141,9 +137,7 @@ const actions = computed(() => [
const keyword = ref("");
const customerId = ref("");
const selectedCustomer = ref<Customer>();
const scannerVisible = ref(false);
const scanStatus = ref("点击扫码开始识别。");
let latestDecodedText = "";
const customerSelectorVisible = ref(false);
let customerKeyword = "";
const orderType = ref("ALL");
type PaymentFilter = "ALL" | GaoSalesPaymentStatus | "PENDING_RECEIVE";
@@ -204,6 +198,16 @@ async function loadRouteCustomer(): Promise<void> {
setCustomerKeyword(selectedCustomer.value);
}
async function handleCustomerChange(): Promise<void> {
try {
await loadRouteCustomer();
await fetchList(true);
} catch (error) {
selectedCustomer.value = undefined;
Message.error(getErrorMessage(error, "客户加载失败"));
}
}
function buildPageFilter(): SalesOrderPage {
const pendingReceive = paymentStatus.value === "PENDING_RECEIVE";
return {
@@ -279,39 +283,6 @@ async function selectRefundStatus(value: DropdownValue): Promise<void> {
}
}
async function toggleScanner(): Promise<void> {
scannerVisible.value = !scannerVisible.value;
if (scannerVisible.value) {
latestDecodedText = "";
scanStatus.value = "正在打开相机。";
}
}
async function handleDecodedText(rawText: string): Promise<void> {
const code = rawText.trim();
if (!code || code === latestDecodedText) {
return;
}
latestDecodedText = code;
try {
const customer = await CustomerAPI.findByCode(code);
if (!customer?.id) {
scanStatus.value = `客户 ${code} 不存在。`;
return;
}
setCustomerKeyword(customer);
scanStatus.value = `已识别 ${customer.name || customer.code || code},已填入搜索框。`;
scannerVisible.value = false;
await fetchList(true);
} catch (error) {
scanStatus.value = getErrorMessage(error, "客户查询失败,请重试。");
}
}
function handleScanStatusChange(value: string): void {
scanStatus.value = value;
}
async function toDetail(item: SalesOrder): Promise<void> {
if (item.id) await router.push(`/management/sales-orders/${item.id}`);
}
@@ -455,10 +426,6 @@ onUnmounted(() => { navBarStore.clearRight(); search.cancel(); });
.list-wrap {
padding-top: 1rem;
.scanner-wrap {
margin: 0 1rem 1rem;
}
.items {
gap: 1rem;
display: flex;