优化供应商全称搜索与下拉展示

This commit is contained in:
kx_guo 2026-09-10 17:33:54 +08:00
parent c2a0756d2f
commit fd26b766a3
2 changed files with 18 additions and 14 deletions

View File

@ -5,6 +5,10 @@ export interface SupplierOption {
name: string;
anomalyCount: number;
tier: string;
city?: string | null;
province?: string | null;
shortName?: string | null;
reviewStatus?: string | null;
}
export interface SupplierListData {
items: SupplierOption[];

View File

@ -11,7 +11,7 @@ const route = useRoute();
const supplierNames = ref<string[]>([]);
const selected = ref("");
const supplierQuery = ref("");
const supplierResults = ref<string[]>([]);
const supplierResults = ref<Array<{ name: string; city?: string | null; anomalyCount: number; reviewStatus?: string | null }>>([]);
const supplierDropdownOpen = ref(false);
const supplierSearching = ref(false);
let supplierSearchTimer: ReturnType<typeof setTimeout> | undefined;
@ -95,7 +95,7 @@ async function loadOptions() {
? route.query.supplier
: (response.data.data?.defaultSupplier ?? supplierNames.value[0] ?? "");
supplierQuery.value = selected.value;
supplierResults.value = supplierNames.value;
supplierResults.value = (response.data.data?.items ?? []).map((item) => ({ name: item.name, city: item.city, anomalyCount: item.anomalyCount, reviewStatus: item.reviewStatus }));
if (selected.value) await loadProfile();
} catch {
error.value = "供应商列表加载失败,请重试。";
@ -105,7 +105,7 @@ async function loadOptions() {
function openSupplierDropdown() {
supplierDropdownOpen.value = true;
if (!supplierQuery.value || supplierQuery.value === selected.value) {
supplierResults.value = supplierNames.value;
supplierResults.value = supplierNames.value.map((name) => ({ name, anomalyCount: 0 }));
}
}
@ -113,20 +113,19 @@ function searchSuppliers(value: string) {
if (supplierSearchTimer) clearTimeout(supplierSearchTimer);
const keyword = value.trim();
if (!keyword) {
supplierResults.value = supplierNames.value;
supplierResults.value = supplierNames.value.map((name) => ({ name, anomalyCount: 0 }));
supplierSearching.value = false;
return;
}
const local = supplierNames.value.filter((name) => matchesSupplier(name, keyword));
supplierResults.value = local;
supplierResults.value = local.map((name) => ({ name, anomalyCount: 0 }));
supplierSearching.value = true;
supplierSearchTimer = setTimeout(async () => {
try {
const response = await fetchSupplierOptions(keyword);
supplierResults.value =
response.data.data?.items.map((item) => item.name) ?? [];
supplierResults.value = (response.data.data?.items ?? []).map((item) => ({ name: item.name, city: item.city, anomalyCount: item.anomalyCount, reviewStatus: item.reviewStatus }));
} catch {
supplierResults.value = local;
supplierResults.value = local.map((name) => ({ name, anomalyCount: 0 }));
} finally {
supplierSearching.value = false;
}
@ -235,16 +234,17 @@ watch(
role="listbox"
>
<button
v-for="name in supplierResults"
:key="name"
v-for="item in supplierResults"
:key="item.name"
type="button"
class="supplier-option"
:class="{ active: name === selected }"
:class="{ active: item.name === selected }"
role="option"
:aria-selected="name === selected"
@mousedown.prevent="selectSupplier(name)"
:aria-selected="item.name === selected"
@mousedown.prevent="selectSupplier(item.name)"
>
{{ name }}
{{ item.name }}<small v-if="item.city"> · {{ item.city }}</small>
<small v-if="item.anomalyCount"> · {{ item.anomalyCount }} 条异常</small>
</button>
<span v-if="supplierSearching" class="supplier-option-state"
>搜索中…</span