update cascase filter

This commit is contained in:
2026-03-23 13:45:13 +08:00
parent fea4745142
commit b830af76f5
7 changed files with 79 additions and 64 deletions
+23 -7
View File
@@ -9,19 +9,26 @@ export interface CascadeValue {
const model = defineModel<CascadeValue>({ default: () => ({ company_id: undefined, platform_id: undefined, store_id: undefined }) }) const model = defineModel<CascadeValue>({ default: () => ({ company_id: undefined, platform_id: undefined, store_id: undefined }) })
const companies = ref<{ id: number; name: string; label: string }[]>([]) const companies = ref<{ id: number; name: string; label: string | null }[]>([])
const platforms = ref<{ id: number; developer_id: number }[]>([]) const platforms = ref<{ id: number; name: string; label: string | null; developer_id?: number }[]>([])
const stores = ref<{ id: number; company_id: number; platform_id: number; name: string; label: string }[]>([]) const stores = ref<{ id: number; company_id: number; platform_id: number; name: string; label: string | null }[]>([])
/** 清洗 label:过滤 "null" 字符串,优先 label 其次 name */
function cleanLabel(label: string | null | undefined, name: string | undefined, fallback: string): string {
if (label && label !== 'null') return label
if (name) return name
return fallback
}
const loadingCompanies = ref(false) const loadingCompanies = ref(false)
const loadingStores = ref(false) const loadingStores = ref(false)
const companyOptions = computed(() => const companyOptions = computed(() =>
companies.value.map((c) => ({ value: c.id, label: c.label || c.name })), companies.value.map((c) => ({ value: c.id, label: cleanLabel(c.label, c.name, `公司 #${c.id}`) })),
) )
const platformOptions = computed(() => const platformOptions = computed(() =>
platforms.value.map((p) => ({ value: p.id, label: `平台 #${p.id}` })), platforms.value.map((p) => ({ value: p.id, label: cleanLabel(p.label, p.name, `平台 #${p.id}`) })),
) )
const storeOptions = computed(() => { const storeOptions = computed(() => {
@@ -32,7 +39,7 @@ const storeOptions = computed(() => {
if (model.value.platform_id) { if (model.value.platform_id) {
filtered = filtered.filter((s) => s.platform_id === model.value.platform_id) filtered = filtered.filter((s) => s.platform_id === model.value.platform_id)
} }
return filtered.map((s) => ({ value: s.id, label: s.label || s.name })) return filtered.map((s) => ({ value: s.id, label: cleanLabel(s.label, s.name, `店铺 #${s.id}`) }))
}) })
function handleCompanyChange(val: unknown) { function handleCompanyChange(val: unknown) {
@@ -85,7 +92,9 @@ onMounted(() => {
</script> </script>
<template> <template>
<div class="flex gap-2 items-center"> <div class="flex gap-4 items-center">
<div class="flex items-center gap-1">
<span class="text-gray-600 text-sm whitespace-nowrap">公司</span>
<a-select <a-select
:value="model.company_id" :value="model.company_id"
:options="companyOptions" :options="companyOptions"
@@ -99,6 +108,9 @@ onMounted(() => {
style="min-width: 160px" style="min-width: 160px"
@change="handleCompanyChange" @change="handleCompanyChange"
/> />
</div>
<div class="flex items-center gap-1">
<span class="text-gray-600 text-sm whitespace-nowrap">平台</span>
<a-select <a-select
:value="model.platform_id" :value="model.platform_id"
:options="platformOptions" :options="platformOptions"
@@ -111,6 +123,9 @@ onMounted(() => {
style="min-width: 160px" style="min-width: 160px"
@change="handlePlatformChange" @change="handlePlatformChange"
/> />
</div>
<div class="flex items-center gap-1">
<span class="text-gray-600 text-sm whitespace-nowrap">店铺</span>
<a-select <a-select
:value="model.store_id" :value="model.store_id"
:options="storeOptions" :options="storeOptions"
@@ -125,4 +140,5 @@ onMounted(() => {
@change="handleStoreChange" @change="handleStoreChange"
/> />
</div> </div>
</div>
</template> </template>
+1 -1
View File
@@ -167,7 +167,7 @@ async function handleViewDetail(record: { id: number }) {
<h2 class="text-xl font-semibold mb-4">订单管理</h2> <h2 class="text-xl font-semibold mb-4">订单管理</h2>
<!-- Filter area --> <!-- Filter area -->
<a-card class="mb-4"> <a-card class="mb-6">
<a-form layout="inline" @submit.prevent="handleSearch"> <a-form layout="inline" @submit.prevent="handleSearch">
<a-form-item> <a-form-item>
<CascadeFilter v-model="store.cascadeValue" /> <CascadeFilter v-model="store.cascadeValue" />
+1 -1
View File
@@ -121,7 +121,7 @@ async function handleViewDetail(record: { id: number }) {
<h2 class="text-xl font-semibold mb-4">产品管理</h2> <h2 class="text-xl font-semibold mb-4">产品管理</h2>
<!-- Filter area --> <!-- Filter area -->
<a-card class="mb-4"> <a-card class="mb-6">
<a-form layout="inline" @submit.prevent="handleSearch"> <a-form layout="inline" @submit.prevent="handleSearch">
<a-form-item> <a-form-item>
<CascadeFilter v-model="store.cascadeValue" /> <CascadeFilter v-model="store.cascadeValue" />
+1 -1
View File
@@ -141,7 +141,7 @@ async function handleViewDetail(record: { id: number }) {
<h2 class="text-xl font-semibold mb-4">退款管理</h2> <h2 class="text-xl font-semibold mb-4">退款管理</h2>
<!-- Filter area --> <!-- Filter area -->
<a-card class="mb-4"> <a-card class="mb-6">
<a-form layout="inline" @submit.prevent="handleSearch"> <a-form layout="inline" @submit.prevent="handleSearch">
<a-form-item> <a-form-item>
<CascadeFilter v-model="store.cascadeValue" /> <CascadeFilter v-model="store.cascadeValue" />
+5 -5
View File
@@ -127,24 +127,24 @@ export const useOrderStore = defineStore('order', () => {
// 名称映射数据 // 名称映射数据
const companies = ref<LookupItem[]>([]) const companies = ref<LookupItem[]>([])
const platforms = ref<{ id: number; developer_id: number }[]>([]) const platforms = ref<{ id: number; name: string; label?: string; developer_id: number }[]>([])
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([]) const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
const companyMap = computed( const companyMap = computed(
() => new Map(companies.value.map((c) => [c.id, c.label || c.name])), () => new Map(companies.value.map((c) => [c.id, (c.label && c.label !== 'null') ? c.label : c.name])),
) )
const platformMap = computed( const platformMap = computed(
() => new Map(platforms.value.map((p) => [p.id, `平台 #${p.id}`])), () => new Map(platforms.value.map((p) => [p.id, (p.label && p.label !== 'null') ? p.label : (p.name || `平台 #${p.id}`)])),
) )
const storeMap = computed( const storeMap = computed(
() => new Map(stores.value.map((s) => [s.id, s.label || s.name])), () => new Map(stores.value.map((s) => [s.id, (s.label && s.label !== 'null') ? s.label : s.name])),
) )
async function loadLookups() { async function loadLookups() {
try { try {
const [c, p, s] = await Promise.all([ const [c, p, s] = await Promise.all([
api.get<LookupItem[]>('/api/v1/companies'), api.get<LookupItem[]>('/api/v1/companies'),
api.get<{ id: number; developer_id: number }[]>('/api/v1/platforms'), api.get<{ id: number; name: string; label?: string; developer_id: number }[]>('/api/v1/platforms'),
api.get<(LookupItem & { company_id: number; platform_id: number })[]>( api.get<(LookupItem & { company_id: number; platform_id: number })[]>(
'/api/v1/stores', '/api/v1/stores',
), ),
+5 -6
View File
@@ -85,19 +85,18 @@ export const useProductStore = defineStore('product', () => {
// 名称映射数据 // 名称映射数据
const companies = ref<LookupItem[]>([]) const companies = ref<LookupItem[]>([])
const platforms = ref<{ id: number; developer_id: number }[]>([]) const platforms = ref<{ id: number; name: string; label?: string; developer_id: number }[]>([])
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([]) const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
const companyMap = computed(() => new Map(companies.value.map((c) => [c.id, c.label || c.name]))) const companyMap = computed(() => new Map(companies.value.map((c) => [c.id, (c.label && c.label !== 'null') ? c.label : c.name])))
// platforms API 不返回 name 字段,使用 ID 作为显示标签 const platformMap = computed(() => new Map(platforms.value.map((p) => [p.id, (p.label && p.label !== 'null') ? p.label : (p.name || `平台 #${p.id}`)])))
const platformMap = computed(() => new Map(platforms.value.map((p) => [p.id, `平台 #${p.id}`]))) const storeMap = computed(() => new Map(stores.value.map((s) => [s.id, (s.label && s.label !== 'null') ? s.label : s.name])))
const storeMap = computed(() => new Map(stores.value.map((s) => [s.id, s.label || s.name])))
async function loadLookups() { async function loadLookups() {
try { try {
const [c, p, s] = await Promise.all([ const [c, p, s] = await Promise.all([
api.get<LookupItem[]>('/api/v1/companies'), api.get<LookupItem[]>('/api/v1/companies'),
api.get<{ id: number; developer_id: number }[]>('/api/v1/platforms'), api.get<{ id: number; name: string; label?: string; developer_id: number }[]>('/api/v1/platforms'),
api.get<(LookupItem & { company_id: number; platform_id: number })[]>('/api/v1/stores'), api.get<(LookupItem & { company_id: number; platform_id: number })[]>('/api/v1/stores'),
]) ])
companies.value = c companies.value = c
+5 -5
View File
@@ -33,24 +33,24 @@ export const useRefundStore = defineStore('refund', () => {
// 名称映射数据 // 名称映射数据
const companies = ref<LookupItem[]>([]) const companies = ref<LookupItem[]>([])
const platforms = ref<{ id: number; developer_id: number }[]>([]) const platforms = ref<{ id: number; name: string; label?: string; developer_id: number }[]>([])
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([]) const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
const companyMap = computed( const companyMap = computed(
() => new Map(companies.value.map((c) => [c.id, c.label || c.name])), () => new Map(companies.value.map((c) => [c.id, (c.label && c.label !== 'null') ? c.label : c.name])),
) )
const platformMap = computed( const platformMap = computed(
() => new Map(platforms.value.map((p) => [p.id, `平台 #${p.id}`])), () => new Map(platforms.value.map((p) => [p.id, (p.label && p.label !== 'null') ? p.label : (p.name || `平台 #${p.id}`)])),
) )
const storeMap = computed( const storeMap = computed(
() => new Map(stores.value.map((s) => [s.id, s.label || s.name])), () => new Map(stores.value.map((s) => [s.id, (s.label && s.label !== 'null') ? s.label : s.name])),
) )
async function loadLookups() { async function loadLookups() {
try { try {
const [c, p, s] = await Promise.all([ const [c, p, s] = await Promise.all([
api.get<LookupItem[]>('/api/v1/companies'), api.get<LookupItem[]>('/api/v1/companies'),
api.get<{ id: number; developer_id: number }[]>('/api/v1/platforms'), api.get<{ id: number; name: string; label?: string; developer_id: number }[]>('/api/v1/platforms'),
api.get<(LookupItem & { company_id: number; platform_id: number })[]>( api.get<(LookupItem & { company_id: number; platform_id: number })[]>(
'/api/v1/stores', '/api/v1/stores',
), ),